Fix: Cleanup \n 1. Remove PostgreSQL \n 2. Remove comments from Python \n 3. Remove non-demo ERP Python code \n 4. Remove deprecated Python code
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -11,6 +11,7 @@ __pycache__/
|
||||
|
||||
# Ignore logs and databases
|
||||
*.log
|
||||
*.log.*
|
||||
|
||||
# Ignore logs and databases
|
||||
# *.sql
|
||||
@@ -58,13 +59,13 @@ TODO.md
|
||||
tmp/
|
||||
|
||||
# Ignore all .txt files in the doc/ directory
|
||||
doc/*.txt
|
||||
static/docs/*.txt
|
||||
|
||||
# But don't ignore doc/important.txt, even though we're ignoring .txt files above
|
||||
!doc/important.txt
|
||||
!static/docs/important.txt
|
||||
|
||||
# Ignore all .pdf files in the doc/ directory and any of its subdirectories
|
||||
doc/**/*.pdf
|
||||
static/docs/**/*.pdf
|
||||
|
||||
# Ignore deprecated files
|
||||
DEPRECATED/
|
||||
|
||||
59
README.md
59
README.md
@@ -8,49 +8,40 @@ NOTE: ALL INSTRUCTIONS ARE FOR LINUX.
|
||||
- Python 3.10
|
||||
- npm
|
||||
- Locally hosted MySQL database
|
||||
- Auth0 application for project
|
||||
- (Optional) Google ReCAPTCHA public and secret keys
|
||||
- (Optional) Bot email account
|
||||
|
||||
## 1. Create Auth0 application for project
|
||||
## 1. Create and populate database
|
||||
1.1. Sign into your local MySQL workspace
|
||||
1.2. Run script static/MySQL/0000_combined.sql
|
||||
|
||||
## 2. (Optional) Create Google reCAPTCHA service
|
||||
NOTE: IF CONTACT US PAGE FORM FUNCTIONALITY IS REQUIRED, COMPLETE THIS STEP.
|
||||
2.1. Go to the reCAPTCHA Admin Console and register your site: https://www.google.com/recaptcha/admin
|
||||
2.2. Choose reCAPTCH v2
|
||||
2.3. Generate and save keys for step 10
|
||||
|
||||
## 3. (Optional) Create bot email account
|
||||
NOTE: IF CONTACT US PAGE FORM FUNCTIONALITY IS REQUIRED, COMPLETE THIS STEP.
|
||||
3.1. Using your chosen email provider, create a new account for sending emails from the web server
|
||||
|
||||
## 4. Create and populate database
|
||||
4.1. Sign into your local MySQL workspace
|
||||
4.2. Run script static/MySQL/0000_combined.sql
|
||||
|
||||
## 5. Open the project in a new terminal window
|
||||
5.1. Open a new terminal window
|
||||
5.2. Navigate to the project with the following command
|
||||
## 2. Open the project in a new terminal window
|
||||
2.1. Open a new terminal window
|
||||
2.2. Navigate to the project with the following command
|
||||
- cd path/to/project/main/directory
|
||||
|
||||
## 6. Create virtual environment
|
||||
6.1. Terminal command
|
||||
## 3. Create virtual environment
|
||||
3.1. Terminal command
|
||||
- python3 -m venv env_demo_partsERP
|
||||
|
||||
## 7. Enter virtual environment
|
||||
7.1. Terminal command
|
||||
## 4. Enter virtual environment
|
||||
4.1. Terminal command
|
||||
- source env_demo_partsERP/bin/activate
|
||||
|
||||
## 8. Run module bundler
|
||||
8.1. Terminal command
|
||||
## 5. Run module bundler
|
||||
5.1. Terminal command
|
||||
- npm run build
|
||||
|
||||
## 9. Install required python packages
|
||||
9.1. Terminal command
|
||||
## 6. Install required python packages
|
||||
6.1. Terminal command
|
||||
- pip3 install -r requirements.txt
|
||||
|
||||
## 10. Set required environment variables
|
||||
10.1. Terminal command
|
||||
## 7. Set required environment variables
|
||||
7.1. Terminal command
|
||||
- export variable_name=variable_value
|
||||
|
||||
10.2. Required variables
|
||||
7.2. Required variables
|
||||
| Name | Purpose | Example Value |
|
||||
| -------- | -------- | -------- |
|
||||
| KEY_SECRET_FLASK | Private key for server encryption. | password123 |
|
||||
@@ -60,7 +51,7 @@ NOTE: IF CONTACT US PAGE FORM FUNCTIONALITY IS REQUIRED, COMPLETE THIS STEP.
|
||||
| SQLALCHEMY_DATABASE_URI | Database connection string for SQLAlchemy. | mysql://db_user_name:db_password@127.0.0.1:3306/db_name |
|
||||
| URL_HOST | Domain (and port as necessary) that the project is hosted on. | https://127.0.0.1:5000/ |
|
||||
|
||||
10.3. Optional variables
|
||||
7.3. Optional variables
|
||||
| Name | Purpose | Example Value |
|
||||
| -------- | -------- | -------- |
|
||||
| MAIL_DEFAULT_SENDER | Bot email address. Required for sending internal emails following form completion on Contact Us page. | bot@partsltd.co.uk |
|
||||
@@ -69,12 +60,12 @@ NOTE: IF CONTACT US PAGE FORM FUNCTIONALITY IS REQUIRED, COMPLETE THIS STEP.
|
||||
| RECAPTCHA_PUBLIC_KEY | Public key for Google reCAPTCHA. Required for bot-prevention mesaures on Contact Us page form.| erDasdku8asdncuSAAS88... |
|
||||
| RECAPTCHA_PRIVATE_KEY | Private key for Google reCAPTCHA. Required for bot-prevention mesaures on Contact Us page form. | erDasdku8asdncuSAAS8... |
|
||||
|
||||
## 11. Host project
|
||||
NOTE: DO EITHER 11.1 OR 11.2.
|
||||
11.1. Host for local machine
|
||||
## 8. Host project
|
||||
NOTE: DO EITHER 8.1 OR 8.2.
|
||||
8.1. Host for local machine
|
||||
- python3 -m flask run
|
||||
|
||||
11.2. Host for local network
|
||||
8.2. Host for local network
|
||||
- python3 -m flask run --host=0.0.0.0
|
||||
|
||||
|
||||
|
||||
27
app.py
27
app.py
@@ -10,11 +10,6 @@ Description:
|
||||
Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles.
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
|
||||
# IMPORTS
|
||||
# internal
|
||||
from config import app_config, Config
|
||||
from controllers.core import routes_core
|
||||
@@ -33,7 +28,6 @@ from extensions import db, csrf, mail, oauth
|
||||
from helpers.helper_app import Helper_App
|
||||
# external
|
||||
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session
|
||||
# from flask_appconfig import AppConfig
|
||||
from flask_cors import CORS
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_mail import Mail, Message
|
||||
@@ -46,17 +40,13 @@ from logging.handlers import RotatingFileHandler
|
||||
import traceback
|
||||
import logging
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__)) # Todo: why?
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# AppConfig(app)
|
||||
app.config.from_object(app_config) # for db init with required keys
|
||||
app.config.from_object(app_config)
|
||||
app.app_config = app_config
|
||||
# app.config["config"] = app_config()
|
||||
|
||||
# logging
|
||||
handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=3)
|
||||
handler.setLevel(logging.DEBUG)
|
||||
app.logger.addHandler(handler)
|
||||
@@ -82,6 +72,8 @@ def make_session_permanent():
|
||||
session.permanent = True
|
||||
|
||||
csrf = CSRFProtect()
|
||||
csrf.init_app(app)
|
||||
|
||||
cors = CORS(app, resources={
|
||||
r"/static/*": {
|
||||
"origins": [app.config["URL_HOST"]],
|
||||
@@ -89,15 +81,15 @@ cors = CORS(app, resources={
|
||||
"max_age": 3600
|
||||
}
|
||||
})
|
||||
|
||||
csrf.init_app(app)
|
||||
cors.init_app(app)
|
||||
|
||||
db.init_app(app)
|
||||
mail.init_app(app)
|
||||
|
||||
oauth.init_app(app)
|
||||
|
||||
mail.init_app(app)
|
||||
|
||||
with app.app_context():
|
||||
# config = app.config["config"]
|
||||
db.create_all()
|
||||
db.engine.url = app.config['SQLALCHEMY_DATABASE_URI']
|
||||
|
||||
@@ -114,7 +106,6 @@ with app.app_context():
|
||||
access_token_url = f'https://{app.config["DOMAIN_AUTH0"]}/oauth/token',
|
||||
)
|
||||
|
||||
|
||||
app.register_blueprint(routes_core)
|
||||
app.register_blueprint(routes_legal)
|
||||
app.register_blueprint(routes_store)
|
||||
@@ -138,9 +129,7 @@ def console_log(value):
|
||||
@app.after_request
|
||||
def add_cache_headers(response):
|
||||
if request.path.startswith('/static/'):
|
||||
# Cache static assets
|
||||
response.headers['Cache-Control'] = 'public, max-age=31536000'
|
||||
else:
|
||||
# No caching for dynamic content
|
||||
response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
|
||||
return response
|
||||
@@ -37,8 +37,6 @@ class Address(db.Model, Base):
|
||||
county = db.Column(db.String(256))
|
||||
active = db.Column(db.Boolean)
|
||||
|
||||
# region = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
Base.__init__(self)
|
||||
|
||||
@@ -67,10 +67,6 @@ class Base():
|
||||
FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value_local_vat_excl'
|
||||
FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value_local_vat_incl'
|
||||
FLAG_WEBSITE: ClassVar[str] = 'website'
|
||||
"""
|
||||
NAME_ATTR_OPTION_TEXT: ClassVar[str] = 'name-attribute-option-text'
|
||||
NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'name-attribute-option-value'
|
||||
"""
|
||||
def __repr__(self):
|
||||
attrs = '\n'.join(f'{k}={v!r}' for k, v in self.__dict__.items())
|
||||
return f'<{self.__class__.__name__}(\n{attrs}\n)>'
|
||||
|
||||
@@ -17,29 +17,6 @@ from lib import argument_validation as av
|
||||
# external
|
||||
from typing import ClassVar
|
||||
|
||||
# CLASSES
|
||||
"""
|
||||
class Currency_Enum(Enum):
|
||||
GBP = 1
|
||||
|
||||
def text(self):
|
||||
return Currency_Enum.Currency_Enum_Text(self)
|
||||
|
||||
def Currency_Enum_Text(currency):
|
||||
av.val_instance(currency, 'currency', 'Currency_Enum_Text', Currency_Enum)
|
||||
if currency == Currency_Enum.GBP:
|
||||
return 'GBP'
|
||||
else:
|
||||
# return 'Unknown'
|
||||
raise ValueError("Unknown Currency Enum.")
|
||||
|
||||
def get_member_by_text(text):
|
||||
for member in Resolution_Level_Enum.__members__.values():
|
||||
if member.name == text:
|
||||
return member
|
||||
raise ValueError("Unknown Currency Enum.")
|
||||
# return Resolution_Level_Enum.HIGH
|
||||
"""
|
||||
|
||||
class Currency(db.Model, Store_Base):
|
||||
FLAG_FACTOR_FROM_GBP: ClassVar[str] = 'factor-from-GBP'
|
||||
|
||||
@@ -32,28 +32,13 @@ class Get_Many_Parameters_Base(BaseModel, metaclass=ABCMeta):
|
||||
pass
|
||||
def to_json(self):
|
||||
return self.dict()
|
||||
"""
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def from_json(cls, json):
|
||||
pass
|
||||
"""
|
||||
"""
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def from_form(cls, form):
|
||||
pass
|
||||
"""
|
||||
|
||||
|
||||
# db = SQLAlchemy()
|
||||
# Base = declarative_base()
|
||||
class SQLAlchemy_ABCMeta(db.Model.__class__, ABCMeta):
|
||||
pass
|
||||
|
||||
class SQLAlchemy_ABC(db.Model, metaclass=SQLAlchemy_ABCMeta):
|
||||
__abstract__ = True
|
||||
# id = db.Column(db.Integer, primary_key=True)
|
||||
def __init__(self):
|
||||
pass
|
||||
def __repr__(self):
|
||||
@@ -63,10 +48,6 @@ class SQLAlchemy_ABC(db.Model, metaclass=SQLAlchemy_ABCMeta):
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
pass
|
||||
"""
|
||||
def to_json_option(self):
|
||||
pass
|
||||
"""
|
||||
def to_temporary_record(self):
|
||||
pass
|
||||
def to_object_with_missing_attributes(self, excluded_attributes):
|
||||
|
||||
@@ -27,8 +27,6 @@ class Region(db.Model, Base):
|
||||
code = db.Column(db.String(50))
|
||||
name = db.Column(db.String(200))
|
||||
active = db.Column(db.Boolean)
|
||||
|
||||
# region = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
@@ -22,11 +22,9 @@ import locale
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
db = SQLAlchemy()
|
||||
|
||||
|
||||
# CLASSES
|
||||
class SQL_Error(db.Model):
|
||||
display_order = db.Column(db.Integer, primary_key=True)
|
||||
id_type = db.Column(db.Integer)
|
||||
@@ -35,22 +33,6 @@ class SQL_Error(db.Model):
|
||||
name = db.Column(db.String(500))
|
||||
description = db.Column(db.String(4000))
|
||||
|
||||
"""
|
||||
def __new__(cls, display_order, code, msg):
|
||||
_m = 'SQL_Error.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_int(display_order, 'display_order', _m)
|
||||
av.val_str(code, 'code', _m, max_len=50, v_arg_type=v_arg_type)
|
||||
av.val_str(msg, 'msg', _m, max_len=4000, v_arg_type=v_arg_type)
|
||||
return super(SQL_Error, cls).__new__(cls)
|
||||
|
||||
def __init__(self, display_order, code, msg):
|
||||
self.display_order = display_order
|
||||
self.code = code
|
||||
self.msg = msg
|
||||
super().__init__()
|
||||
"""
|
||||
|
||||
def from_DB_record(record):
|
||||
error = SQL_Error()
|
||||
error.display_order = record[0]
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Basket Business Object
|
||||
|
||||
Description:
|
||||
Business object for basket
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
# VARIABLE INSTANTIATION
|
||||
# CLASSES
|
||||
# METHODS
|
||||
|
||||
# IMPORTS
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
# from lib import data_types
|
||||
from business_objects.store.product import Product #, Parameters_Product
|
||||
from business_objects.store.discount import Discount
|
||||
from business_objects.store.delivery_option import Delivery_Option
|
||||
from business_objects.store.store_base import Store_Base
|
||||
# from forms import Form_Product
|
||||
# from models.model_view_store import Model_View_Store # circular
|
||||
# from datastores.datastore_store import DataStore_Store # circular
|
||||
# from forms import Form_Basket_Add, Form_Basket_Edit # possibly circular
|
||||
from helpers.helper_app import Helper_App
|
||||
# external
|
||||
# from enum import Enum
|
||||
from flask import jsonify
|
||||
import locale
|
||||
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
|
||||
# CLASSES
|
||||
class Basket_Item():
|
||||
product: Product
|
||||
quantity: int
|
||||
delivery_option: Delivery_Option
|
||||
discounts: list
|
||||
# form: Form_Product
|
||||
is_included_VAT: bool
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
self.is_unavailable_in_currency_or_region = False
|
||||
self.is_available = True
|
||||
"""
|
||||
|
||||
def from_product_and_quantity_and_VAT_included(product, quantity, is_included_VAT):
|
||||
# Initialiser - validation
|
||||
_m = 'Basket_Item.from_product_and_quantity'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_instance(product, 'product', _m, Product, v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity, 'quantity', _m, product.get_quantity_min(), v_arg_type=v_arg_type)
|
||||
basket_item = Basket_Item()
|
||||
basket_item.product = product
|
||||
basket_item.quantity = quantity
|
||||
basket_item.is_included_VAT = is_included_VAT
|
||||
return basket_item
|
||||
|
||||
def add_product_price_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Basket_Item.add_product_price_discount', Discount, v_arg_type='class attribute')
|
||||
self.discounts.append(discount)
|
||||
|
||||
def set_delivery_option(self, delivery_option):
|
||||
av.val_instance(delivery_option, 'delivery_option', 'Basket_Item.set_delivery_option', Delivery_Option, v_arg_type='class attribute')
|
||||
self.delivery_option = delivery_option
|
||||
|
||||
def update_quantity(self, quantity):
|
||||
_m = 'Basket_Item.update_quantity'
|
||||
v_arg_type = 'class attribute'
|
||||
av.full_val_float(quantity, 'quantity', _m, self.product.get_quantity_min(), v_arg_type=v_arg_type)
|
||||
self.quantity = quantity
|
||||
|
||||
def jsonify(self):
|
||||
return jsonify(self)
|
||||
|
||||
def to_json(self):
|
||||
permutation = self.product.get_permutation_selected()
|
||||
return {
|
||||
'product_id': self.product.id_product,
|
||||
'permutation_id': permutation.id_permutation,
|
||||
'price': permutation.output_price(self.is_included_VAT),
|
||||
'quantity': self.quantity
|
||||
}
|
||||
|
||||
def get_subtotal(self):
|
||||
permutation = self.product.get_permutation_selected()
|
||||
return round(self.product.get_price_local(self.is_included_VAT) * self.quantity, 2) if permutation.is_available else 0
|
||||
|
||||
def output_currency(self):
|
||||
return self.product.output_currency()
|
||||
|
||||
def output_subtotal(self):
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
subtotal = self.get_subtotal()
|
||||
permutation = self.product.get_permutation_selected()
|
||||
return 'Not available in this currency or region' if permutation.is_unavailable_in_currency_or_region else 'Not available' if not permutation.is_available else f'{self.product.output_currency()} {locale.format_string("%d", subtotal, grouping=True)}'
|
||||
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
product: {self.product}
|
||||
quantity: {self.quantity}
|
||||
subtotal: {self.get_subtotal()}
|
||||
'''
|
||||
|
||||
class Basket(Store_Base):
|
||||
KEY_BASKET: str = 'basket'
|
||||
KEY_ID_CURRENCY: str = 'id_currency'
|
||||
KEY_ID_REGION_DELIVERY: str = 'id_region_delivery'
|
||||
KEY_IS_INCLUDED_VAT: str = 'is_included_VAT'
|
||||
KEY_ITEMS: str = 'items'
|
||||
items: list
|
||||
is_included_VAT: bool
|
||||
id_region_delivery: int
|
||||
id_currency: int
|
||||
|
||||
def __init__(self, is_included_VAT, id_currency, id_region_delivery):
|
||||
self.items = []
|
||||
self.is_included_VAT = is_included_VAT
|
||||
self.id_currency = id_currency
|
||||
self.id_region_delivery = id_region_delivery
|
||||
def add_item(self, item):
|
||||
av.val_instance(item, 'item', 'Basket.add_item', Basket_Item)
|
||||
self.items.append(item)
|
||||
def to_csv(self):
|
||||
ids_permutation = ''
|
||||
quantities_permutation = ''
|
||||
for b_i in range(len(self.items)):
|
||||
basket_item = self.items[b_i]
|
||||
product = basket_item.product
|
||||
if b_i > 0:
|
||||
ids_permutation += ','
|
||||
quantities_permutation += ','
|
||||
ids_permutation += str(product.get_id_permutation())
|
||||
quantities_permutation += str(basket_item.quantity)
|
||||
Helper_App.console_log(f'ids_permutation_basket = {ids_permutation}')
|
||||
Helper_App.console_log(f'quantities_permutation_basket = {quantities_permutation}')
|
||||
return ids_permutation, quantities_permutation
|
||||
def to_json_list(self):
|
||||
json_list = []
|
||||
for item in self.items:
|
||||
json_list.append(item.to_json())
|
||||
return json_list
|
||||
def to_json(self):
|
||||
return {
|
||||
**self.get_shared_json_attributes(self),
|
||||
Basket.KEY_ITEMS: self.to_json_list(),
|
||||
Basket.KEY_IS_INCLUDED_VAT: self.is_included_VAT,
|
||||
Basket.KEY_ID_CURRENCY: self.id_currency,
|
||||
Basket.KEY_ID_REGION_DELIVERY: self.id_region_delivery
|
||||
}
|
||||
def output_total(self):
|
||||
sum = 0
|
||||
for b_i in self.items:
|
||||
sum += b_i.get_subtotal()
|
||||
symbol = self.items[0].output_currency() if len(self.items) > 0 else ''
|
||||
|
||||
return f'{symbol} {locale.format_string("%d", sum, grouping=True)}'
|
||||
def len(self):
|
||||
return len(self.items)
|
||||
"""
|
||||
def get_key_product_index_from_ids_product_permutation(id_product, id_permutation):
|
||||
return f'{id_product},{"" if id_permutation is None else id_permutation}'
|
||||
"""
|
||||
def __repr__(self):
|
||||
repr = f'Basket:'
|
||||
for basket_item in self.items:
|
||||
Helper_App.console_log(f'{basket_item}')
|
||||
repr = f'{repr}\n{basket_item}'
|
||||
return repr
|
||||
|
||||
def get_ids_permutation_unavailable(self):
|
||||
ids_permutation = []
|
||||
for item in self.items:
|
||||
permutation = item.product.get_permutation_selected()
|
||||
if not permutation.is_available:
|
||||
ids_permutation.append(permutation.id_permutation)
|
||||
return ids_permutation
|
||||
@@ -1,98 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Product Delivery Option Business Object
|
||||
|
||||
Description:
|
||||
Business object for delivery option
|
||||
"""
|
||||
|
||||
# internal
|
||||
from extensions import db
|
||||
|
||||
|
||||
# CLASSES
|
||||
"""
|
||||
class Delivery_Option():
|
||||
name: str
|
||||
delay_min: int # days
|
||||
delay_max: int
|
||||
quantity_min: float
|
||||
quantity_max: float
|
||||
regions: list # [Enum_Region]
|
||||
cost: float
|
||||
|
||||
def __new__(cls, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost):
|
||||
_m = 'Delivery_Option.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(name, 'name', _m, v_arg_type = v_arg_type)
|
||||
av.val_int(delay_min, 'delay_min', _m, 0, v_arg_type = v_arg_type)
|
||||
av.val_int(delay_max, 'delay_max', _m, 0, v_arg_type = v_arg_type)
|
||||
av.val_float(quantity_min, 'quantity_min', _m, 0, v_arg_type = v_arg_type)
|
||||
av.val_float(quantity_max, 'quantity_max', _m, 0, v_arg_type = v_arg_type)
|
||||
av.val_list_instances(regions, 'regions', _m, Enum_Region, v_arg_type = v_arg_type)
|
||||
av.val_float(cost, 'cost', _m, 0, v_arg_type = v_arg_type)
|
||||
return super(Delivery_Option, cls).__new__(cls)
|
||||
|
||||
def __init__(self, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost):
|
||||
self.name = name
|
||||
self.delay_min = delay_min
|
||||
self.delay_max = delay_max
|
||||
self.quantity_min = quantity_min
|
||||
self.quantity_max = quantity_max
|
||||
self.regions = regions
|
||||
self.cost = cost
|
||||
"""
|
||||
class Delivery_Option(db.Model):
|
||||
id_option = db.Column(db.Integer, primary_key=True)
|
||||
id_product = db.Column(db.Integer)
|
||||
id_permutation = db.Column(db.Integer)
|
||||
id_category = db.Column(db.Integer)
|
||||
code = db.Column(db.String(50))
|
||||
name = db.Column(db.String(100))
|
||||
latency_min = db.Column(db.Integer)
|
||||
latency_max = db.Column(db.Integer)
|
||||
quantity_min = db.Column(db.Integer)
|
||||
quantity_max = db.Column(db.Integer)
|
||||
codes_region = db.Column(db.String(4000))
|
||||
names_region = db.Column(db.String(4000))
|
||||
price_GBP = db.Column(db.Float)
|
||||
display_order = db.Column(db.Integer)
|
||||
def __init__(self):
|
||||
self.delivery_regions = []
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
option = Delivery_Option()
|
||||
option.id_option = query_row[0]
|
||||
option.id_product = query_row[1]
|
||||
option.id_permutation = query_row[2]
|
||||
option.id_category = query_row[3]
|
||||
option.code = query_row[4]
|
||||
option.name = query_row[5]
|
||||
option.latency_min = query_row[6]
|
||||
option.latency_max = query_row[7]
|
||||
option.quantity_min = query_row[8]
|
||||
option.quantity_max = query_row[9]
|
||||
option.codes_region = query_row[10]
|
||||
option.names_region = query_row[11]
|
||||
option.price_GBP = query_row[12]
|
||||
option.display_order = query_row[13]
|
||||
return option
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
id: {self.id_option}
|
||||
id_product: {self.id_product}
|
||||
id_category: {self.id_category}
|
||||
name: {self.name}
|
||||
code: {self.code}
|
||||
latency_min: {self.latency_min}
|
||||
latency_max: {self.latency_max}
|
||||
quantity_min: {self.quantity_min}
|
||||
quantity_max: {self.quantity_max}
|
||||
codes_region: {self.codes_region}
|
||||
names_region: {self.names_region}
|
||||
price_GBP: {self.price_GBP}
|
||||
display_order: {self.display_order}
|
||||
'''
|
||||
@@ -59,25 +59,7 @@ class Image(db.Model, Store_Base):
|
||||
url = db.Column(db.String(255))
|
||||
active = db.Column(db.Boolean)
|
||||
display_order = db.Column(db.Integer)
|
||||
"""
|
||||
def __new__(cls, id, id_product, id_category, url, display_order):
|
||||
_m = 'Image.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_int(id_product, 'id_product', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_int(id_category, 'id_category', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_str(url, 'url', _m, max_len=254, v_arg_type=v_arg_type)
|
||||
av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type)
|
||||
return super(Image, cls).__new__(cls)
|
||||
|
||||
def __init__(self, id, id_product, id_category, url, display_order):
|
||||
self.id_image = id
|
||||
self.id_product = id_product
|
||||
self.id_category = id_category
|
||||
self.url = url
|
||||
self.display_order = display_order
|
||||
super().__init__()
|
||||
"""
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Image.from_DB_get_many_product_catalogue'
|
||||
# Helper_App.console_log(f'image: {query_row}')
|
||||
|
||||
@@ -302,12 +302,6 @@ class Manufacturing_Purchase_Order_Product_Link_Temp(db.Model, Store_Base):
|
||||
id_unit_latency_manufacture = db.Column(db.Integer)
|
||||
latency_manufacture: int = db.Column(db.Integer)
|
||||
display_order: int = db.Column(db.Integer)
|
||||
"""
|
||||
cost_unit_local_VAT_excl: float = db.Column(db.Float)
|
||||
cost_unit_local_VAT_incl: float = db.Column(db.Float)
|
||||
price_unit_local_VAT_excl: float = db.Column(db.Float)
|
||||
price_unit_local_VAT_incl: float = db.Column(db.Float)
|
||||
"""
|
||||
active: bool = db.Column(db.Boolean)
|
||||
guid: str = db.Column(db.String(36))
|
||||
def __init__(self):
|
||||
@@ -328,12 +322,6 @@ class Manufacturing_Purchase_Order_Product_Link_Temp(db.Model, Store_Base):
|
||||
row.id_unit_latency_manufacture = manufacturing_purchase_order_product_link.id_unit_latency_manufacture
|
||||
row.latency_manufacture = manufacturing_purchase_order_product_link.latency_manufacture
|
||||
row.display_order = manufacturing_purchase_order_product_link.display_order
|
||||
"""
|
||||
row.cost_unit_local_VAT_excl = manufacturing_purchase_order_product_link.cost_unit_local_VAT_excl
|
||||
row.cost_unit_local_VAT_incl = manufacturing_purchase_order_product_link.cost_unit_local_VAT_incl
|
||||
row.price_unit_local_VAT_excl = manufacturing_purchase_order_product_link.price_unit_local_VAT_excl
|
||||
row.price_unit_local_VAT_incl = manufacturing_purchase_order_product_link.price_unit_local_VAT_incl
|
||||
"""
|
||||
row.active = 1 if manufacturing_purchase_order_product_link.active else 0
|
||||
return row
|
||||
def __repr__(self):
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Order Business Object
|
||||
|
||||
Description:
|
||||
Business object for order
|
||||
"""
|
||||
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
# from lib import data_types
|
||||
from business_objects.store.product import Product
|
||||
from business_objects.store.delivery_option import Delivery_Option
|
||||
from business_objects.store.store_base import Store_Base
|
||||
# from forms import Form_Product
|
||||
# from models.model_view_store import Model_View_Store # circular
|
||||
# external
|
||||
# from enum import Enum
|
||||
from flask import jsonify
|
||||
import locale
|
||||
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
|
||||
# CLASSES
|
||||
class Order(Store_Base):
|
||||
category: str
|
||||
product: Product
|
||||
quantity: int
|
||||
subtotal: float
|
||||
delivery_option: Delivery_Option
|
||||
# form: Form_Product
|
||||
|
||||
def __new__(cls, category, product, quantity):
|
||||
# Initialiser - validation
|
||||
_m = 'Product.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_str(category, 'category', _m, v_arg_type=v_arg_type)
|
||||
av.val_instance(product, 'product', _m, Product, v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity, 'quantity', _m, product.quantity_min, v_arg_type=v_arg_type)
|
||||
return super(Basket_Item, cls).__new__(cls)
|
||||
|
||||
def __init__(self, category, product, quantity):
|
||||
# Constructor
|
||||
self.category = category
|
||||
self.product = product
|
||||
self.quantity = quantity
|
||||
self.subtotal = round(self.product.price_GBP_full * self.quantity, 2)
|
||||
"""
|
||||
self.form = Form_Product()
|
||||
if self.form.validate_on_submit():
|
||||
# Handle form submission
|
||||
|
||||
pass
|
||||
"""
|
||||
|
||||
def update_quantity(self, quantity):
|
||||
_m = 'Basket_Item.update_quantity'
|
||||
v_arg_type = 'class attribute'
|
||||
av.full_val_float(quantity, 'quantity', _m, self.product.quantity_min, v_arg_type=v_arg_type)
|
||||
self.quantity = quantity
|
||||
self.subtotal = round(self.product.price_GBP_full * self.quantity, 2)
|
||||
|
||||
def jsonify(self):
|
||||
return jsonify(self)
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
**self.get_shared_json_attributes(self),
|
||||
'product_id': self.product.id_product,
|
||||
'price': self.product.price_GBP_full,
|
||||
'quantity': self.quantity
|
||||
}
|
||||
|
||||
def output_subtotal(self):
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
return locale.format_string("%d", self.subtotal, grouping=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
category: {self.category}
|
||||
product: {self.product}
|
||||
quantity: {self.quantity}
|
||||
subtotal: {self.subtotal}
|
||||
'''
|
||||
@@ -32,28 +32,7 @@ from helpers.helper_app import Helper_App
|
||||
# external
|
||||
from dataclasses import dataclass
|
||||
from typing import ClassVar, List
|
||||
"""
|
||||
class Enum_Status_Stock(Enum):
|
||||
OUT = 0
|
||||
LOW = 1
|
||||
IN = 99
|
||||
|
||||
def text(self):
|
||||
return Enum_Status_Stock.Enum_Status_Stock_Text(self)
|
||||
|
||||
def Enum_Status_Stock_Text(status):
|
||||
av.val_instance(status, 'category', 'Enum_Status_Stock_Text', Enum_Status_Stock)
|
||||
if status == Enum_Status_Stock.OUT:
|
||||
return 'Out of stock'
|
||||
elif status == Enum_Status_Stock.LOW:
|
||||
return 'Low on stock'
|
||||
else:
|
||||
return 'Fully stocked'
|
||||
|
||||
def get_member_by_text(text):
|
||||
return data_types.get_enum_member_by_text(Enum_Status_Stock, text.upper())
|
||||
|
||||
"""
|
||||
class Product(SQLAlchemy_ABC, Store_Base):
|
||||
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PRODUCT
|
||||
NAME_ATTR_OPTION_TEXT = Store_Base.FLAG_NAME
|
||||
@@ -70,16 +49,6 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
can_view = db.Column(db.Boolean)
|
||||
can_edit = db.Column(db.Boolean)
|
||||
can_admin = db.Column(db.Boolean)
|
||||
# form_basket_add: Form_Basket_Add
|
||||
# form_basket_edit: Form_Basket_Edit
|
||||
# has_variations: bool
|
||||
# index_permutation_selected: int
|
||||
|
||||
"""
|
||||
permutations: list = None
|
||||
permutation_index: dict = None
|
||||
variation_trees: list = None
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.permutations = []
|
||||
@@ -109,24 +78,6 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
product.can_edit = av.input_bool(query_row[9], "can_edit", _m, v_arg_type=v_arg_type)
|
||||
product.can_admin = av.input_bool(query_row[10], "can_admin", _m, v_arg_type=v_arg_type)
|
||||
return product
|
||||
"""
|
||||
def from_permutation(permutation, has_variations = False):
|
||||
_m = 'Product.from_permutation'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_instance(permutation, 'permutation', _m, Product_Permutation, v_arg_type=v_arg_type)
|
||||
product = Product()
|
||||
product.has_variations = has_variations
|
||||
product.index_permutation_selected = 0
|
||||
product.id_product = permutation.id_product
|
||||
product.id_category = permutation.id_category
|
||||
product.display_order = permutation.display_order
|
||||
product.can_view = permutation.can_view
|
||||
product.can_edit = permutation.can_edit
|
||||
product.can_admin = permutation.can_admin
|
||||
product.permutations.append(permutation)
|
||||
# product.get_variation_trees()
|
||||
return product
|
||||
"""
|
||||
def add_product_permutation(self, permutation):
|
||||
_m = 'Product.add_product_permutation'
|
||||
av.val_instance(permutation, 'permutation', _m, Product_Permutation)
|
||||
@@ -136,36 +87,9 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
except KeyError:
|
||||
self.permutation_index[permutation.id_permutation] = len(self.permutations)
|
||||
self.permutations.append(permutation)
|
||||
"""
|
||||
if self.has_variations:
|
||||
self.has_variations = False
|
||||
"""
|
||||
if self.index_permutation_selected is None:
|
||||
self.index_permutation_selected = self.permutation_index[permutation.id_permutation]
|
||||
Helper_App.console_log(f'setting selected permutation for product {self.id_product} to {self.index_permutation_selected}') # :\n{self.permutations[self.index_permutation_selected]}
|
||||
"""
|
||||
def from_permutations(permutations):
|
||||
_m = 'Product.from_permutations'
|
||||
v_arg_type = 'class attribute'
|
||||
if len(permutations) == 0:
|
||||
raise ValueError(av.error_msg_str(permutations, 'permutations', _m, list, v_arg_type=v_arg_type))
|
||||
product = Product()
|
||||
product.has_variations = True
|
||||
product.index_permutation_selected = 0
|
||||
product.id_product = permutations[0].id_product
|
||||
product.id_category = permutations[0].id_category
|
||||
product.display_order = permutations[0].display_order
|
||||
product.can_view = True
|
||||
product.can_edit = True
|
||||
product.can_admin = True
|
||||
for permutation in permutations:
|
||||
product.can_view &= permutation.can_view
|
||||
product.can_edit &= permutation.can_edit
|
||||
product.can_admin &= permutation.can_admin
|
||||
product.permutations.append(permutations)
|
||||
product.get_variation_trees()
|
||||
return product
|
||||
"""
|
||||
Helper_App.console_log(f'setting selected permutation for product {self.id_product} to {self.index_permutation_selected}')
|
||||
def get_variation_trees(self):
|
||||
self.variation_trees = []
|
||||
for index_permutation in range(len(self.permutations)):
|
||||
@@ -186,12 +110,6 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
permutation = Product_Permutation.from_DB_Stripe_price(query_row)
|
||||
product = Product.from_permutation(permutation)
|
||||
return product
|
||||
"""
|
||||
def from_json(json_basket_item, key_id_product, key_id_permutation):
|
||||
permutation = Product_Permutation.from_json(json_basket_item, key_id_product, key_id_permutation)
|
||||
product = Product.from_permutation(permutation)
|
||||
return product
|
||||
"""
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
product = cls()
|
||||
@@ -242,13 +160,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
return self.get_permutation_selected().description
|
||||
def output_currency(self):
|
||||
return self.get_permutation_selected().get_price().symbol_currency
|
||||
"""
|
||||
def add_form_basket_add(self):
|
||||
self.form_basket_add = None
|
||||
|
||||
def add_form_basket_edit(self):
|
||||
self.form_basket_edit = None
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return f'''Product
|
||||
id_product: {self.id_product}
|
||||
@@ -263,23 +175,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
variation trees: {self.variation_trees}
|
||||
active: {self.active}
|
||||
'''
|
||||
"""
|
||||
def get_index_permutation_from_id(self, id_permutation):
|
||||
if id_permutation is None and not self.has_variations:
|
||||
return 0
|
||||
for index_permutation in range(len(self.permutations)):
|
||||
permutation = self.permutations[index_permutation]
|
||||
if permutation.id_permutation == id_permutation:
|
||||
return index_permutation
|
||||
raise ValueError(f"{av.error_msg_str(id_permutation, 'id_permutation', 'Product.get_index_permutation_from_id', int)}\nPermutation ID not found.")
|
||||
"""
|
||||
"""
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product.add_product_variation', Product_Variation)
|
||||
# Helper_App.console_log(f'variation: {variation}')
|
||||
index_permutation = self.permutation_index[variation.id_permutation] # self.get_index_permutation_from_id(variation.id_permutation)
|
||||
self.permutations[index_permutation].add_product_variation(variation)
|
||||
"""
|
||||
|
||||
def add_product_variation_type(self, variation_type):
|
||||
variation = variation_type.variations[0]
|
||||
index_permutation = self.permutation_index[variation.id_permutation]
|
||||
@@ -318,27 +214,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
for permutation in self.permutations:
|
||||
list_rows.append(permutation.to_row_permutation())
|
||||
return list_rows
|
||||
"""
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
product = cls()
|
||||
product.id_product = json[cls.ATTR_ID_PRODUCT]
|
||||
product.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
|
||||
product.name = json[cls.FLAG_NAME]
|
||||
product.display_order = json[cls.FLAG_DISPLAY_ORDER]
|
||||
product.can_view = json[cls.FLAG_CAN_VIEW]
|
||||
product.can_edit = json[cls.FLAG_CAN_EDIT]
|
||||
product.can_admin = json[cls.FLAG_CAN_ADMIN]
|
||||
product.has_variations = json[cls.FLAG_HAS_VARIATIONS]
|
||||
product.index_permutation_selected = json[cls.FLAG_INDEX_PERMUTATION_SELECTED]
|
||||
product.permutations = []
|
||||
for json_permutation in json[cls.ATTR_ID_PRODUCT_PERMUTATION]:
|
||||
product.permutations.append(Product_Permutation.from_json(json_permutation))
|
||||
product.variation_trees = []
|
||||
for json_tree in json[cls.FLAG_PRODUCT_VARIATION_TREES]:
|
||||
product.variation_trees.append(Product_Variation_Tree.from_json(json_tree))
|
||||
return product
|
||||
"""
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
**self.get_shared_json_attributes(self),
|
||||
@@ -366,22 +242,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
if type not in list_types:
|
||||
list_types.append(type)
|
||||
return list_types
|
||||
"""
|
||||
def get_json_str_types_variation_trees(self):
|
||||
json_str = ''
|
||||
for tree in self.variation_trees:
|
||||
if json_str != '':
|
||||
json_str += '\n'
|
||||
json_str += tree.get_json_str_types()
|
||||
return json_str
|
||||
def get_text_input_variation_types(self):
|
||||
text_input = ''
|
||||
for tree in self.variation_trees:
|
||||
if text_input != '':
|
||||
text_input += '\n'
|
||||
text_input += tree.get_text_input_types()
|
||||
return text_input
|
||||
"""
|
||||
|
||||
def get_csv_ids_permutation(self):
|
||||
csv = ''
|
||||
for permutation in self.permutations:
|
||||
@@ -392,36 +253,18 @@ class Product(SQLAlchemy_ABC, Store_Base):
|
||||
|
||||
|
||||
class Parameters_Product(Get_Many_Parameters_Base):
|
||||
# id_user: str
|
||||
get_all_product_category: bool
|
||||
get_inactive_product_category: bool
|
||||
# get_first_product_category_only: bool
|
||||
ids_product_category: str
|
||||
get_all_product: bool
|
||||
get_inactive_product: bool
|
||||
# get_first_product_only: bool
|
||||
ids_product: str
|
||||
get_all_permutation: bool
|
||||
get_inactive_permutation: bool
|
||||
# get_first_permutation_only: bool
|
||||
ids_permutation: str
|
||||
get_all_image: bool
|
||||
get_inactive_image: bool
|
||||
# get_first_image_only: bool
|
||||
ids_image: str
|
||||
"""
|
||||
get_all_region: bool
|
||||
get_inactive_region: bool
|
||||
get_first_region_only: bool
|
||||
ids_region: str
|
||||
get_all_currency: bool
|
||||
get_inactive_currency: bool
|
||||
get_first_currency_only: bool
|
||||
ids_currency: str
|
||||
get_all_discount: bool
|
||||
get_inactive_discount: bool
|
||||
ids_discount: str
|
||||
"""
|
||||
get_products_quantity_stock_below_min: bool
|
||||
|
||||
def to_json(self):
|
||||
@@ -429,37 +272,21 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
# 'a_id_user': None,
|
||||
'a_get_all_product_category': self.get_all_product_category,
|
||||
'a_get_inactive_product_category': self.get_inactive_product_category,
|
||||
# 'a_get_first_product_category_only': self.get_first_product_category_only,
|
||||
'a_ids_product_category': self.ids_product_category,
|
||||
'a_get_all_product': self.get_all_product,
|
||||
'a_get_inactive_product': self.get_inactive_product,
|
||||
# 'a_get_first_product_only': self.get_first_product_only,
|
||||
'a_ids_product': self.ids_product,
|
||||
'a_get_all_permutation': self.get_all_permutation,
|
||||
'a_get_inactive_permutation': self.get_inactive_permutation,
|
||||
# 'a_get_first_permutation_only': self.get_first_permutation_only,
|
||||
'a_ids_permutation': self.ids_permutation,
|
||||
'a_get_all_image': self.get_all_image,
|
||||
'a_get_inactive_image': self.get_inactive_image,
|
||||
# 'a_get_first_image_only': self.get_first_image_only,
|
||||
'a_ids_image': self.ids_image,
|
||||
# 'a_get_all_delivery_region': self.get_all_region,
|
||||
# 'a_get_inactive_delivery_region': self.get_inactive_region,
|
||||
# 'a_get_first_delivery_region_only': self.get_first_region_only,
|
||||
# 'a_ids_delivery_region': self.ids_region,
|
||||
# 'a_get_all_currency': self.get_all_currency,
|
||||
# 'a_get_inactive_currency': self.get_inactive_currency,
|
||||
# 'a_get_first_currency_only': self.get_first_currency_only,
|
||||
# 'a_ids_currency': self.ids_currency,
|
||||
# 'a_get_all_discount': self.get_all_discount,
|
||||
# 'a_get_inactive_discount': self.get_inactive_discount,
|
||||
# 'a_ids_discount': self.ids_discount,
|
||||
'a_get_products_quantity_stock_below_min': self.get_products_quantity_stock_below_min
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def from_form_filters_product(form):
|
||||
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product)
|
||||
has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '' or form.id_category.data is None)
|
||||
is_not_empty = av.input_bool(form.is_not_empty.data, "is_not_empty", "Parameters_Product.from_form_filters_product")
|
||||
@@ -467,37 +294,20 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
return Parameters_Product(
|
||||
get_all_product_category = not has_filter_category,
|
||||
get_inactive_product_category = not active,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = form.id_category.data if form.id_category.data is not None else '',
|
||||
get_all_product = True,
|
||||
get_inactive_product = not active,
|
||||
# get_first_product_only = False,
|
||||
ids_product = '',
|
||||
get_all_permutation = True,
|
||||
get_inactive_permutation = not active,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = False,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = False,
|
||||
# get_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = False,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = False,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = False
|
||||
)
|
||||
@staticmethod
|
||||
def from_form_filters_product_permutation(form):
|
||||
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
# av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product_Permutation)
|
||||
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '' or form.id_category.data is None)
|
||||
has_product_filter = not (form.id_product.data == '0' or form.id_product.data == '' or form.id_product.data is None)
|
||||
get_permutations_stock_below_min = av.input_bool(form.is_out_of_stock.data, "is_out_of_stock", "Parameters_Product.from_form_filters_product_permutation")
|
||||
@@ -506,31 +316,16 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
return Parameters_Product(
|
||||
get_all_product_category = not has_category_filter,
|
||||
get_inactive_product_category = get_inactive,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = form.id_category.data if form.id_category.data is not None else '',
|
||||
get_all_product = not has_product_filter,
|
||||
get_inactive_product = get_inactive,
|
||||
# get_first_product_only = False,
|
||||
ids_product = form.id_product.data if form.id_product.data is not None else '',
|
||||
get_all_permutation = not get_permutations_stock_below_min,
|
||||
get_inactive_permutation = get_inactive,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = False,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = False,
|
||||
# get_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = False,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = False,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = get_permutations_stock_below_min
|
||||
)
|
||||
|
||||
@@ -539,31 +334,16 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
return Parameters_Product(
|
||||
get_all_product_category = True,
|
||||
get_inactive_product_category = False,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = '',
|
||||
get_all_product = True,
|
||||
get_inactive_product = False,
|
||||
# get_first_product_only = False,
|
||||
ids_product = '',
|
||||
get_all_permutation = True,
|
||||
get_inactive_permutation = False,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = True,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = True,
|
||||
# et_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = True,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = True,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = True
|
||||
)
|
||||
|
||||
@@ -572,31 +352,16 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
return cls(
|
||||
get_all_product_category = json.get('a_get_all_product_category', False),
|
||||
get_inactive_product_category = json.get('a_get_inactive_product_category', False),
|
||||
# get_first_product_category_only = json.get('a_get_first_product_category_only', False),
|
||||
ids_product_category = json.get('a_ids_product_category', ''),
|
||||
get_all_product = json.get('a_get_all_product', False),
|
||||
get_inactive_product = json.get('a_get_inactive_product', False),
|
||||
# get_first_product_only = json.get('a_get_first_product_only', False),
|
||||
ids_product = json.get('a_ids_product', ''),
|
||||
get_all_permutation = json.get('a_get_all_permutation', False),
|
||||
get_inactive_permutation = json.get('a_get_inactive_permutation', False),
|
||||
# get_first_permutation_only = json.get('a_get_first_permutation_only', False),
|
||||
ids_permutation = json.get('a_ids_permutation', ''),
|
||||
get_all_image = json.get('a_get_all_image', False),
|
||||
get_inactive_image = json.get('a_get_inactive_image', False),
|
||||
# get_first_image_only = json.get('a_get_first_image_only', False),
|
||||
ids_image = json.get('a_ids_image', ''),
|
||||
# get_all_region = json.get('a_get_all_region', False),
|
||||
# get_inactive_region = json.get('a_get_inactive_region', False),
|
||||
# get_first_region_only = json.get('a_get_first_region_only', False),
|
||||
# ids_region = json.get('a_ids_region', ''),
|
||||
# get_all_currency = json.get('a_get_all_currency', False),
|
||||
# get_inactive_currency = json.get('a_get_inactive_currency', False),
|
||||
# get_first_currency_only = json.get('a_get_first_currency_only', False),
|
||||
# ids_currency = json.get('a_ids_currency', ''),
|
||||
# get_all_discount = json.get('a_get_all_discount', False),
|
||||
# get_inactive_discount = json.get('a_get_inactive_discount', False),
|
||||
# ids_discount = json.get('a_ids_discount', ''),
|
||||
get_products_quantity_stock_below_min = json.get('a_get_products_quantity_stock_below_min', False)
|
||||
)
|
||||
|
||||
@@ -621,242 +386,6 @@ class Parameters_Product(Get_Many_Parameters_Base):
|
||||
def from_filters_stock_item(cls, filters_stock_item):
|
||||
return cls.from_form_filters_product_permutation(filters_stock_item)
|
||||
|
||||
"""
|
||||
class Parameters_Product(Get_Many_Parameters_Base):
|
||||
# id_user: str
|
||||
get_all_product_category: bool
|
||||
get_inactive_product_category: bool
|
||||
# get_first_product_category_only: bool
|
||||
ids_product_category: str
|
||||
get_all_product: bool
|
||||
get_inactive_product: bool
|
||||
# get_first_product_only: bool
|
||||
ids_product: str
|
||||
get_all_permutation: bool
|
||||
get_inactive_permutation: bool
|
||||
# get_first_permutation_only: bool
|
||||
ids_permutation: str
|
||||
get_all_image: bool
|
||||
get_inactive_image: bool
|
||||
# get_first_image_only: bool
|
||||
ids_image: str
|
||||
""
|
||||
get_all_region: bool
|
||||
get_inactive_region: bool
|
||||
get_first_region_only: bool
|
||||
ids_region: str
|
||||
get_all_currency: bool
|
||||
get_inactive_currency: bool
|
||||
get_first_currency_only: bool
|
||||
ids_currency: str
|
||||
get_all_discount: bool
|
||||
get_inactive_discount: bool
|
||||
ids_discount: str
|
||||
""
|
||||
get_products_quantity_stock_below_min: bool
|
||||
|
||||
def __init__(self, a_id_user, **kwargs):
|
||||
super().__init__(a_id_user, **kwargs)
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'a_id_user': self.a_id_user,
|
||||
'a_get_all_product_category': self.get_all_product_category,
|
||||
'a_get_inactive_product_category': self.get_inactive_product_category,
|
||||
# 'a_get_first_product_category_only': self.get_first_product_category_only,
|
||||
'a_ids_product_category': self.ids_product_category,
|
||||
'a_get_all_product': self.get_all_product,
|
||||
'a_get_inactive_product': self.get_inactive_product,
|
||||
# 'a_get_first_product_only': self.get_first_product_only,
|
||||
'a_ids_product': self.ids_product,
|
||||
'a_get_all_permutation': self.get_all_permutation,
|
||||
'a_get_inactive_permutation': self.get_inactive_permutation,
|
||||
# 'a_get_first_permutation_only': self.get_first_permutation_only,
|
||||
'a_ids_permutation': self.ids_permutation,
|
||||
'a_get_all_image': self.get_all_image,
|
||||
'a_get_inactive_image': self.get_inactive_image,
|
||||
# 'a_get_first_image_only': self.get_first_image_only,
|
||||
'a_ids_image': self.ids_image,
|
||||
# 'a_get_all_delivery_region': self.get_all_region,
|
||||
# 'a_get_inactive_delivery_region': self.get_inactive_region,
|
||||
# 'a_get_first_delivery_region_only': self.get_first_region_only,
|
||||
# 'a_ids_delivery_region': self.ids_region,
|
||||
# 'a_get_all_currency': self.get_all_currency,
|
||||
# 'a_get_inactive_currency': self.get_inactive_currency,
|
||||
# 'a_get_first_currency_only': self.get_first_currency_only,
|
||||
# 'a_ids_currency': self.ids_currency,
|
||||
# 'a_get_all_discount': self.get_all_discount,
|
||||
# 'a_get_inactive_discount': self.get_inactive_discount,
|
||||
# 'a_ids_discount': self.ids_discount,
|
||||
'a_get_products_quantity_stock_below_min': self.get_products_quantity_stock_below_min
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def from_form_filters_product(form, id_user):
|
||||
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product)
|
||||
has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '')
|
||||
is_not_empty = av.input_bool(form.is_not_empty.data, "is_not_empty", "Parameters_Product.from_form_filters_product")
|
||||
active = av.input_bool(form.active.data, "active", "Parameters_Product.from_form_filters_product")
|
||||
return Parameters_Product(
|
||||
a_id_user = id_user,
|
||||
get_all_product_category = not has_filter_category,
|
||||
get_inactive_product_category = not active,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = str(form.id_category.data),
|
||||
get_all_product = True,
|
||||
get_inactive_product = not active,
|
||||
# get_first_product_only = False,
|
||||
ids_product = '',
|
||||
get_all_permutation = True,
|
||||
get_inactive_permutation = not active,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = False,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = False,
|
||||
# get_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = False,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = False,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = False
|
||||
)
|
||||
@staticmethod
|
||||
def from_form_filters_product_permutation(form):
|
||||
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
# av.val_instance(form, 'form', 'Parameters_Product.from_form', Form_Base)
|
||||
has_category_filter = not (form.id_category.data is None or form.id_category.data == '0' or form.id_category.data == '')
|
||||
has_product_filter = not (form.id_product.data is None or form.id_product.data == '0' or form.id_product.data == '')
|
||||
get_permutations_stock_below_min = av.input_bool(form.is_out_of_stock.data, "is_out_of_stock", "Parameters_Product.from_form")
|
||||
Helper_App.console_log(f'form question: {type(form.is_out_of_stock)}\nbool interpretted: {get_permutations_stock_below_min}\type form: {type(form)}')
|
||||
return Parameters_Product(
|
||||
get_all_product_category = not has_category_filter,
|
||||
get_inactive_product_category = False,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = str(form.id_category.data) if has_category_filter else '',
|
||||
get_all_product = not has_product_filter,
|
||||
get_inactive_product = False,
|
||||
# get_first_product_only = False,
|
||||
ids_product = str(form.id_product.data) if has_product_filter else '',
|
||||
get_all_permutation = not get_permutations_stock_below_min,
|
||||
get_inactive_permutation = False,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = False,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = False,
|
||||
# get_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = False,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = False,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = get_permutations_stock_below_min
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_default(cls, id_user):
|
||||
return cls(
|
||||
a_id_user = id_user,
|
||||
get_all_product_category = True,
|
||||
get_inactive_product_category = False,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = '',
|
||||
get_all_product = True,
|
||||
get_inactive_product = False,
|
||||
# get_first_product_only = False,
|
||||
ids_product = '',
|
||||
get_all_permutation = True,
|
||||
get_inactive_permutation = False,
|
||||
# get_first_permutation_only = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = True,
|
||||
get_inactive_image = False,
|
||||
# get_first_image_only = False,
|
||||
ids_image = '',
|
||||
# get_all_region = True,
|
||||
# et_inactive_region = False,
|
||||
# get_first_region_only = False,
|
||||
# ids_region = '',
|
||||
# get_all_currency = True,
|
||||
# get_inactive_currency = False,
|
||||
# get_first_currency_only = False,
|
||||
# ids_currency = '',
|
||||
# get_all_discount = True,
|
||||
# get_inactive_discount = False,
|
||||
# ids_discount = '',
|
||||
get_products_quantity_stock_below_min = True
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
return cls(
|
||||
get_all_product_category = json.get('a_get_all_product_category', False),
|
||||
get_inactive_product_category = json.get('a_get_inactive_product_category', False),
|
||||
# get_first_product_category_only = json.get('a_get_first_product_category_only', False),
|
||||
ids_product_category = json.get('a_ids_product_category', ''),
|
||||
get_all_product = json.get('a_get_all_product', False),
|
||||
get_inactive_product = json.get('a_get_inactive_product', False),
|
||||
# get_first_product_only = json.get('a_get_first_product_only', False),
|
||||
ids_product = json.get('a_ids_product', ''),
|
||||
get_all_permutation = json.get('a_get_all_permutation', False),
|
||||
get_inactive_permutation = json.get('a_get_inactive_permutation', False),
|
||||
# get_first_permutation_only = json.get('a_get_first_permutation_only', False),
|
||||
ids_permutation = json.get('a_ids_permutation', ''),
|
||||
get_all_image = json.get('a_get_all_image', False),
|
||||
get_inactive_image = json.get('a_get_inactive_image', False),
|
||||
# get_first_image_only = json.get('a_get_first_image_only', False),
|
||||
ids_image = json.get('a_ids_image', ''),
|
||||
# get_all_region = json.get('a_get_all_region', False),
|
||||
# get_inactive_region = json.get('a_get_inactive_region', False),
|
||||
# get_first_region_only = json.get('a_get_first_region_only', False),
|
||||
# ids_region = json.get('a_ids_region', ''),
|
||||
# get_all_currency = json.get('a_get_all_currency', False),
|
||||
# get_inactive_currency = json.get('a_get_inactive_currency', False),
|
||||
# get_first_currency_only = json.get('a_get_first_currency_only', False),
|
||||
# ids_currency = json.get('a_ids_currency', ''),
|
||||
# get_all_discount = json.get('a_get_all_discount', False),
|
||||
# get_inactive_discount = json.get('a_get_inactive_discount', False),
|
||||
# ids_discount = json.get('a_ids_discount', ''),
|
||||
get_products_quantity_stock_below_min = json.get('a_get_products_quantity_stock_below_min', False)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_filters_product_category(cls, filters_category):
|
||||
return cls(
|
||||
get_all_product_category = True,
|
||||
get_inactive_product_category = filters_category.active.data,
|
||||
ids_product_category = '',
|
||||
get_all_product = True,
|
||||
get_inactive_product = False,
|
||||
ids_product = '',
|
||||
get_all_permutation = True,
|
||||
get_inactive_permutation = False,
|
||||
ids_permutation = '',
|
||||
get_all_image = False,
|
||||
get_inactive_image = False,
|
||||
ids_image = '',
|
||||
get_products_quantity_stock_below_min = False
|
||||
)
|
||||
@classmethod
|
||||
def from_filters_stock_item(cls, filters_stock_item):
|
||||
return cls.from_form_filters_product_permutation(filters_stock_item)
|
||||
"""
|
||||
|
||||
class Product_Temp(db.Model, Store_Base):
|
||||
__tablename__ = 'Shop_Product_Temp'
|
||||
__table_args__ = { 'extend_existing': True }
|
||||
@@ -883,11 +412,6 @@ class Product_Temp(db.Model, Store_Base):
|
||||
row.id_access_level_required = product.id_access_level_required[0] if isinstance(product.id_access_level_required, tuple) else product.id_access_level_required
|
||||
row.active = product.active
|
||||
row.display_order = product.display_order
|
||||
"""
|
||||
row.guid = product.guid
|
||||
row.created_on = product.created_on
|
||||
row.created_by = product.created_by
|
||||
"""
|
||||
return row
|
||||
def to_json(self):
|
||||
return {
|
||||
@@ -900,10 +424,6 @@ class Product_Temp(db.Model, Store_Base):
|
||||
'display_order': self.display_order,
|
||||
'guid': self.guid,
|
||||
}
|
||||
"""
|
||||
'created_on': self.created_on,
|
||||
'created_by': self.created_by
|
||||
"""
|
||||
def __repr__(self):
|
||||
return f'''Product_Temp
|
||||
id_product: {self.id_product}
|
||||
|
||||
@@ -463,19 +463,6 @@ class Product_Category_Container(Store_Base):
|
||||
return ','.join(list_ids)
|
||||
|
||||
|
||||
"""
|
||||
class Table_Shop_Product_Category(db.Model):
|
||||
__tablename__ = 'Shop_Product_Category'
|
||||
id_category: int = db.Column(db.Integer, primary_key=True)
|
||||
code: str = db.Column(db.String(50))
|
||||
name: str = db.Column(db.String(255))
|
||||
description: str = db.Column(db.String(4000))
|
||||
active: bool = db.Column(db.Boolean)
|
||||
display_order: int = db.Column(db.Integer)
|
||||
created_on: datetime = db.Column(db.DateTime)
|
||||
created_by: int = db.Column(db.Integer)
|
||||
id_change_set: int = db.Column(db.Integer)
|
||||
"""
|
||||
class Product_Category_Temp(db.Model, Store_Base):
|
||||
__tablename__ = 'Shop_Product_Category_Temp'
|
||||
__table_args__ = { 'extend_existing': True }
|
||||
@@ -488,11 +475,11 @@ class Product_Category_Temp(db.Model, Store_Base):
|
||||
active: bool = db.Column(db.Boolean)
|
||||
display_order: int = db.Column(db.Integer)
|
||||
guid: str = db.Column(db.String(36))
|
||||
# created_on: datetime = db.Column(db.DateTime)
|
||||
# created_by: int = db.Column(db.Integer)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.id_temp = None
|
||||
|
||||
@classmethod
|
||||
def from_product_category(cls, product_category):
|
||||
row = cls()
|
||||
@@ -503,12 +490,8 @@ class Product_Category_Temp(db.Model, Store_Base):
|
||||
row.id_access_level_required = product_category.id_access_level_required[0] if isinstance(product_category.id_access_level_required, tuple) else product_category.id_access_level_required
|
||||
row.active = product_category.active
|
||||
row.display_order = product_category.display_order
|
||||
"""
|
||||
row.guid = product_category.guid
|
||||
row.created_on = product_category.created_on
|
||||
row.created_by = product_category.created_by
|
||||
"""
|
||||
return row
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'id_category': self.id_category,
|
||||
@@ -520,10 +503,6 @@ class Product_Category_Temp(db.Model, Store_Base):
|
||||
'display_order': self.display_order,
|
||||
'guid': self.guid,
|
||||
}
|
||||
"""
|
||||
'created_on': self.created_on,
|
||||
'created_by': self.created_by
|
||||
"""
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.__dict__)
|
||||
@@ -145,38 +145,6 @@ class Parameters_Product_Variation(Get_Many_Parameters_Base):
|
||||
parameters.a_get_inactive_variation = get_inactive
|
||||
return parameters
|
||||
|
||||
"""
|
||||
class Product_Variation_Container(BaseModel):
|
||||
variation_types: list = []
|
||||
variations: list = []
|
||||
|
||||
def add_product_variation_type(self, variation_type):
|
||||
av.val_instance(variation_type, 'variation_type', 'Product_Variation_Container.add_product_variation_type', Product_Variation_Type)
|
||||
self.variations.append(variation_type)
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product_Variation_Container.add_product_variation', Product_Variation)
|
||||
if variation.variation_type is None:
|
||||
variation_type = next(filterfalse(lambda x: x.id_type != variation.id_type, self.variation_types), None)
|
||||
if variation_type is not None:
|
||||
variation.variation_type = variation_type
|
||||
self.variations.append(variation)
|
||||
|
||||
def __repr__(self):
|
||||
return f'Product_Variation_Container:\nvariations_types: {self.variation_types}\nvariations: {self.variations}'
|
||||
|
||||
def to_list_variation_options(self):
|
||||
list_variations = []
|
||||
for variation in self.variations:
|
||||
list_variations.append(variation.to_json_option())
|
||||
Helper_App.console_log(f'list_variations: {list_variations}')
|
||||
return list_variations
|
||||
def to_list_variation_type_options(self):
|
||||
list_variation_types = []
|
||||
for variation_type in self.variation_types:
|
||||
list_variation_types.append(variation_type.to_json_option())
|
||||
return list_variation_types
|
||||
"""
|
||||
|
||||
class Product_Variation_Temp(db.Model, Store_Base):
|
||||
__tablename__ = 'Shop_Variation_Temp'
|
||||
__table_args__ = { 'extend_existing': True }
|
||||
|
||||
@@ -123,18 +123,6 @@ class Product_Variation_Tree():
|
||||
at_leaf_node = node.is_leaf()
|
||||
types.append(node.variation_type)
|
||||
return types
|
||||
"""
|
||||
def get_product_variations(self):
|
||||
variations = []
|
||||
node = self.node_root
|
||||
at_leaf_node = node.is_leaf()
|
||||
variations.append(node.variation)
|
||||
while not at_leaf_node:
|
||||
node = node.nodes_child[0]
|
||||
at_leaf_node = node.is_leaf()
|
||||
variations.append(node.variation)
|
||||
return variations
|
||||
"""
|
||||
def to_preview_str(self):
|
||||
Helper_App.console_log(f'Product_Variation_Tree.to_preview_str')
|
||||
variation_types = self.get_product_variation_types()
|
||||
|
||||
@@ -107,18 +107,6 @@ class Product_Variation_Type(db.Model, Store_Base):
|
||||
'value': self.id_type,
|
||||
'text': self.name_singular
|
||||
}
|
||||
"""
|
||||
def get_preview_variations(self):
|
||||
preview = ''
|
||||
if len(self.variations) > 0:
|
||||
# preview = '\n'.join([variation.name for variation in self.variations])
|
||||
preview = '<p>' + '</p><p>'.join([variation.name for variation in self.variations]) + '</p>'
|
||||
return preview
|
||||
def get_str_list_ids_variation(self):
|
||||
if self.variations is None or len(self.variations) == 0:
|
||||
return ''
|
||||
return ','.join([str(variation.id_variation) for variation in self.variations])
|
||||
"""
|
||||
|
||||
class Product_Variation_Type_Temp(db.Model, Store_Base):
|
||||
__tablename__ = 'Shop_Variation_Type_Temp'
|
||||
|
||||
@@ -56,12 +56,6 @@ class Stock_Item(db.Model, Store_Base):
|
||||
is_consumed = db.Column(db.Boolean)
|
||||
date_consumed = db.Column(db.DateTime)
|
||||
active = db.Column(db.Boolean)
|
||||
"""
|
||||
can_view = db.Column(db.Boolean)
|
||||
can_edit = db.Column(db.Boolean)
|
||||
can_admin = db.Column(db.Boolean)
|
||||
"""
|
||||
# variation_tree: Product_Variation_Tree = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -93,11 +87,6 @@ class Stock_Item(db.Model, Store_Base):
|
||||
stock_item.is_consumed = av.input_bool(query_row[22], "is_consumed", _m, v_arg_type=v_arg_type)
|
||||
stock_item.date_consumed = query_row[23]
|
||||
stock_item.active = av.input_bool(query_row[24], "active", _m, v_arg_type=v_arg_type)
|
||||
"""
|
||||
stock_item.can_view = av.input_bool(query_row[24], "can_view", _m, v_arg_type=v_arg_type)
|
||||
stock_item.can_edit = av.input_bool(query_row[25], "can_edit", _m, v_arg_type=v_arg_type)
|
||||
stock_item.can_admin = av.input_bool(query_row[26], "can_admin", _m, v_arg_type=v_arg_type)
|
||||
"""
|
||||
return stock_item
|
||||
|
||||
@classmethod
|
||||
@@ -163,18 +152,6 @@ class Stock_Item(db.Model, Store_Base):
|
||||
if permutation.is_available():
|
||||
return True
|
||||
return False
|
||||
"""
|
||||
def to_permutation_row_list(self):
|
||||
list_rows = []
|
||||
for permutation in self.permutations:
|
||||
list_rows.append(permutation.to_row_permutation())
|
||||
return list_rows
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_stock_item,
|
||||
'text': self.id_stock_item
|
||||
}
|
||||
"""
|
||||
|
||||
class Parameters_Stock_Item(Get_Many_Parameters_Base):
|
||||
a_get_all_product_permutation: bool
|
||||
|
||||
@@ -18,43 +18,6 @@ import lib.argument_validation as av
|
||||
# external
|
||||
from typing import ClassVar
|
||||
|
||||
"""
|
||||
class I_Store_Base():
|
||||
@abstractmethod
|
||||
def __repr__(self):
|
||||
pass
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def from_json(cls, json):
|
||||
pass
|
||||
@abstractmethod
|
||||
def to_json(self):
|
||||
pass
|
||||
@abstractmethod
|
||||
def to_json_option(self):
|
||||
pass
|
||||
@abstractmethod
|
||||
def test_69 (self):
|
||||
pass
|
||||
""
|
||||
def __init_subclass__(cls, **kwargs):
|
||||
super().__init_subclass__(**kwargs)
|
||||
for name, value in vars(Store_Base).items():
|
||||
if getattr(value, "__isabstractmethod__", False):
|
||||
if name not in cls.__dict__:
|
||||
raise TypeError(f"Can't instantiate class {cls.__name__} "
|
||||
f"without implementation of abstract method {name}")
|
||||
subclass_value = cls.__dict__[name]
|
||||
if (isinstance(value, (staticmethod, classmethod)) and
|
||||
not isinstance(subclass_value, type(value))):
|
||||
raise TypeError(f"Abstract {type(value).__name__} {name} in {cls.__name__} "
|
||||
f"must be implemented as a {type(value).__name__}")
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if cls is Store_Base:
|
||||
raise TypeError("Can't instantiate abstract class Store_Base directly")
|
||||
return super().__new__(cls)
|
||||
""
|
||||
"""
|
||||
|
||||
class Store_Base(Base):
|
||||
# ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost'
|
||||
@@ -124,6 +87,10 @@ class Store_Base(Base):
|
||||
FLAG_UNIT_MEASUREMENT_LATENCY_MANUFACTURE: ClassVar[str] = 'unit_measurement_latency_manufacture'
|
||||
FLAG_UNIT_MEASUREMENT_QUANTITY: ClassVar[str] = 'unit_measurement_quantity'
|
||||
FLAG_VALUE_TEXT: ClassVar[str] = 'value_text'
|
||||
|
||||
KEY_BASKET: ClassVar[str] = 'basket'
|
||||
KEY_IS_INCLUDED_VAT: ClassVar[str] = 'is-included_vat'
|
||||
KEY_ID_CURRENCY: ClassVar[str] = 'currency'
|
||||
KEY_ID_REGION_DELIVERY: ClassVar[str] = 'id-region-delivery'
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.__dict__)
|
||||
@@ -1,161 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Stripe Business Object
|
||||
|
||||
Description:
|
||||
Business objects for Stripe
|
||||
"""
|
||||
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
from lib import data_types
|
||||
from forms.forms import Form_Basket_Add, Form_Basket_Edit # Form_Product
|
||||
from extensions import db
|
||||
from helpers.helper_app import Helper_App
|
||||
# external
|
||||
from datetime import datetime, timedelta
|
||||
import locale
|
||||
|
||||
class Stripe_Product(db.Model):
|
||||
id_product = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(255))
|
||||
description = db.Column(db.String(4000))
|
||||
price_GBP_full = db.Column(db.Float)
|
||||
id_category = db.Column(db.Integer)
|
||||
lead_time_manuf = db.Column(db.Integer)
|
||||
quantity_min = db.Column(db.Float)
|
||||
quantity_max = db.Column(db.Float)
|
||||
quantity_step = db.Column(db.Float)
|
||||
quantity_stock = db.Column(db.Float)
|
||||
id_stripe_product = db.Column(db.String(255))
|
||||
id_stripe_price = db.Column(db.String(255))
|
||||
is_subscription = db.Column(db.Boolean)
|
||||
name_recurring_interval = db.Column(db.String(255))
|
||||
name_plural_recurring_interval = db.Column(db.String(256))
|
||||
count_recurring_interval = db.Column(db.Integer)
|
||||
display_order = db.Column(db.Integer)
|
||||
can_view = db.Column(db.Boolean)
|
||||
can_edit = db.Column(db.Boolean)
|
||||
can_admin = db.Column(db.Boolean)
|
||||
# form_basket_add: Form_Basket_Add
|
||||
# form_basket_edit: Form_Basket_Edit
|
||||
|
||||
def __new__(cls, id, name, description, price_GBP_full, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price,
|
||||
is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, display_order, can_view, can_edit, can_admin):
|
||||
_m = 'Product.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_str(name, 'name', _m, max_len=256, v_arg_type=v_arg_type)
|
||||
av.val_str(description, 'description', _m, max_len=4000, v_arg_type=v_arg_type)
|
||||
av.full_val_float(price_GBP_full, 'price_GBP_full', _m, 0., v_arg_type=v_arg_type)
|
||||
av.val_int(id_category, 'id_category', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_int(lead_time_manuf, 'lead_time_manuf', _m, 0, v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity_step, 'quantity_step', _m, 0., v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity_min, 'quantity_min', _m, quantity_step, v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity_max, 'quantity_max', _m, quantity_min, v_arg_type=v_arg_type)
|
||||
av.full_val_float(quantity_stock, 'quantity_stock', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_str(id_stripe_product, 'id_stripe_product', _m, max_len=100, v_arg_type=v_arg_type)
|
||||
av.val_str(id_stripe_price, 'id_stripe_price', _m, max_len=100, v_arg_type=v_arg_type)
|
||||
av.full_val_bool(is_subscription, 'is_subscription', _m, v_arg_type=v_arg_type)
|
||||
Helper_App.console_log(f'is_subscription: {is_subscription}, {av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type)}')
|
||||
is_subscription = av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type)
|
||||
if is_subscription:
|
||||
av.val_str(name_recurring_interval, 'name_recurring_interval', _m, max_len=255, v_arg_type=v_arg_type)
|
||||
av.val_str(name_plural_recurring_interval, 'name_plural_recurring_interval', _m, max_len=256, v_arg_type=v_arg_type)
|
||||
av.val_int(count_recurring_interval, 'count_recurring_interval', _m, 0, v_arg_type=v_arg_type)
|
||||
av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type)
|
||||
av.full_val_bool(can_view, 'can_view', _m, v_arg_type=v_arg_type)
|
||||
# can_view = av.input_bool(can_view, "can_view", _m, v_arg_type=v_arg_type)
|
||||
av.full_val_bool(can_edit, 'can_edit', _m, v_arg_type=v_arg_type)
|
||||
# can_edit = av.input_bool(can_edit, "can_edit", _m, v_arg_type=v_arg_type)
|
||||
av.full_val_bool(can_admin, 'can_admin', _m, v_arg_type=v_arg_type)
|
||||
# can_admin = av.input_bool(can_admin, "can_admin", _m, v_arg_type=v_arg_type)
|
||||
return super(Product, cls).__new__(cls) # , id, name, description, price_GBP, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price,
|
||||
# is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, can_view, can_edit, can_admin)
|
||||
|
||||
def __init__(self, id, name, description, price_GBP_full, id_category, lead_time_manuf, quantity_min, quantity_max, quantity_step, quantity_stock, id_stripe_product, id_stripe_price,
|
||||
is_subscription, name_recurring_interval, name_plural_recurring_interval, count_recurring_interval, display_order, can_view, can_edit, can_admin):
|
||||
_m = 'Product.__new__'
|
||||
v_arg_type = 'class attribute'
|
||||
self.id_product = id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.price_GBP_full = price_GBP_full
|
||||
self.id_category = id_category
|
||||
self.lead_time_manuf = lead_time_manuf
|
||||
self.quantity_min = quantity_min
|
||||
self.quantity_max = quantity_max
|
||||
self.quantity_step = quantity_step
|
||||
self.quantity_stock = quantity_stock
|
||||
self.id_stripe_product = id_stripe_product
|
||||
self.id_stripe_price = id_stripe_price
|
||||
self.is_subscription = av.input_bool(is_subscription, "is_subscription", _m, v_arg_type=v_arg_type)
|
||||
self.name_recurring_interval = name_recurring_interval
|
||||
self.name_plural_recurring_interval = name_plural_recurring_interval
|
||||
self.count_recurring_interval = count_recurring_interval
|
||||
self.display_order = display_order
|
||||
self.can_view = av.input_bool(can_view, "can_view", _m, v_arg_type=v_arg_type)
|
||||
self.can_edit = av.input_bool(can_edit, "can_edit", _m, v_arg_type=v_arg_type)
|
||||
self.can_admin = av.input_bool(can_admin, "can_admin", _m, v_arg_type=v_arg_type)
|
||||
self.variations = []
|
||||
self.images = []
|
||||
self.delivery_options = []
|
||||
self.discounts = []
|
||||
self.discount_index = {}
|
||||
super().__init__()
|
||||
self.form_basket_add = Form_Basket_Add()
|
||||
self.form_basket_edit = Form_Basket_Edit()
|
||||
|
||||
def output_lead_time(self):
|
||||
return '1 day' if self.lead_time_manuf == 1 else f'{self.lead_time_manuf} days'
|
||||
|
||||
def output_delivery_date(self):
|
||||
return (datetime.now() + timedelta(days=self.lead_time_manuf)).strftime('%A, %d %B %Y')
|
||||
|
||||
def output_price(self):
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
return locale.format_string("%d", self.price_GBP_full, grouping=True)
|
||||
"""
|
||||
def add_form_basket_add(self):
|
||||
self.form_basket_add = None
|
||||
|
||||
def add_form_basket_edit(self):
|
||||
self.form_basket_edit = None
|
||||
"""
|
||||
def __repr__(self):
|
||||
return f'''Product
|
||||
id: {self.id_product}
|
||||
name: {self.name}
|
||||
description: {self.description}
|
||||
price_GBP_full: {self.price_GBP_full}
|
||||
id_category: {self.id_category}
|
||||
lead_time_manuf: {self.lead_time_manuf}
|
||||
quantity_min: {self.quantity_min}
|
||||
quantity_max: {self.quantity_max}
|
||||
quantity_step: {self.quantity_step}
|
||||
quantity_stock: {self.quantity_stock}
|
||||
id_stripe_product: {self.id_stripe_product}
|
||||
id_stripe_price: {self.id_stripe_price}
|
||||
is_subscription: {self.is_subscription}
|
||||
name_recurring_interval: {self.name_recurring_interval}
|
||||
name_plural_recurring_interval: {self.name_plural_recurring_interval}
|
||||
count_recurring_interval: {self.count_recurring_interval}
|
||||
display_order: {self.display_order}
|
||||
can_view: {self.can_view}
|
||||
can_edit: {self.can_edit}
|
||||
can_admin: {self.can_admin}
|
||||
variations: {self.variations}
|
||||
images: {self.images}
|
||||
delivery_options: {self.delivery_options}
|
||||
'''
|
||||
|
||||
def add_product_price_discount(self, discount):
|
||||
_m = 'Category.add_product'
|
||||
av.val_instance(discount, 'discount', _m, Discount)
|
||||
# self.product_index.append(len(self.products))
|
||||
self.discount_index[discount.id_discount] = len(self.discounts)
|
||||
self.discounts.append(discount)
|
||||
@@ -185,48 +185,6 @@ class Parameters_User(Get_Many_Parameters_Base):
|
||||
ids_user = '',
|
||||
ids_user_auth0 = ''
|
||||
)
|
||||
""" User_Eval
|
||||
@dataclass
|
||||
class User_Filters():
|
||||
ids_user: str
|
||||
get_inactive_users: bool
|
||||
ids_permission: str
|
||||
ids_access_level: str
|
||||
ids_product: str
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
**self.get_shared_json_attributes(self),
|
||||
'a_ids_user': self.ids_user,
|
||||
'a_get_inactive_users': self.get_inactive_users,
|
||||
'a_ids_permission': self.ids_permission,
|
||||
'a_ids_access_level': self.ids_access_level,
|
||||
'a_ids_product': self.ids_product,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def from_form(form):
|
||||
av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_User)
|
||||
get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form")
|
||||
return User_Filters(
|
||||
ids_user = form.id_user.data,
|
||||
get_inactive_users = get_inactive,
|
||||
ids_permission = form.ids_permission.data,
|
||||
ids_access_level = form.ids_access_level.data,
|
||||
ids_product = form.ids_product.data,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_default(datastore_store):
|
||||
is_user_logged_in, id_user = datastore_store.get_login_user()
|
||||
return User_Filters(
|
||||
ids_user = id_user,
|
||||
get_inactive_users = False,
|
||||
ids_permission = '',
|
||||
ids_access_level = '',
|
||||
ids_product = '',
|
||||
)
|
||||
"""
|
||||
|
||||
class User_Permission_Evaluation(db.Model):
|
||||
id_evaluation = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
104
config.py
104
config.py
@@ -10,7 +10,6 @@ Description:
|
||||
Configuration variables
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
from lib import argument_validation as av
|
||||
import os
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
@@ -18,17 +17,35 @@ from flask import current_app
|
||||
|
||||
load_dotenv(find_dotenv())
|
||||
|
||||
# CLASSES
|
||||
class Config:
|
||||
is_development = False
|
||||
is_production = False
|
||||
# Miscellaneous
|
||||
DEBUG = False # av.input_bool(os.getenv('DEBUG'), 'DEBUG', 'Config')
|
||||
TESTING = False
|
||||
URL_HOST = os.getenv('URL_HOST')
|
||||
SECRET_KEY = os.getenv('KEY_SECRET_FLASK') # gen cmd: openssl rand -hex 32
|
||||
# Add other configuration variables as needed
|
||||
# MySQL
|
||||
|
||||
DB_HOST = os.getenv('DB_HOST')
|
||||
DB_NAME = os.getenv('partsltd_prod')
|
||||
DB_PASSWORD = os.getenv('DB_PASSWORD')
|
||||
DB_USER = os.getenv('DB_USER')
|
||||
DEBUG = False
|
||||
DOMAIN_AUTH0 = os.getenv('DOMAIN_AUTH0')
|
||||
ID_AUTH0_CLIENT = os.getenv('ID_AUTH0_CLIENT')
|
||||
ID_AUTH0_CLIENT_SECRET = os.getenv('ID_AUTH0_CLIENT_SECRET')
|
||||
ID_TOKEN_USER = 'user'
|
||||
MAIL_DEBUG = False
|
||||
MAIL_SERVER = 'mail.partsltd.co.uk'
|
||||
MAIL_PORT = 465
|
||||
MAIL_USE_TLS = False
|
||||
MAIL_USE_SSL = True
|
||||
MAIL_USERNAME = os.getenv('MAIL_DEFAULT_SENDER')
|
||||
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')
|
||||
MAIL_DEFAULT_SENDER = os.getenv('MAIL_DEFAULT_SENDER')
|
||||
MAIL_CONTACT_PUBLIC = os.getenv('MAIL_CONTACT_PUBLIC')
|
||||
RECAPTCHA_PUBLIC_KEY = os.getenv('RECAPTCHA_PUBLIC_KEY')
|
||||
RECAPTCHA_PRIVATE_KEY = os.getenv('RECAPTCHA_PRIVATE_KEY')
|
||||
REMEMBER_COOKIE_SECURE = True
|
||||
SECRET_KEY = os.getenv('KEY_SECRET_FLASK')
|
||||
SESSION_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax' # 'Strict' # Strict is preferable for security, but Lax is required for OAuth functionality
|
||||
SQLALCHEMY_DATABASE_URI = os.getenv('SQLALCHEMY_DATABASE_URI')
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SQLALCHEMY_ENGINE_OPTIONS = {
|
||||
@@ -37,91 +54,28 @@ class Config:
|
||||
'pool_pre_ping': True,
|
||||
'pool_timeout': 30,
|
||||
}
|
||||
# Auth0
|
||||
SESSION_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax' # 'Strict' # Strict is preferable for security, but Lax is required for OAuth functionality
|
||||
REMEMBER_COOKIE_SECURE = True
|
||||
# PERMANENT_SESSION_LIFETIME = 3600
|
||||
TESTING = False
|
||||
URL_HOST = os.getenv('URL_HOST')
|
||||
WTF_CSRF_ENABLED = True
|
||||
# WTF_CSRF_CHECK_DEFAULT = False # We'll check it manually for API routes
|
||||
# WTF_CSRF_HEADERS = ['X-CSRFToken'] # Accept CSRF token from this header
|
||||
WTF_CSRF_SSL_STRICT = False
|
||||
WTF_CSRF_TIME_LIMIT = None
|
||||
WTF_CSRF_SSL_STRICT = False # Allows testing without HTTPS
|
||||
ID_AUTH0_CLIENT = os.getenv('ID_AUTH0_CLIENT')
|
||||
ID_AUTH0_CLIENT_SECRET = os.getenv('ID_AUTH0_CLIENT_SECRET')
|
||||
DOMAIN_AUTH0 = os.getenv('DOMAIN_AUTH0')
|
||||
ID_TOKEN_USER = 'user'
|
||||
# PostgreSQL
|
||||
DB_NAME = os.getenv('partsltd')
|
||||
DB_USER = os.getenv('DB_USER')
|
||||
DB_PASSWORD = os.getenv('DB_PASSWORD')
|
||||
DB_HOST = os.getenv('DB_HOST')
|
||||
# DB_PORT = os.getenv('DB_PORT')
|
||||
# Store
|
||||
# is_included_VAT = True
|
||||
"""
|
||||
KEY_IS_INCLUDED_VAT = 'is_included_VAT'
|
||||
code_currency = 1
|
||||
KEY_CODE_CURRENCY = 'id_currency'
|
||||
code_region_delivery = 1
|
||||
KEY_CODE_REGION_DELIVERY = 'id_region_delivery'
|
||||
KEY_ID_CURRENCY = 'id_currency'
|
||||
KEY_ID_REGION_DELIVERY = 'id_region_delivery'
|
||||
"""
|
||||
# id_currency = 1
|
||||
# id_region_delivery = 1
|
||||
# Mail
|
||||
MAIL_DEBUG = False # av.input_bool(os.getenv('DEBUG'), 'DEBUG', 'Config')
|
||||
MAIL_SERVER = 'mail.partsltd.co.uk' # 'smtp.gmail.com'
|
||||
MAIL_PORT = 465 # 587
|
||||
MAIL_USE_TLS = False
|
||||
MAIL_USE_SSL = True
|
||||
MAIL_USERNAME = os.getenv('MAIL_DEFAULT_SENDER')
|
||||
MAIL_PASSWORD = os.getenv('MAIL_PASSWORD')
|
||||
MAIL_DEFAULT_SENDER = os.getenv('MAIL_DEFAULT_SENDER')
|
||||
MAIL_CONTACT_PUBLIC = os.getenv('MAIL_CONTACT_PUBLIC')
|
||||
# Recaptcha
|
||||
RECAPTCHA_PUBLIC_KEY = os.getenv('RECAPTCHA_PUBLIC_KEY')
|
||||
RECAPTCHA_PRIVATE_KEY = os.getenv('RECAPTCHA_PRIVATE_KEY')
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
is_development = True
|
||||
# Add development-specific configuration variables
|
||||
DEBUG = True
|
||||
MAIL_DEBUG = True
|
||||
SESSION_COOKIE_SECURE = False
|
||||
|
||||
class ProductionConfig(Config):
|
||||
is_production = True
|
||||
# Add production-specific configuration variables
|
||||
pass
|
||||
|
||||
# Set the configuration class based on the environment
|
||||
# You can change 'development' to 'production' when deploying
|
||||
config_env = os.getenv('FLASK_ENV', "production")
|
||||
with open('app.log', 'a') as f:
|
||||
print(f'config_env: {config_env}')
|
||||
f.write(f'config_env: {config_env}\n')
|
||||
# current_app.logger.error(f'config_env: {config_env}') # logger not yet initialised
|
||||
if config_env == 'development':
|
||||
app_config = DevelopmentConfig
|
||||
elif config_env == 'production':
|
||||
app_config = ProductionConfig
|
||||
else:
|
||||
raise ValueError("Invalid configuration environment")
|
||||
|
||||
# environment variables
|
||||
"""
|
||||
SET KEY_SECRET_FLASK=nips
|
||||
SET ID_AUTH0_CLIENT=
|
||||
SET ID_AUTH0_CLIENT_SECRET=
|
||||
SET DOMAIN_AUTH0=
|
||||
SET MAIL_PASSWORD=
|
||||
SET RECAPTCHA_PUBLIC_KEY=
|
||||
SET RECAPTCHA_PRIVATE_KEY=
|
||||
SET SQLALCHEMY_DATABASE_URI=
|
||||
SET URL_HOST=
|
||||
"""
|
||||
# SET SQLALCHEMY_DATABASE_URI = mysql://username:password@localhost/dbname
|
||||
# Replace 'username', 'password', 'localhost', and 'dbname' with your actual database credentials
|
||||
@@ -59,18 +59,15 @@ def contact_post():
|
||||
try:
|
||||
form = Form_Contact()
|
||||
if form.validate_on_submit():
|
||||
# Handle form submission
|
||||
email = form.email.data
|
||||
CC = form.CC.data # not in use
|
||||
# CC = form.CC.data # not in use
|
||||
name = form.name.data
|
||||
message = form.message.data
|
||||
# send email
|
||||
mailItem = Message("PARTS Website Contact Us Message", recipients=[current_app.config['MAIL_CONTACT_PUBLIC']])
|
||||
mailItem.body = f"Dear Lord Edward Middleton-Smith,\n\n{message}\n\nKind regards,\n{name}\n{email}"
|
||||
mail.send(mailItem)
|
||||
return "Submitted."
|
||||
return "Invalid. Failed to submit."
|
||||
# html_body = render_template('pages/core/_contact.html', model = model)
|
||||
except Exception as e:
|
||||
return jsonify(error=str(e)), 403
|
||||
|
||||
@@ -88,7 +85,6 @@ def admin_home():
|
||||
try:
|
||||
model = Model_View_Admin_Home()
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', callback = Model_View_Admin_Home.HASH_PAGE_ADMIN_HOME))
|
||||
return redirect(url_for('routes_core.home'))
|
||||
if not (model.user.can_admin_store or model.user.can_admin_user):
|
||||
return redirect(url_for('routes_core.home'))
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: App General
|
||||
Feature: App
|
||||
|
||||
Description:
|
||||
Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles.
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
from helpers.helper_app import Helper_App
|
||||
import os
|
||||
import stripe
|
||||
import json
|
||||
from flask import Flask, render_template, render_template_string, jsonify, request, send_from_directory, redirect
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
key_secret = os.environ.get("KEY_SECRET_STRIPE")
|
||||
key_public = os.environ.get("KEY_PUBLIC_STRIPE") # 'pk_test_51OGrxlL7BuLKjoMpfpfw7bSmZZK1MhqMoQ5VhW2jUj7YtoEejO4vqnxKPiqTHHuh9U4qqkywbPCSI9TpFKtr4SYH007KHMWs68'
|
||||
|
||||
# METHODS
|
||||
def create_product_price():
|
||||
Helper_App.console_log(f'stripe.api_key = {stripe.api_key}')
|
||||
starter_subscription = stripe.Product.create(
|
||||
name="Starter Subscription",
|
||||
description="$12/Month subscription",
|
||||
)
|
||||
|
||||
starter_subscription_price = stripe.Price.create(
|
||||
unit_amount=1200,
|
||||
currency="usd",
|
||||
recurring={"interval": "month"},
|
||||
product=starter_subscription['id'],
|
||||
)
|
||||
|
||||
# Save these identifiers
|
||||
Helper_App.console_log(f"Success! Here is your starter subscription product id: {starter_subscription.id}")
|
||||
Helper_App.console_log(f"Success! Here is your starter subscription price id: {starter_subscription_price.id}")
|
||||
|
||||
return starter_subscription_price.id
|
||||
|
||||
def get_file_str(f_address):
|
||||
f = open(f_address)
|
||||
return f.read()
|
||||
|
||||
# Ensure environment variables are set.
|
||||
price = os.getenv('PRICE')
|
||||
if price is None or price == 'price_12345' or price == '':
|
||||
Helper_App.console_log('You must set a Price ID in .env. Please see the README.')
|
||||
exit(0)
|
||||
|
||||
# For sample support and debugging, not required for production:
|
||||
stripe.set_app_info(
|
||||
'stripe-samples/checkout-one-time-payments',
|
||||
version='0.0.1',
|
||||
url='https://github.com/stripe-samples/checkout-one-time-payments')
|
||||
|
||||
# stripe.api_version = '2020-08-27'
|
||||
stripe.api_key = key_secret # os.getenv('KEY_SECRET_STRIPE')
|
||||
|
||||
app_dir = str(os.path.abspath(os.path.join(
|
||||
__file__, "..", "..")))
|
||||
static_dir = str(os.path.abspath(os.path.join(
|
||||
app_dir, os.getenv("STATIC_DIR"))))
|
||||
app = Flask(__name__, static_folder=static_dir,
|
||||
static_url_path="", template_folder=static_dir)
|
||||
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def get_example():
|
||||
# return render_template(f'{app_dir}\\templates\\_home.html') # f'{app_dir}\\templates\\layout.html')
|
||||
# return render_template_string(get_file_str(f'{app_dir}\\templates\\_home.html')) # f'{app_dir}\\templates\\layout.html')
|
||||
return render_template('../templates/_home.html')
|
||||
|
||||
|
||||
@app.route('/config', methods=['GET'])
|
||||
def get_publishable_key():
|
||||
price = stripe.Price.retrieve(os.getenv('PRICE'))
|
||||
return jsonify({
|
||||
'publicKey': key_public, # os.getenv('KEY_PUBLIC_STRIPE'),
|
||||
'unitAmount': price['unit_amount'],
|
||||
'currency': price['currency']
|
||||
})
|
||||
|
||||
# Fetch the Checkout Session to display the JSON result on the success page
|
||||
@app.route('/checkout-session', methods=['GET'])
|
||||
def get_checkout_session():
|
||||
id = request.args.get('sessionId')
|
||||
checkout_session = stripe.checkout.Session.retrieve(id)
|
||||
return jsonify(checkout_session)
|
||||
|
||||
|
||||
@app.route('/create-checkout-session', methods=['POST'])
|
||||
def create_checkout_session():
|
||||
quantity = request.form.get('quantity', 1)
|
||||
domain_url = os.getenv('DOMAIN')
|
||||
|
||||
try:
|
||||
# Create new Checkout Session for the order
|
||||
# Other optional params include:
|
||||
# [billing_address_collection] - to display billing address details on the page
|
||||
# [customer] - if you have an existing Stripe Customer ID
|
||||
# [payment_intent_data] - lets capture the payment later
|
||||
# [customer_email] - lets you prefill the email input in the form
|
||||
# [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page
|
||||
# For full details see https://stripe.com/docs/api/checkout/sessions/create
|
||||
|
||||
# ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param
|
||||
checkout_session = stripe.checkout.Session.create(
|
||||
success_url=domain_url + '/success.html?session_id={CHECKOUT_SESSION_ID}',
|
||||
cancel_url=domain_url + '/canceled.html',
|
||||
mode='payment',
|
||||
# automatic_tax={'enabled': True},
|
||||
line_items=[{
|
||||
'price': os.getenv('PRICE'),
|
||||
'quantity': quantity,
|
||||
}]
|
||||
)
|
||||
return redirect(checkout_session.url, code=303)
|
||||
except Exception as e:
|
||||
return jsonify(error=str(e)), 403
|
||||
|
||||
|
||||
@app.route('/webhook', methods=['POST'])
|
||||
def webhook_received():
|
||||
# You can use webhooks to receive information about asynchronous payment events.
|
||||
# For more about our webhook events check out https://stripe.com/docs/webhooks.
|
||||
webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET')
|
||||
request_data = json.loads(request.data)
|
||||
|
||||
if webhook_secret:
|
||||
# Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
|
||||
signature = request.headers.get('stripe-signature')
|
||||
try:
|
||||
event = stripe.Webhook.construct_event(
|
||||
payload=request.data, sig_header=signature, secret=webhook_secret)
|
||||
data = event['data']
|
||||
except Exception as e:
|
||||
return e
|
||||
# Get the type of webhook event sent - used to check the status of PaymentIntents.
|
||||
event_type = event['type']
|
||||
else:
|
||||
data = request_data['data']
|
||||
event_type = request_data['type']
|
||||
data_object = data['object']
|
||||
|
||||
Helper_App.console_log('event ' + event_type)
|
||||
|
||||
if event_type == 'checkout.session.completed':
|
||||
Helper_App.console_log('🔔 Payment succeeded!')
|
||||
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# stripe.api_key = key_secret
|
||||
|
||||
# create_product_price()
|
||||
|
||||
# Setup Stripe python client library.
|
||||
load_dotenv(find_dotenv())
|
||||
app.run(port=4242, debug=True)
|
||||
@@ -39,7 +39,6 @@ def products():
|
||||
Helper_App.console_log(f'form_filters={form_filters}')
|
||||
model = Model_View_Store_Product(form_filters)
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product.FLAG_CALLBACK: Model_View_Store_Product.HASH_PAGE_STORE_PRODUCTS })))
|
||||
return redirect(url_for('routes_core.home'))
|
||||
return render_template('pages/store/_products.html', model = model)
|
||||
|
||||
@@ -54,7 +53,6 @@ def save_product():
|
||||
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_FAILURE,
|
||||
Model_View_Store_Product.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
|
||||
})
|
||||
# filters_form = Filters_Product.from_form(form_filters)
|
||||
Helper_App.console_log(f'form_filters: {form_filters}')
|
||||
|
||||
products = data[Model_View_Store_Product.FLAG_PRODUCT]
|
||||
@@ -66,7 +64,6 @@ def save_product():
|
||||
objsProduct = []
|
||||
for product in products:
|
||||
objsProduct.append(Product.from_json(product))
|
||||
# model_save = Model_View_Store_Product() # filters_product=filters_form)
|
||||
Helper_App.console_log(f'objsProduct={objsProduct}')
|
||||
save_errors = Model_View_Store_Product.save_products(data.get('comment', 'No comment'), objsProduct)
|
||||
|
||||
|
||||
@@ -31,31 +31,14 @@ routes_store_product_category = Blueprint('routes_store_product_category', __nam
|
||||
@routes_store_product_category.route(Model_View_Store_Product_Category.HASH_PAGE_STORE_PRODUCT_CATEGORIES, methods=['GET'])
|
||||
def categories():
|
||||
Helper_App.console_log('categories')
|
||||
# data = Helper_App.get_request_data(request)
|
||||
try:
|
||||
form_filters = Filters_Product_Category.from_json(request.args)
|
||||
except Exception as e:
|
||||
Helper_App.console_log(f'Error: {e}')
|
||||
form_filters = Filters_Product_Category()
|
||||
Helper_App.console_log(f'form_filters={form_filters}')
|
||||
"""
|
||||
filters = Filters_Product_Category.get_default()
|
||||
have_changed_filters = False
|
||||
arg_filter_is_not_empty = request.args.get(Model_View_Store_Product_Category.FLAG_IS_NOT_EMPTY, None)
|
||||
have_changed_filters = have_changed_filters or arg_filter_is_not_empty is None
|
||||
Helper_App.console_log(f'arg_filter_is_not_empty={arg_filter_is_not_empty}')
|
||||
filters.is_not_empty = filters.is_not_empty if arg_filter_is_not_empty is None else av.input_bool(arg_filter_is_not_empty, 'is_not_empty', 'filter_category')
|
||||
arg_filter_active = request.args.get(Model_View_Store_Product_Category.FLAG_ACTIVE, None)
|
||||
have_changed_filters = have_changed_filters or arg_filter_active is None
|
||||
Helper_App.console_log(f'arg_filter_active={arg_filter_active}')
|
||||
filters.active = filters.active if arg_filter_active is None else av.input_bool(arg_filter_active, 'active', 'filter_category')
|
||||
if have_changed_filters:
|
||||
Helper_App.console_log('redirecting')
|
||||
return redirect(url_for('routes_store_product_category.categories', **filters.to_json()))
|
||||
"""
|
||||
model = Model_View_Store_Product_Category(form_filters)
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Category.FLAG_CALLBACK: Model_View_Store_Product_Category.HASH_PAGE_STORE_PRODUCT_CATEGORIES })))
|
||||
return redirect(url_for('routes_core.home'))
|
||||
return render_template('pages/store/_product_categories.html', model = model)
|
||||
|
||||
@@ -69,7 +52,6 @@ def save_category():
|
||||
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_FAILURE,
|
||||
Model_View_Store_Product_Category.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
|
||||
})
|
||||
# filters_form = Filters_Product_Category.from_form(form_filters)
|
||||
|
||||
categories = data[Model_View_Store_Product_Category.FLAG_PRODUCT_CATEGORY]
|
||||
if len(categories) == 0:
|
||||
@@ -80,7 +62,6 @@ def save_category():
|
||||
objsCategory = []
|
||||
for category in categories:
|
||||
objsCategory.append(Product_Category.from_json(category))
|
||||
# model_save = Model_View_Store_Product_Category() # filters_product=filters_form)
|
||||
Helper_App.console_log(f'objsCategory={objsCategory}')
|
||||
errors = Model_View_Store_Product_Category.save_categories(data.get('comment', 'No comment'), objsCategory)
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ routes_store_product_permutation = Blueprint('routes_store_product_permutation',
|
||||
def permutations():
|
||||
Helper_App.console_log('permutations')
|
||||
data = request.args
|
||||
# Helper_App.console_log(f'data={data}\nrequest.args={request.args}\nrequest.form={request.form}\nrequest.data={request.data}\nrequest.values={request.values}\nrequest.headers={request.headers}')
|
||||
try:
|
||||
form_filters = Filters_Product_Permutation.from_json(data)
|
||||
except Exception as e:
|
||||
@@ -43,7 +42,6 @@ def permutations():
|
||||
Helper_App.console_log(f'form_filters={form_filters}')
|
||||
model = Model_View_Store_Product_Permutation(form_filters)
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Permutation.FLAG_CALLBACK: Model_View_Store_Product_Permutation.HASH_PAGE_STORE_PRODUCT_PERMUTATIONS })))
|
||||
return redirect(url_for('routes_core.home'))
|
||||
return render_template('pages/store/_product_permutations.html', model = model)
|
||||
|
||||
@@ -58,7 +56,6 @@ def save_permutation():
|
||||
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_FAILURE,
|
||||
Model_View_Store_Product_Permutation.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
|
||||
})
|
||||
# filters_form = Filters_Product_Permutation.from_form(form_filters)
|
||||
Helper_App.console_log(f'form_filters: {form_filters}')
|
||||
|
||||
permutations = data[Model_View_Store_Product_Permutation.FLAG_PRODUCT_PERMUTATION]
|
||||
@@ -70,7 +67,6 @@ def save_permutation():
|
||||
objsPermutation = []
|
||||
for permutation in permutations:
|
||||
objsPermutation.append(Product_Permutation.from_json(permutation))
|
||||
# model_save = Model_View_Store_Product_Permutation() # filters_product=filters_form)
|
||||
Helper_App.console_log(f'objsPermutation={objsPermutation}')
|
||||
Model_View_Store_Product_Permutation.save_permutations(data.get('comment', 'No comment'), objsPermutation)
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ def save_product_variation():
|
||||
Model_View_Store_Product_Variation.FLAG_STATUS: Model_View_Store_Product_Variation.FLAG_FAILURE,
|
||||
Model_View_Store_Product_Variation.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
|
||||
})
|
||||
# filters_form = Filters_Product_Variation.from_form(form_filters)
|
||||
Helper_App.console_log(f'form_filters: {form_filters}')
|
||||
|
||||
product_variation_types = data[Model_View_Store_Product_Variation.FLAG_PRODUCT_VARIATION_TYPE]
|
||||
@@ -67,7 +66,6 @@ def save_product_variation():
|
||||
objs_product_variation_type = []
|
||||
for product_variation_type in product_variation_types:
|
||||
objs_product_variation_type.append(Product_Variation_Type.from_json(product_variation_type))
|
||||
# model_save = Model_View_Store_Product_Variation() # filters_product_variation=filters_form)
|
||||
Helper_App.console_log(f'objs_product_variation_type={objs_product_variation_type}')
|
||||
save_errors = Model_View_Store_Product_Variation.save_product_variations(data.get('comment', 'No comment'), objs_product_variation_type)
|
||||
|
||||
|
||||
@@ -39,8 +39,6 @@ def stock_items():
|
||||
Helper_App.console_log(f'form_filters={form_filters}')
|
||||
model = Model_View_Store_Stock_Item(form_filters)
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Stock_Item.FLAG_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })))
|
||||
# return requests.post(f"{current_app.config['URL_HOST']}{url_for('routes_user.login')}", json={ Model_View_Store_Stock_Item.FLAG_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })
|
||||
return redirect(url_for('routes_core.home'))
|
||||
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
|
||||
|
||||
@@ -50,28 +48,6 @@ def save_stock_item():
|
||||
data = Helper_App.get_request_data(request)
|
||||
try:
|
||||
form_filters = Filters_Stock_Item.from_json(data[Model_View_Store_Stock_Item.FLAG_FORM_FILTERS])
|
||||
"""
|
||||
if not form_filters.validate_on_submit():
|
||||
error_keys = list(form_filters.errors.keys())
|
||||
try:
|
||||
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT_CATEGORY)
|
||||
""
|
||||
if not av.val_int(form_filters.id_product_category.data):
|
||||
form_filters.errors[Stock_Item.ATTR_ID_PRODUCT_CATEGORY] = ['Invalid category.']
|
||||
""
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT)
|
||||
except:
|
||||
pass
|
||||
if error_keys:
|
||||
return jsonify({
|
||||
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
|
||||
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
|
||||
})
|
||||
"""
|
||||
# filters_form = Filters_Stock_Item.from_form(form_filters)
|
||||
Helper_App.console_log(f'form_filters: {form_filters}')
|
||||
|
||||
stock_items = data[Model_View_Store_Stock_Item.FLAG_STOCK_ITEM]
|
||||
@@ -84,7 +60,6 @@ def save_stock_item():
|
||||
objs_stock_item = []
|
||||
for stock_item in stock_items:
|
||||
objs_stock_item.append(Stock_Item.from_json(stock_item))
|
||||
# model_save = Model_View_Store_Stock_Item() # filters_product=filters_form)
|
||||
Helper_App.console_log(f'objs_stock_item={objs_stock_item}')
|
||||
save_errors = Model_View_Store_Stock_Item.save_stock_items(data.get('comment', 'No comment'), objs_stock_item)
|
||||
if len(save_errors) > 0:
|
||||
|
||||
@@ -116,7 +116,7 @@ def login():
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
|
||||
@routes_user.route("/login_callback") # <path:subpath>/<code>
|
||||
@routes_user.route("/login_callback")
|
||||
@handle_db_disconnect
|
||||
def login_callback():
|
||||
Helper_App.console_log('login_callback')
|
||||
@@ -128,25 +128,13 @@ def login_callback():
|
||||
error_text = f'Error: {error_state}: {error_description}'
|
||||
Helper_App.console_log(error_text)
|
||||
return login()
|
||||
# Helper_App.console_log(f'code: {code}')
|
||||
token = None
|
||||
try:
|
||||
token = oauth.auth0.authorize_access_token()
|
||||
except Exception as e:
|
||||
# Log the error for debugging
|
||||
Helper_App.console_log(f"Error: {str(e)}")
|
||||
session[current_app.config['ID_TOKEN_USER']] = token
|
||||
# import user id
|
||||
"""
|
||||
Helper_App.console_log(f'str(type(token)) = {str(type(token))}')
|
||||
Helper_App.console_log(f'token = {token}')
|
||||
userinfo = token.get('userinfo')
|
||||
Helper_App.console_log(f'user info: {userinfo}')
|
||||
# id_user = token.get('sub')
|
||||
id_user = userinfo.get('sub')
|
||||
Helper_App.console_log(f'user ID: {id_user}')
|
||||
"""
|
||||
user = User.from_json_auth0(token) # datastore_user.get_user_auth0()
|
||||
user = User.from_json_auth0(token)
|
||||
Helper_App.console_log(f'user: {user}')
|
||||
filters = Parameters_User.from_user(user)
|
||||
datastore_user = DataStore_User()
|
||||
@@ -168,13 +156,10 @@ def login_callback():
|
||||
Helper_App.console_log('hash is none')
|
||||
state = request.args.get('state')
|
||||
Helper_App.console_log(f'state: {state}')
|
||||
hash_callback = state # .get('hash_callback')
|
||||
hash_callback = state
|
||||
Helper_App.console_log(f'hash_callback: {hash_callback}')
|
||||
except:
|
||||
Helper_App.console_log("get hash callback failed")
|
||||
# id_user = get_id_user()
|
||||
# add user to database
|
||||
# DataStore_Store().add_new_user(id_user) # this is part of get basket - should occur on page load
|
||||
|
||||
Helper_App.console_log(f'user session: {session[Model_View_Base.FLAG_USER]}')
|
||||
return redirect(f"{current_app.config['URL_HOST']}{hash_callback}")
|
||||
@@ -188,38 +173,15 @@ def logout():
|
||||
{
|
||||
"returnTo": url_for("routes_user.logout_callback", _external=True),
|
||||
"client_id": current_app.config['ID_AUTH0_CLIENT'],
|
||||
}# ,
|
||||
# quote_via=quote_plus,
|
||||
}
|
||||
)
|
||||
Helper_App.console_log(f"Redirecting to {url_logout}")
|
||||
return redirect(url_logout)
|
||||
|
||||
@routes_user.route("/logout_callback") # <path:subpath>/<code>
|
||||
@routes_user.route("/logout_callback")
|
||||
@handle_db_disconnect
|
||||
def logout_callback():
|
||||
return redirect(url_for('routes_core.home'))
|
||||
try:
|
||||
session[current_app.ID_TOKEN_USER] = None
|
||||
user = User()
|
||||
try:
|
||||
hash_callback = token.get('hash_callback')
|
||||
if hash_callback is None:
|
||||
Helper_App.console_log('hash is none')
|
||||
state = request.args.get('state')
|
||||
Helper_App.console_log(f'state: {state}')
|
||||
hash_callback = state # .get('hash_callback')
|
||||
Helper_App.console_log(f'hash_callback: {hash_callback}')
|
||||
except:
|
||||
Helper_App.console_log("get hash callback failed")
|
||||
# id_user = get_id_user()
|
||||
# add user to database
|
||||
# DataStore_Store().add_new_user(id_user) # this is part of get basket - should occur on page load
|
||||
|
||||
Helper_App.console_log(f'user session: {session[Model_View_Base.FLAG_USER]}')
|
||||
return redirect(f'{current_app.URL_HOST}{hash_callback}')
|
||||
except Exception as e:
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Controller error.\n{e}'})
|
||||
|
||||
|
||||
@routes_user.route("/user")
|
||||
def user():
|
||||
@@ -235,7 +197,6 @@ def user():
|
||||
break
|
||||
model.users = [model.user]
|
||||
if not model.is_user_logged_in:
|
||||
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_User.FLAG_CALLBACK: Model_View_User.HASH_PAGE_USER_ACCOUNT })))
|
||||
return redirect(url_for('routes_core.home'))
|
||||
html_body = render_template('pages/user/_user.html', model = model)
|
||||
except Exception as e:
|
||||
|
||||
@@ -14,16 +14,6 @@ Datastore for Store
|
||||
# from routes import bp_home
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.access_level import Access_Level
|
||||
"""
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Product_Category_Container, Product_Category
|
||||
from business_objects.store.currency import Currency
|
||||
from business_objects.store.image import Image
|
||||
from business_objects.store.delivery_option import Delivery_Option
|
||||
from business_objects.store.discount import Discount
|
||||
from business_objects.store.order import Order
|
||||
from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product # Permutation_Variation_Link
|
||||
"""
|
||||
from business_objects.region import Region
|
||||
from business_objects.sql_error import SQL_Error
|
||||
from business_objects.store.stock_item import Stock_Item
|
||||
@@ -48,29 +38,11 @@ from datetime import datetime
|
||||
import time
|
||||
from sqlalchemy.exc import OperationalError
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_Base(BaseModel):
|
||||
# Global constants
|
||||
# Attributes
|
||||
"""
|
||||
app: Flask = None
|
||||
db: SQLAlchemy = None
|
||||
session: object = None
|
||||
"""
|
||||
|
||||
# model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
# Constructor
|
||||
"""
|
||||
self.db = db
|
||||
self.app = current_app
|
||||
with self.app.app_context():
|
||||
self.session = session
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def db_procedure_execute(proc_name, argument_dict_list = None):
|
||||
# Argument validation
|
||||
@@ -78,9 +50,7 @@ class DataStore_Base(BaseModel):
|
||||
av.val_str(proc_name, 'proc_name', _m)
|
||||
has_arguments = not str(type(argument_dict_list)) == "<class 'NoneType'>"
|
||||
if has_arguments:
|
||||
# av.val_list_instances(argument_dict_list, 'argument_dict_list', _m, dict)
|
||||
pass
|
||||
# Methods
|
||||
proc_string = f'CALL {proc_name}('
|
||||
if has_arguments:
|
||||
arg_keys = list(argument_dict_list.keys())
|
||||
@@ -90,15 +60,12 @@ class DataStore_Base(BaseModel):
|
||||
proc_string = text(proc_string)
|
||||
Helper_App.console_log(f'{_m}\nproc_string: {proc_string}\nargs: {argument_dict_list}')
|
||||
|
||||
# with self.db.session.begin() as session:
|
||||
# conn = Helper_DB_MySQL(self.app).get_db_connection()
|
||||
|
||||
if has_arguments:
|
||||
result = db.session.execute(proc_string, argument_dict_list)
|
||||
else:
|
||||
result = db.session.execute(proc_string)
|
||||
Helper_App.console_log(f'result: {result}')
|
||||
# conn.session.remove()
|
||||
|
||||
return result
|
||||
cursor = result.cursor
|
||||
result_set_1 = cursor.fetchall()
|
||||
@@ -200,7 +167,7 @@ class DataStore_Base(BaseModel):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -217,7 +184,6 @@ class DataStore_Base(BaseModel):
|
||||
if db.session.dirty or db.session.new or db.session.deleted:
|
||||
Helper_App.console_log("Session is not clean")
|
||||
return
|
||||
# Assuming `permanent_table_name` is a string representing the table name
|
||||
table_object = db.metadata.tables.get(permanent_table_name)
|
||||
if table_object is None:
|
||||
Helper_App.console_log(f"Table {permanent_table_name} not found in metadata.")
|
||||
@@ -225,30 +191,7 @@ class DataStore_Base(BaseModel):
|
||||
else:
|
||||
expected_columns = set(column.name for column in db.inspect(table_object).columns)
|
||||
Helper_App.console_log(f'expected_columns: {expected_columns}')
|
||||
""" v1, v2
|
||||
try:
|
||||
for i in range(0, len(records), batch_size):
|
||||
"" v1
|
||||
batch = records[i:i+batch_size]
|
||||
Helper_App.console_log(f'batch: {batch}')
|
||||
db.session.bulk_save_objects(batch)
|
||||
""
|
||||
""
|
||||
data = [object.to_json() for object in batch]
|
||||
Helper_App.console_log(f'data: {data}')
|
||||
for row in data:
|
||||
row_keys = set(row.keys())
|
||||
if row_keys != expected_columns:
|
||||
Helper_App.console_log(f"Column mismatch in row: {row}")
|
||||
Helper_App.console_log(f'missing columns: {expected_columns - row_keys}')
|
||||
Helper_App.console_log(f'extra columns: {row_keys - expected_columns}')
|
||||
# db.session.bulk_insert_mappings(permanent_table_name, data)
|
||||
""
|
||||
except Exception as e:
|
||||
Helper_App.console_log(f'{_m}\n{e}')
|
||||
db.session.rollback()
|
||||
raise e
|
||||
"""
|
||||
|
||||
max_retries = 3
|
||||
initial_backoff = 1
|
||||
for i in range(0, len(records), batch_size):
|
||||
@@ -269,7 +212,6 @@ class DataStore_Base(BaseModel):
|
||||
time.sleep(wait_time)
|
||||
retries += 1
|
||||
|
||||
# Ensure the session is clean for the retry
|
||||
db.session.rollback()
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
@@ -282,8 +224,6 @@ class DataStore_Base(BaseModel):
|
||||
filters = Filters_Access_Level()
|
||||
av.val_instance(filters, 'filters', _m, Filters_Access_Level)
|
||||
argument_dict = filters.to_json()
|
||||
# user = cls.get_user_session()
|
||||
# argument_dict['a_id_user'] = 1 # 'auth0|6582b95c895d09a70ba10fef' # id_user
|
||||
Helper_App.console_log(f'argument_dict: {argument_dict}')
|
||||
Helper_App.console_log('executing p_shop_get_many_access_level')
|
||||
result = cls.db_procedure_execute('p_shop_get_many_access_level', argument_dict)
|
||||
@@ -304,7 +244,7 @@ class DataStore_Base(BaseModel):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -319,8 +259,6 @@ class DataStore_Base(BaseModel):
|
||||
filters = Filters_Unit_Measurement()
|
||||
av.val_instance(filters, 'filters', _m, Filters_Unit_Measurement)
|
||||
argument_dict = filters.to_json()
|
||||
# user = cls.get_user_session()
|
||||
# argument_dict['a_id_user'] = 1 # 'auth0|6582b95c895d09a70ba10fef' # id_user
|
||||
Helper_App.console_log(f'argument_dict: {argument_dict}')
|
||||
Helper_App.console_log('executing p_shop_get_many_unit_measurement')
|
||||
result = cls.db_procedure_execute('p_shop_get_many_unit_measurement', argument_dict)
|
||||
@@ -341,7 +279,7 @@ class DataStore_Base(BaseModel):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -364,7 +302,6 @@ class DataStore_Base(BaseModel):
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
# cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
regions = []
|
||||
for row in result_set_1:
|
||||
|
||||
@@ -12,18 +12,16 @@ Datastore for Store
|
||||
|
||||
# internal
|
||||
# from routes import bp_home
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Product_Category_Container, Product_Category
|
||||
from business_objects.currency import Currency
|
||||
from business_objects.store.image import Image
|
||||
from business_objects.store.delivery_option import Delivery_Option
|
||||
from business_objects.region import Region
|
||||
from business_objects.store.discount import Discount
|
||||
from business_objects.store.order import Order
|
||||
from business_objects.store.plant import Plant
|
||||
from business_objects.store.product import Product, Product_Permutation, Parameters_Product
|
||||
from business_objects.sql_error import SQL_Error
|
||||
from business_objects.store.stock_item import Stock_Item
|
||||
from business_objects.store.store_base import Store_Base
|
||||
from business_objects.store.storage_location import Storage_Location
|
||||
from business_objects.store.product_variation import Product_Variation, Parameters_Product_Variation
|
||||
from business_objects.store.product_variation_type import Product_Variation_Type
|
||||
@@ -44,30 +42,22 @@ from pydantic import BaseModel, ConfigDict
|
||||
from typing import ClassVar
|
||||
from datetime import datetime
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_Store_Base(DataStore_Base):
|
||||
# Global constants
|
||||
KEY_BASKET: ClassVar[str] = Basket.KEY_BASKET
|
||||
KEY_IS_INCLUDED_VAT: ClassVar[str] = Basket.KEY_IS_INCLUDED_VAT # 'is_included_VAT'
|
||||
KEY_ID_CURRENCY: ClassVar[str] = Basket.KEY_ID_CURRENCY # 'id_currency'
|
||||
KEY_ID_REGION_DELIVERY: ClassVar[str] = Basket.KEY_ID_REGION_DELIVERY # 'id_region_delivery'
|
||||
# Attributes
|
||||
KEY_BASKET: ClassVar[str] = Store_Base.KEY_BASKET
|
||||
KEY_IS_INCLUDED_VAT: ClassVar[str] = Store_Base.KEY_IS_INCLUDED_VAT
|
||||
KEY_ID_CURRENCY: ClassVar[str] = Store_Base.KEY_ID_CURRENCY
|
||||
KEY_ID_REGION_DELIVERY: ClassVar[str] = Store_Base.KEY_ID_REGION_DELIVERY
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@classmethod
|
||||
def get_many_product(cls, product_filters):
|
||||
# redundant argument validation?
|
||||
_m = 'DataStore_Store_Base.get_many_product'
|
||||
av.val_instance(product_filters, 'product_filters', _m, Parameters_Product)
|
||||
argument_dict = product_filters.to_json()
|
||||
user = cls.get_user_session()
|
||||
"""
|
||||
argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
|
||||
argument_dict['a_debug'] = 0
|
||||
"""
|
||||
argument_dict = {
|
||||
'a_id_user': user.id_user
|
||||
, **argument_dict
|
||||
@@ -139,18 +129,11 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
category_list.get_all_product_variation_trees()
|
||||
"""
|
||||
for category in category_list.categories:
|
||||
Helper_App.console_log(f'category: {category.name}')
|
||||
for product in category.products:
|
||||
permutation = product.get_permutation_selected()
|
||||
Helper_App.console_log(f'product: {product.name}\nselected permutation: {permutation}')
|
||||
"""
|
||||
|
||||
if len(errors) > 0:
|
||||
for error in errors:
|
||||
@@ -172,18 +155,8 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
cursor.close()
|
||||
|
||||
Helper_App.console_log(f'get many category_list: {category_list}')
|
||||
return category_list, errors # categories, category_index
|
||||
return category_list, errors
|
||||
|
||||
"""
|
||||
def get_many_id_price(self, product_ids):
|
||||
_m = 'DataStore_Store_Base.get_many_id_price'
|
||||
av.val_str(product_ids, 'product_ids', _m)
|
||||
price_ids = []
|
||||
for product_id in product_ids.split(','):
|
||||
if product_id == 'prod_PB0NUOSEs06ymG':
|
||||
price_ids.append() # get price id
|
||||
return price_ids
|
||||
"""
|
||||
@staticmethod
|
||||
def get_ids_permutation_from_error_availability(msg_error_availability):
|
||||
ids_permutation = []
|
||||
@@ -210,7 +183,6 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
# cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
plants = []
|
||||
for row in result_set_1:
|
||||
@@ -236,7 +208,6 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
# cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
storage_locations = []
|
||||
for row in result_set_1:
|
||||
@@ -262,7 +233,6 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
# cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
currencies = []
|
||||
for row in result_set_1:
|
||||
@@ -287,36 +257,22 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
av.val_instance(variation_filters, 'variation_filters', _m, Parameters_Product_Variation)
|
||||
|
||||
guid = Helper_DB_MySQL.create_guid()
|
||||
# now = datetime.now()
|
||||
# user = self.get_user_session()
|
||||
|
||||
"""
|
||||
argument_dict_list = {
|
||||
'a_id_user': id_user,
|
||||
'a_comment': comment,
|
||||
'a_guid': guid
|
||||
}
|
||||
"""
|
||||
user = cls.get_user_session()
|
||||
argument_dict_list = {
|
||||
# 'a_guid': guid
|
||||
'a_id_user': user.id_user
|
||||
, **variation_filters.to_json()
|
||||
, 'a_debug': 0
|
||||
}
|
||||
# argument_dict_list['a_guid'] = guid
|
||||
result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
|
||||
|
||||
cursor = result.cursor
|
||||
result_set_vt = cursor.fetchall()
|
||||
|
||||
# Product_Variation Types
|
||||
# variation_container = Product_Variation_Container()
|
||||
variation_types = []
|
||||
index_variation_type = {}
|
||||
for row in result_set_vt:
|
||||
new_variation_type = Product_Variation_Type.from_DB_get_many_product_variation(row)
|
||||
# variation_container.add_product_variation_type(new_variation_type)
|
||||
new_variation_type = Product_Variation_Type.from_DB_get_many_product_variation(row)
|
||||
index_variation_type[new_variation_type.id_type] = len(variation_types)
|
||||
variation_types.append(new_variation_type)
|
||||
|
||||
@@ -325,12 +281,9 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
# Product_Variations
|
||||
cursor.nextset()
|
||||
result_set_v = cursor.fetchall()
|
||||
# variations = Product_Variation_Container()
|
||||
variations = []
|
||||
for row in result_set_v:
|
||||
new_variation = Product_Variation.from_DB_get_many_product_variation(row)
|
||||
# new_variation.variation_type = variation_types_dict[new_variation.id_type]
|
||||
# variation_container.add_product_variation(new_variation)
|
||||
variation_types[index_variation_type[new_variation.id_type]].variations.append(new_variation)
|
||||
variations.append(new_variation)
|
||||
|
||||
@@ -339,7 +292,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: DataStores
|
||||
Feature: Store Basket DataStore
|
||||
|
||||
Description:
|
||||
Datastore for Store Baskets
|
||||
"""
|
||||
|
||||
# internal
|
||||
# from routes import bp_home
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.sql_error import SQL_Error
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_app import Helper_App
|
||||
# from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
|
||||
from extensions import db
|
||||
# external
|
||||
# from abc import ABC, abstractmethod, abstractproperty
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text
|
||||
import stripe
|
||||
import os
|
||||
from flask import Flask, session, current_app
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import ClassVar
|
||||
from datetime import datetime
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_Store_Basket(DataStore_Store_Base):
|
||||
# Global constants
|
||||
KEY_BASKET: ClassVar[str] = Basket.KEY_BASKET
|
||||
# Attributes
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def get_metadata_basket(json_request):
|
||||
try:
|
||||
basket = json_request[DataStore_Store_Basket.KEY_BASKET]
|
||||
except KeyError:
|
||||
basket = {DataStore_Store_Basket.KEY_IS_INCLUDED_VAT: True, DataStore_Store_Basket.KEY_ID_CURRENCY: 1, DataStore_Store_Basket.KEY_ID_REGION_DELIVERY: 1}
|
||||
is_included_VAT = basket[DataStore_Store_Basket.KEY_IS_INCLUDED_VAT]
|
||||
id_currency = basket[DataStore_Store_Basket.KEY_ID_CURRENCY]
|
||||
id_region_delivery = basket[DataStore_Store_Basket.KEY_ID_REGION_DELIVERY]
|
||||
return id_currency, id_region_delivery, is_included_VAT
|
||||
|
||||
def edit_basket(self, ids_permutation_basket, quantities_permutation_basket, id_permutation_edit, quantity_permutation_edit, sum_not_edit, id_currency, id_region_delivery, is_included_VAT):
|
||||
# redundant argument validation?
|
||||
_m = 'DataStore_Store_Base.edit_basket'
|
||||
Helper_App.console_log(f'{_m}\nstarting...')
|
||||
# av.val_instance(filters, 'filters', _m, Parameters_Product_Category)
|
||||
# av.val_str(ids_product_basket, 'ids_product_basket', _m)
|
||||
av.val_str(ids_permutation_basket, 'ids_permutation_basket', _m)
|
||||
# av.val_str(quantities_product_basket, 'quantities_product_basket', _m)
|
||||
av.val_str(quantities_permutation_basket, 'quantities_permutation_basket', _m)
|
||||
"""
|
||||
if id_product_edit == 'None':
|
||||
id_product_edit = None
|
||||
else:
|
||||
Helper_App.console_log(f'id_product_edit: {id_product_edit}')
|
||||
av.val_int(id_product_edit, 'id_product_edit', _m)
|
||||
"""
|
||||
if id_permutation_edit == 'None' or str(type(id_permutation_edit)) =="<class 'NoneType'>":
|
||||
id_permutation_edit = None
|
||||
else:
|
||||
Helper_App.console_log(f'id_permutation_edit: {id_permutation_edit}')
|
||||
Helper_App.console_log(str(type(id_permutation_edit)))
|
||||
av.val_int(id_permutation_edit, 'id_permutation_edit', _m)
|
||||
if quantity_permutation_edit == 'None' or str(type(quantity_permutation_edit)) =="<class 'NoneType'>":
|
||||
quantity_permutation_edit = None
|
||||
else:
|
||||
Helper_App.console_log(f'quantity_permutation_edit: {quantity_permutation_edit}')
|
||||
av.val_int(quantity_permutation_edit, 'quantity_permutation_edit', _m)
|
||||
if sum_not_edit == 'None':
|
||||
sum_not_edit = None
|
||||
else:
|
||||
Helper_App.console_log(f'sum_not_edit: {sum_not_edit}')
|
||||
av.val_bool(sum_not_edit, 'sum_not_edit', _m)
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': self.info_user.get('sub'),
|
||||
# 'a_ids_product_basket': ids_product_basket,
|
||||
'a_ids_permutation_basket': ids_permutation_basket,
|
||||
# 'a_quantities_product_basket': quantities_product_basket,
|
||||
'a_quantities_permutation_basket': quantities_permutation_basket,
|
||||
# 'a_id_product_edit': id_product_edit if id_permutation_edit is None else None,
|
||||
'a_id_permutation_edit': id_permutation_edit,
|
||||
'a_quantity_permutation_edit': quantity_permutation_edit,
|
||||
'a_sum_not_edit': 1 if sum_not_edit else 0,
|
||||
'a_id_currency': id_currency,
|
||||
'a_id_region_purchase': id_region_delivery
|
||||
}
|
||||
|
||||
result = self.db_procedure_execute('p_shop_edit_user_basket', argument_dict_list)
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
cursor = result.cursor
|
||||
|
||||
# categories, category_index = DataStore_Store_Base.input_many_product(cursor)
|
||||
category_list, errors = DataStore_Store_Base.input_many_product(cursor)
|
||||
|
||||
Helper_App.console_log(f'cursor: {str(cursor)}')
|
||||
|
||||
# Basket
|
||||
if not cursor.nextset():
|
||||
raise Exception("No more query results! Cannot open basket contents")
|
||||
result_set = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw basket: {result_set}')
|
||||
# Helper_App.console_log(f'variations: {result_set_3}')
|
||||
# variations = [Product_Variation(**row) for row in result_set_3]
|
||||
basket = Basket(is_included_VAT, id_currency, id_region_delivery)
|
||||
for row in result_set:
|
||||
index_category = category_list.get_index_category_from_id(row[0])
|
||||
category = category_list.categories[index_category]
|
||||
index_product = category.get_index_product_from_id(row[1])
|
||||
product = category.products[index_product]
|
||||
basket_item = Basket_Item.from_product_and_quantity_and_VAT_included(product, row[7], self.app.is_included_VAT)
|
||||
Helper_App.console_log(f'adding basket item: {row}')
|
||||
Helper_App.console_log(f'basket item: {basket_item}')
|
||||
basket.add_item(basket_item) # basket.append(basket_item) # Basket_Item(category.name, product, row[4]))
|
||||
|
||||
Helper_App.console_log(f'basket: {basket}')
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_2]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
DataStore_Store_Base.db_cursor_clear(cursor)
|
||||
|
||||
return basket
|
||||
@@ -78,7 +78,7 @@ class DataStore_Store_Manufacturing_Purchase_Order(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -21,65 +21,7 @@ from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
from extensions import db
|
||||
# external
|
||||
# from abc import ABC, abstractmethod, abstractproperty
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text
|
||||
import stripe
|
||||
import os
|
||||
from flask import Flask, session, current_app
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import ClassVar
|
||||
from datetime import datetime
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
"""
|
||||
class Table_Shop_Product_Category(db.Model):
|
||||
__tablename__ = 'Shop_Product_Category'
|
||||
id_category: int = db.Column(db.Integer, primary_key=True)
|
||||
code: str = db.Column(db.String(50))
|
||||
name: str = db.Column(db.String(255))
|
||||
description: str = db.Column(db.String(4000))
|
||||
active: bool = db.Column(db.Boolean)
|
||||
display_order: int = db.Column(db.Integer)
|
||||
created_on: datetime = db.Column(db.DateTime)
|
||||
created_by: int = db.Column(db.Integer)
|
||||
id_change_set: int = db.Column(db.Integer)
|
||||
"""
|
||||
"""
|
||||
class Row_Shop_Product_Temp(db.Model):
|
||||
__tablename__ = 'Shop_Product_Temp'
|
||||
__table_args__ = { 'extend_existing': True }
|
||||
id_product: int = db.Column(db.Integer, primary_key=True)
|
||||
id_category: int = db.Column(db.Integer)
|
||||
name: str = db.Column(db.String(50))
|
||||
has_variations: str = db.Column(db.String(255))
|
||||
id_access_level_required: int = db.Column(db.Integer)
|
||||
active: bool = db.Column(db.Boolean)
|
||||
display_order: int = db.Column(db.Integer)
|
||||
guid: str = db.Column(db.BINARY(36))
|
||||
|
||||
@classmethod
|
||||
def from_product(cls, product):
|
||||
row = cls()
|
||||
row.id_product = product.id_product[0] if isinstance(product.id_product, tuple) else product.id_product
|
||||
row.id_category = product.id_category[0] if isinstance(product.id_category, tuple) else product.id_category
|
||||
row.name = product.name[0] if isinstance(product.name, tuple) else product.name
|
||||
row.id_access_level_required = product.id_access_level_required[0] if isinstance(product.id_access_level_required, tuple) else product.id_access_level_required
|
||||
row.active = product.active
|
||||
row.display_order = product.display_order
|
||||
return row
|
||||
def to_json(self):
|
||||
return {
|
||||
'id_product': self.id_product,
|
||||
'id_category': self.id_category,
|
||||
'name': self.name,
|
||||
'has_variations': self.has_variations,
|
||||
'id_access_level_required': self.id_access_level_required,
|
||||
'active': av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json'),
|
||||
'display_order': self.display_order,
|
||||
'guid': self.guid,
|
||||
}
|
||||
"""
|
||||
|
||||
class DataStore_Store_Product(DataStore_Store_Base):
|
||||
def __init__(self):
|
||||
@@ -115,16 +57,15 @@ class DataStore_Store_Product(DataStore_Store_Base):
|
||||
}
|
||||
save_result = cls.db_procedure_execute('p_shop_save_product', argument_dict_list)
|
||||
|
||||
cursor = save_result # .cursor
|
||||
cursor = save_result
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
# Errors
|
||||
# cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
try:
|
||||
|
||||
@@ -40,8 +40,6 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
_m = 'DataStore_Store_Product_Category.save_categories'
|
||||
Helper_App.console_log(f'{_m}\nstarting...')
|
||||
Helper_App.console_log(f'comment: {comment}\ncategories: {categories}')
|
||||
# av.val_str(comment, 'comment', _m)
|
||||
# av.val_list_instances(categories, 'categories', _m, Product_Category, 1)
|
||||
|
||||
guid = Helper_DB_MySQL.create_guid()
|
||||
now = datetime.now()
|
||||
@@ -50,32 +48,15 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
id_category_new = 0
|
||||
for category in categories:
|
||||
row = Product_Category_Temp.from_product_category(category)
|
||||
# row = category.to_temporary_record()
|
||||
# id_tmp =
|
||||
if row.id_category == '':
|
||||
id_category_new -= 1
|
||||
row.id_category = id_category_new
|
||||
else:
|
||||
Helper_App.console_log(f'row.id_category: {row.id_category}')
|
||||
row.guid = guid
|
||||
# row.created_on = now
|
||||
# row.created_by = user.id_user
|
||||
rows.append(row)
|
||||
|
||||
Helper_App.console_log(f'rows: {rows}')
|
||||
"""
|
||||
cursor = db.cursor()
|
||||
Helper_App.console_log('cursor created')
|
||||
cursor.executemany(
|
||||
'INSERT INTO Shop_Product_Category_Temp (id_category, code, name, description, active, display_order, guid, created_on, created_by) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
|
||||
categories
|
||||
)
|
||||
Helper_App.console_log('bulk upload executed')
|
||||
db.commit()
|
||||
Helper_App.console_log('bulk upload committed')
|
||||
cursor.close()
|
||||
Helper_App.console_log('cursor closed')
|
||||
"""
|
||||
DataStore_Store_Base.upload_bulk(Product_Category_Temp.__tablename__, rows, 1000)
|
||||
|
||||
argument_dict_list = {
|
||||
@@ -92,7 +73,7 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -42,58 +42,17 @@ class DataStore_Store_Product_Permutation(DataStore_Store_Base):
|
||||
def save_permutations(cls, comment, permutations):
|
||||
_m = 'DataStore_Store_Product_Permutation.save_permutations'
|
||||
av.val_str(comment, 'comment', _m)
|
||||
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
|
||||
|
||||
guid = Helper_DB_MySQL.create_guid_str()
|
||||
now = datetime.now()
|
||||
user = cls.get_user_session()
|
||||
rows = []
|
||||
for permutation in permutations:
|
||||
# row = permutation.to_temporary_record()
|
||||
row = Product_Permutation_Temp.from_product_permutation(permutation)
|
||||
row.guid = guid
|
||||
rows.append(row)
|
||||
|
||||
Helper_App.console_log(f'rows: {rows}')
|
||||
|
||||
"""
|
||||
cursor = db.cursor()
|
||||
Helper_App.console_log('cursor created')
|
||||
cursor.executemany(
|
||||
'''INSERT INTO Shop_Product_Permutation_Temp (
|
||||
id_permutation,
|
||||
id_product,
|
||||
description,
|
||||
cost_local,
|
||||
id_currency_cost,
|
||||
profit_local_min,
|
||||
latency_manufacture,
|
||||
id_unit_measurement_quantity,
|
||||
count_unit_measurement_quantity,
|
||||
quantity_min,
|
||||
quantity_max,
|
||||
quantity_stock,
|
||||
is_subscription,
|
||||
id_unit_measurement_interval_recurrence,
|
||||
count_interval_recurrence,
|
||||
id_stripe_product,
|
||||
does_expire_faster_once_unsealed,
|
||||
id_unit_measurement_interval_expiration_unsealed,
|
||||
count_interval_expiration_unsealed,
|
||||
active,
|
||||
guid
|
||||
)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)''',
|
||||
rows
|
||||
)
|
||||
Helper_App.console_log('cursor executed')
|
||||
db.commit()
|
||||
Helper_App.console_log('cursor committed')
|
||||
cursor.close()
|
||||
Helper_App.console_log('cursor closed')
|
||||
"""
|
||||
|
||||
DataStore_Store_Base.upload_bulk(Product_Permutation_Temp.__tablename__, rows, 1000)
|
||||
Helper_App.console_log('bulk uploaded')
|
||||
|
||||
argument_dict_list = {
|
||||
'a_comment': comment,
|
||||
@@ -103,4 +62,3 @@ class DataStore_Store_Product_Permutation(DataStore_Store_Base):
|
||||
}
|
||||
results = cls.db_procedure_execute('p_shop_save_product_permutation', argument_dict_list)
|
||||
DataStore_Store_Base.db_cursor_clear(results.cursor)
|
||||
Helper_App.console_log('saved product permutations')
|
||||
|
||||
@@ -31,19 +31,12 @@ from pydantic import BaseModel, ConfigDict
|
||||
from typing import ClassVar
|
||||
from datetime import datetime
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
# Global constants
|
||||
# Attributes
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Stock Items
|
||||
def get_many_stock_item(self, parameters_stock_item, category_list):
|
||||
# redundant argument validation?
|
||||
_m = 'DataStore_Store_Stock_Item.get_many_stock_item'
|
||||
av.val_instance(parameters_stock_item, 'parameters_stock_item', _m, Parameters_Stock_Item)
|
||||
argument_dict = parameters_stock_item.to_json()
|
||||
@@ -73,7 +66,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw categories: {result_set_1}')
|
||||
for row in result_set_1:
|
||||
new_stock_item = Stock_Item.from_DB_stock_item(row)
|
||||
category_list.add_stock_item(new_stock_item) # , row)
|
||||
category_list.add_stock_item(new_stock_item)
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
@@ -81,27 +74,11 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
"""
|
||||
if len(errors) > 0:
|
||||
for error in errors:
|
||||
if error.code == 'PRODUCT_AVAILABILITY':
|
||||
ids_permutation_unavailable = DataStore_Store_Stock_Item.get_ids_permutation_from_error_availability(error.msg)
|
||||
for id_permutation in ids_permutation_unavailable:
|
||||
index_category = category_list.get_index_category_from_id_permutation(id_permutation)
|
||||
category = category_list.categories[index_category]
|
||||
index_product = category.get_index_product_from_id_permutation(id_permutation)
|
||||
product = category.products[index_product]
|
||||
index_permutation = product.get_index_permutation_from_id(id_permutation)
|
||||
permutation = product.permutations[index_permutation]
|
||||
permutation.is_available = False
|
||||
if 'region' in error.msg or 'currency' in error.msg:
|
||||
permutation.is_unavailable_in_currency_or_region = True
|
||||
"""
|
||||
DataStore_Store_Stock_Item.db_cursor_clear(cursor)
|
||||
return category_list, errors # categories, category_index
|
||||
return category_list, errors
|
||||
|
||||
@classmethod
|
||||
def save_stock_items(cls, comment, stock_items):
|
||||
@@ -113,7 +90,6 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
user = cls.get_user_session()
|
||||
rows = []
|
||||
for stock_item in stock_items:
|
||||
# row = permutation.to_temporary_record()
|
||||
row = Stock_Item_Temp.from_stock_item(stock_item)
|
||||
row.guid = guid
|
||||
rows.append(row)
|
||||
@@ -139,7 +115,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
DataStore_Store_Stock_Item.db_cursor_clear(cursor)
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: DataStores
|
||||
Feature: Store Stripe DataStore
|
||||
|
||||
Description:
|
||||
Datastore for Store Stripe service
|
||||
"""
|
||||
|
||||
# internal
|
||||
# from routes import bp_home
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product import Product, Product_Permutation, Product_Price, Parameters_Product
|
||||
from business_objects.sql_error import SQL_Error
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
# from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
|
||||
from extensions import db
|
||||
from helpers.helper_app import Helper_App
|
||||
# external
|
||||
# from abc import ABC, abstractmethod, abstractproperty
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from sqlalchemy import text
|
||||
import stripe
|
||||
import os
|
||||
from flask import Flask, session, current_app
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from typing import ClassVar
|
||||
from datetime import datetime
|
||||
|
||||
# db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_Store_Stripe(DataStore_Store_Base):
|
||||
# Global constants
|
||||
# Attributes
|
||||
key_public_stripe: str = None
|
||||
key_secret_stripe: str = None
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.key_secret_stripe = os.environ.get("KEY_SECRET_STRIPE")
|
||||
self.key_public_stripe = os.environ.get("KEY_PUBLIC_STRIPE")
|
||||
|
||||
# For sample support and debugging, not required for production:
|
||||
stripe.set_app_info(
|
||||
'stripe-samples/checkout-one-time-payments',
|
||||
version='0.0.1',
|
||||
url='https://github.com/stripe-samples/checkout-one-time-payments')
|
||||
stripe.api_key = self.key_secret_stripe
|
||||
|
||||
def get_many_stripe_product_new(self):
|
||||
_m = 'DataStore_Store_Stripe.get_many_stripe_product_new'
|
||||
_m_db = 'p_shop_get_many_stripe_product_new'
|
||||
# av.val_str(id_user)
|
||||
# validation conducted by server
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': self.info_user
|
||||
}
|
||||
|
||||
Helper_App.console_log(f'executing {_m_db}')
|
||||
result = self.db_procedure_execute(_m_db, argument_dict_list)
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
|
||||
# Products
|
||||
cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
products = []
|
||||
for row in result_set_1:
|
||||
new_product = Product.from_DB_Stripe_product(row) # Product(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19])
|
||||
products.append(new_product)
|
||||
Helper_App.console_log(f'products: {products}')
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
DataStore_Store_Stripe.db_cursor_clear(cursor)
|
||||
|
||||
return products
|
||||
|
||||
def get_many_stripe_price_new(self):
|
||||
_m = 'DataStore_Store_Stripe.get_many_stripe_price_new'
|
||||
_m_db = 'p_shop_get_many_stripe_price_new'
|
||||
# av.val_str(id_user)
|
||||
# validation conducted by server
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': self.info_user
|
||||
}
|
||||
|
||||
Helper_App.console_log(f'executing {_m_db}')
|
||||
result = self.db_procedure_execute(_m_db, argument_dict_list)
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
|
||||
# Products
|
||||
cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
products = []
|
||||
for row in result_set_1:
|
||||
new_product = Product.from_DB_Stripe_price(row) # Product(row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19])
|
||||
products.append(new_product)
|
||||
Helper_App.console_log(f'products: {products}')
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
DataStore_Store_Stripe.db_cursor_clear(cursor)
|
||||
|
||||
return products
|
||||
|
||||
def get_many_product_new(self):
|
||||
_m = 'DataStore_Store_Stripe.get_many_product_new'
|
||||
# Stripe
|
||||
new_products = self.get_many_stripe_product_new()
|
||||
for product in new_products:
|
||||
product.id_stripe_product = self.create_stripe_product(product)
|
||||
return new_products
|
||||
|
||||
def get_many_price_new(self):
|
||||
_m = 'DataStore_Store_Stripe.get_many_product_new'
|
||||
# Stripe
|
||||
new_products = self.get_many_stripe_price_new()
|
||||
for product in new_products:
|
||||
product.id_stripe_price = self.create_stripe_price(product)
|
||||
return new_products
|
||||
|
||||
# Stripe
|
||||
def create_stripe_product(self, product): # _name, product_description):
|
||||
_m = 'DataStore_Store_Stripe_Checkout.create_stripe_product'
|
||||
# av.val_str(product_name, 'product_name', _m)
|
||||
# av.val_str(product_description, 'product_description', _m)
|
||||
av.val_instance(product, 'product', _m, Product)
|
||||
|
||||
Helper_App.console_log(f'stripe.api_key = {stripe.api_key}')
|
||||
new_product = stripe.Product.create(
|
||||
name = product.name,
|
||||
description = product.description,
|
||||
)
|
||||
|
||||
# Save these identifiers
|
||||
Helper_App.console_log(f"Success! Here is your new Stripe product id: {new_product.id}")
|
||||
|
||||
return new_product.id
|
||||
|
||||
def create_stripe_price(self, product, currency): # product_id, product_price, product_currency, product_is_subscription, product_recurring_interval = '', product_interval_count = 0):
|
||||
_m = 'DataStore_Store_Stripe_Checkout.create_stripe_price'
|
||||
"""
|
||||
av.val_str(p_id, 'p_id', _m)
|
||||
av.full_val_float(p_price, 'p_price', _m, 0.01)
|
||||
p_price = round(p_price, 2)
|
||||
av.val_str(p_currency, 'p_currency', _m)
|
||||
av.full_val_bool(p_is_subscription, 'p_is_subscription', _m)
|
||||
p_is_subscription = bool(p_is_subscription)
|
||||
av.val_str(p_recurring_interval, 'p_recurring_interval', _m)
|
||||
av.full_val_int(p_interval_count, 'p_interval_count', _m, 1 if p_is_subscription else 0)
|
||||
p_interval_count = int(p_interval_count)
|
||||
"""
|
||||
av.val_instance(product, 'product', _m, Product)
|
||||
av.val_str(currency, 'currency', _m)
|
||||
|
||||
Helper_App.console_log(f'stripe.api_key = {stripe.api_key}')
|
||||
|
||||
new_product_price = stripe.Price.create(
|
||||
unit_amount = product.unit_price,
|
||||
currency = currency,
|
||||
recurring = { "interval": product.name_recurring_interval, "interval_count": product.count_recurring_interval } if product.is_subscription else None,
|
||||
product = product.id_stripe_product
|
||||
)
|
||||
|
||||
# Save these identifiers
|
||||
Helper_App.console_log(f"Success! Here is your Stripe product price id: {new_product_price.id} for {product.name}")
|
||||
|
||||
return new_product_price.id
|
||||
|
||||
@@ -79,7 +79,7 @@ class DataStore_Store_Supplier(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -135,7 +135,7 @@ class DataStore_Store_Supplier(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class DataStore_Store_Supplier_Purchase_Order(DataStore_Store_Base):
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
errors = []
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1])
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -37,16 +37,11 @@ db = SQLAlchemy()
|
||||
|
||||
|
||||
class DataStore_User(DataStore_Store_Base):
|
||||
# Global constants
|
||||
# Attributes
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def edit_user(self):
|
||||
# redundant argument validation?
|
||||
_m = 'DataStore_User.edit_user'
|
||||
# av.val_instance(filters, 'filters', _m, Filters_Product_Category)
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': self.info_user.get('sub'),
|
||||
@@ -66,7 +61,7 @@ class DataStore_User(DataStore_Store_Base):
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_2]
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -74,94 +69,28 @@ class DataStore_User(DataStore_Store_Base):
|
||||
|
||||
return (result_set_1[0][1] == b'\x01')
|
||||
|
||||
"""
|
||||
def get_many_user_order(self, id_user, ids_order, n_order_max, id_checkout_session):
|
||||
_m = 'DataStore_User.get_many_user_order'
|
||||
# av.val_str(id_user)
|
||||
# validation conducted by server
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': id_user,
|
||||
'a_ids_order': ids_order,
|
||||
'a_n_order_max': n_order_max,
|
||||
'a_id_checkout_session': id_checkout_session
|
||||
}
|
||||
|
||||
Helper_App.console_log('executing p_shop_get_many_user_order')
|
||||
result = self.db_procedure_execute('p_shop_get_many_user_order', argument_dict_list)
|
||||
cursor = result.cursor
|
||||
Helper_App.console_log('data received')
|
||||
|
||||
|
||||
# Discount Delivery Regions
|
||||
cursor.nextset()
|
||||
result_set_1 = cursor.fetchall()
|
||||
orders = []
|
||||
for row in result_set_1:
|
||||
new_order = Order(row[0], row[1], row[2], row[3], row[4], row[5], row[6])
|
||||
orders.append(new_order)
|
||||
Helper_App.console_log(f'orders: {orders}')
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
DataStore_User.db_cursor_clear(cursor)
|
||||
|
||||
return orders
|
||||
"""
|
||||
|
||||
def get_many_user(self, user_filters, user=None):
|
||||
_m = 'DataStore_User.get_many_user'
|
||||
Helper_App.console_log(_m)
|
||||
# av.val_str(user_filters, 'user_filters', _m)
|
||||
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
|
||||
av.val_instance(user_filters, 'user_filters', _m, Parameters_User)
|
||||
|
||||
guid = Helper_DB_MySQL.create_guid()
|
||||
# now = datetime.now()
|
||||
# user = self.get_user_session()
|
||||
|
||||
"""
|
||||
argument_dict_list = {
|
||||
'a_id_user': id_user,
|
||||
'a_comment': comment,
|
||||
'a_guid': guid
|
||||
}
|
||||
"""
|
||||
|
||||
if user is None:
|
||||
user = self.get_user_session()
|
||||
argument_dict_list = {
|
||||
# 'a_guid': guid
|
||||
'a_id_user': user.id_user
|
||||
, 'a_id_user_auth0': user.id_user_auth0
|
||||
, **user_filters.to_json()
|
||||
, 'a_debug': 0
|
||||
|
||||
}
|
||||
# argument_dict_list['a_guid'] = guid
|
||||
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
|
||||
"""
|
||||
query = text(f"SELECT * FROM Shop_Calc_User_Temp UE_T WHERE UE_T.guid = '{guid}'")
|
||||
result = self.db.session.execute(query)
|
||||
"""
|
||||
cursor = result.cursor
|
||||
result_set = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw users: {result_set}')
|
||||
Helper_App.console_log(f'type result set: {str(type(result_set))}')
|
||||
Helper_App.console_log(f'len result set: {len(result_set)}')
|
||||
"""
|
||||
user_permission_evals = []
|
||||
for row in result_set:
|
||||
user_permission_eval = User_Permission_Evaluation.from_DB_user_eval(row)
|
||||
user_permission_evals.append(user_permission_eval)
|
||||
Helper_App.console_log(f'user_permission_evals: {user_permission_evals}')
|
||||
"""
|
||||
users = []
|
||||
if len(result_set) > 0:
|
||||
for row in result_set:
|
||||
@@ -170,13 +99,12 @@ class DataStore_User(DataStore_Store_Base):
|
||||
users.append(user)
|
||||
Helper_App.console_log(f'user {str(type(user))}: {user}')
|
||||
Helper_App.console_log(f'type users: {str(type(users))}\n type user 0: {str(type(None if len(users) == 0 else users[0]))}')
|
||||
# error_list, cursor = self.get_error_list_from_cursor(cursor)
|
||||
errors = []
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
@@ -187,49 +115,25 @@ class DataStore_User(DataStore_Store_Base):
|
||||
def get_many_user(self, user_filters, user=None):
|
||||
_m = 'DataStore_User.get_many_user'
|
||||
Helper_App.console_log(_m)
|
||||
# av.val_str(user_filters, 'user_filters', _m)
|
||||
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
|
||||
av.val_instance(user_filters, 'user_filters', _m, Parameters_User)
|
||||
|
||||
guid = Helper_DB_MySQL.create_guid()
|
||||
# now = datetime.now()
|
||||
# user = self.get_user_session()
|
||||
|
||||
"""
|
||||
argument_dict_list = {
|
||||
'a_id_user': id_user,
|
||||
'a_comment': comment,
|
||||
'a_guid': guid
|
||||
}
|
||||
"""
|
||||
if user is None:
|
||||
user = self.get_user_session()
|
||||
argument_dict_list = {
|
||||
# 'a_guid': guid
|
||||
'a_id_user': user.id_user
|
||||
, 'a_id_user_auth0': user.id_user_auth0
|
||||
, **user_filters.to_json()
|
||||
, 'a_debug': 0
|
||||
|
||||
}
|
||||
# argument_dict_list['a_guid'] = guid
|
||||
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
|
||||
"""
|
||||
query = text(f"SELECT * FROM Shop_Calc_User_Temp UE_T WHERE UE_T.guid = '{guid}'")
|
||||
result = self.db.session.execute(query)
|
||||
"""
|
||||
cursor = result.cursor
|
||||
result_set = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw users: {result_set}')
|
||||
Helper_App.console_log(f'type result set: {str(type(result_set))}')
|
||||
Helper_App.console_log(f'len result set: {len(result_set)}')
|
||||
"""
|
||||
user_permission_evals = []
|
||||
for row in result_set:
|
||||
user_permission_eval = User_Permission_Evaluation.from_DB_user_eval(row)
|
||||
user_permission_evals.append(user_permission_eval)
|
||||
Helper_App.console_log(f'user_permission_evals: {user_permission_evals}')
|
||||
"""
|
||||
users = []
|
||||
if len(result_set) > 0:
|
||||
for row in result_set:
|
||||
@@ -238,13 +142,12 @@ class DataStore_User(DataStore_Store_Base):
|
||||
users.append(user)
|
||||
Helper_App.console_log(f'user {str(type(user))}: {user}')
|
||||
Helper_App.console_log(f'type users: {str(type(users))}\n type user 0: {str(type(None if len(users) == 0 else users[0]))}')
|
||||
# error_list, cursor = self.get_error_list_from_cursor(cursor)
|
||||
errors = []
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
Helper_App.console_log(f'raw errors: {result_set_e}')
|
||||
if len(result_set_e) > 0:
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
|
||||
errors = [SQL_Error.from_DB_record(row) for row in result_set_e]
|
||||
for error in errors:
|
||||
Helper_App.console_log(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
|
||||
@@ -21,15 +21,7 @@ class Form_Base_Meta(type(FlaskForm), ABCMeta):
|
||||
|
||||
|
||||
class Form_Base(FlaskForm, metaclass=Form_Base_Meta):
|
||||
"""
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def from_filters(cls, filters):
|
||||
pass
|
||||
@abstractmethod
|
||||
def __repr__(self):
|
||||
pass
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
fields = ', '.join(
|
||||
f"{name}={field.data}" for name, field in self._fields.items()
|
||||
@@ -42,37 +34,9 @@ class Form_Base(FlaskForm, metaclass=Form_Base_Meta):
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
return cls()
|
||||
"""
|
||||
@abstractmethod
|
||||
def test_69(self):
|
||||
pass
|
||||
|
||||
def get_Filters_Product_Category(data_request):
|
||||
data_form = data_request[Model_View_Store_Product_Category.FLAG_FORM]
|
||||
form_filters = Filters_Product_Category(**data_form)
|
||||
form_filters.is_not_empty.data = av.input_bool(data_form['is_not_empty'], 'is_not_empty', 'filter_category')
|
||||
form_filters.active.data = av.input_bool(data_form['active'], 'active', 'filter_category')
|
||||
return form_filters
|
||||
"""
|
||||
@classmethod
|
||||
def get_choices_blank(cls):
|
||||
return [('', 'Select')]
|
||||
@classmethod
|
||||
def get_choice_all(cls):
|
||||
return ('', 'All')
|
||||
|
||||
'''
|
||||
class Filters_Stored_Procedure_Base(Form_Base):
|
||||
"""
|
||||
@abstractmethod
|
||||
def __repr__(self):
|
||||
pass
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def from_json(cls, json):
|
||||
pass
|
||||
"""
|
||||
@abstractmethod
|
||||
def to_json(self):
|
||||
pass
|
||||
'''
|
||||
@@ -40,43 +40,24 @@ class Form_Register(FlaskForm):
|
||||
submit = SubmitField('Submit')
|
||||
|
||||
|
||||
"""
|
||||
class Form_Product(FlaskForm): # for basket, product tiles, product add
|
||||
# PositiveIntegerField with validation constraints
|
||||
class Form_Basket_Add(FlaskForm):
|
||||
quantity = IntegerField(
|
||||
'Quantity',
|
||||
validators=[
|
||||
# InputRequired(message='Quantity'),
|
||||
validators = [
|
||||
NumberRange(min=1, message='Please enter a positive integer')
|
||||
],
|
||||
default=1
|
||||
)
|
||||
"""
|
||||
|
||||
class Form_Basket_Add(FlaskForm): # for basket, product tiles, product add
|
||||
# PositiveIntegerField with validation constraints
|
||||
quantity = IntegerField(
|
||||
'Quantity',
|
||||
validators=[
|
||||
# InputRequired(message='Quantity'),
|
||||
NumberRange(min=1, message='Please enter a positive integer')
|
||||
],
|
||||
default=1
|
||||
# render_kw={'id-product': ''} # {Model_View_Store.attr_id_product: ''}
|
||||
default = 1
|
||||
)
|
||||
submit = SubmitField('Add')
|
||||
form_type = 'Form_Basket_Add'
|
||||
|
||||
class Form_Basket_Edit(FlaskForm): # for basket, product tiles, product add
|
||||
# PositiveIntegerField with validation constraints
|
||||
class Form_Basket_Edit(FlaskForm):
|
||||
quantity = IntegerField(
|
||||
'Quantity',
|
||||
validators=[
|
||||
# InputRequired(message='Quantity'),
|
||||
validators = [
|
||||
NumberRange(min=1, message='Please enter a positive integer')
|
||||
],
|
||||
default=1
|
||||
# render_kw={'id-product': ''} # {Model_View_Store.attr_id_product: ''}
|
||||
default = 1
|
||||
)
|
||||
submit = SubmitField('Update')
|
||||
form_type = 'Form_Basket_Edit'
|
||||
@@ -109,7 +90,6 @@ class Form_Currency(FlaskForm):
|
||||
id_currency = SelectField('Currency', id='id_currency')
|
||||
|
||||
|
||||
# Store
|
||||
class Form_Supplier(FlaskForm):
|
||||
id_id_supplier = 'id_supplier'
|
||||
id_supplier = SelectField('Supplier', id='id_supplier')
|
||||
@@ -124,11 +104,8 @@ class Form_Supplier(FlaskForm):
|
||||
id_currency = SelectField('Currency ID')
|
||||
is_active = BooleanField('Active', default = True)
|
||||
|
||||
# class Form_Supplier_Purchase_Order(FlaskForm):
|
||||
|
||||
|
||||
|
||||
# User
|
||||
class Form_Filters_User(FlaskForm):
|
||||
active = BooleanField('Active only?', default = True)
|
||||
id_user = SelectField('User ID', validators=[Optional()], choices=[])
|
||||
@@ -28,14 +28,7 @@ from abc import ABCMeta, abstractmethod
|
||||
class Filters_Product_Category(Form_Base):
|
||||
is_not_empty = BooleanField('Not empty only?')
|
||||
active = BooleanField("Active only?", default = True)
|
||||
"""
|
||||
@classmethod
|
||||
def from_filters(cls, filters):
|
||||
form = Filters_Product_Category()
|
||||
form.is_not_empty.data = filters.is_not_empty
|
||||
form.active.data = filters.active
|
||||
return form
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return f'Filters_Product_Category(is_not_empty={self.is_not_empty.data}, active={self.active.data})'
|
||||
@classmethod
|
||||
|
||||
@@ -32,18 +32,7 @@ class Filters_Product_Permutation(Form_Base):
|
||||
active = BooleanField('Active only?', default=True)
|
||||
quantity_min = FloatField('Min stock')
|
||||
quantity_max = FloatField('Max stock')
|
||||
# submit = SubmitField('Submit')
|
||||
"""
|
||||
@classmethod
|
||||
def from_filters(cls, filters):
|
||||
form = Filters_Product_Permutation()
|
||||
form.id_category.choices = Store_Base.convert_list_objects_to_list_options(filters.categories)
|
||||
form.id_product.choices = Store_Base.convert_list_objects_to_list_options(filters.products)
|
||||
form.is_out_of_stock.data = filters.is_out_of_stock
|
||||
form.quantity_min.data = filters.quantity_min
|
||||
form.quantity_max.data = filters.quantity_max
|
||||
return form
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
Filters_Product_Permutation(
|
||||
|
||||
@@ -31,24 +31,11 @@ class Filters_Stock_Item(Form_Base):
|
||||
quantity_min = FloatField('Min stock')
|
||||
quantity_max = FloatField('Max stock')
|
||||
active = BooleanField("Active")
|
||||
# submit = SubmitField('Submit')
|
||||
"""
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
{self.__class__.__name__}(
|
||||
id_category={self.id_category.data},
|
||||
id_product={self.id_product.data},
|
||||
is_out_of_stock={self.is_out_of_stock.data},
|
||||
quantity_min={self.quantity_min.data},
|
||||
quantity_max={self.quantity_max.data})
|
||||
'''
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
form = cls()
|
||||
# form.id_category.choices = [(json[Store_Base.ATTR_ID_PRODUCT_CATEGORY], json[Store_Base.ATTR_ID_PRODUCT_CATEGORY])]
|
||||
form.id_category.data = json[Store_Base.ATTR_ID_PRODUCT_CATEGORY]
|
||||
# form.id_product.choices = [(json[Store_Base.ATTR_ID_PRODUCT], json[Store_Base.ATTR_ID_PRODUCT])]
|
||||
form.id_product.data = json[Store_Base.ATTR_ID_PRODUCT]
|
||||
form.is_out_of_stock.data = av.input_bool(json[Store_Base.FLAG_IS_OUT_OF_STOCK], Store_Base.FLAG_IS_OUT_OF_STOCK, f'{cls.__name__}.from_json')
|
||||
form.quantity_min.data = json[Store_Base.FLAG_QUANTITY_MIN]
|
||||
@@ -69,11 +56,4 @@ class Filters_Stock_Item(Form_Base):
|
||||
filters = cls()
|
||||
filters.id_category.choices = cls.get_choices_blank()
|
||||
filters.id_product.choices = cls.get_choices_blank()
|
||||
"""
|
||||
def import_values(self, form_filters):
|
||||
self.id_category.data = form_filters.id_category.data
|
||||
self.id_product.data = form_filters.id_product.data
|
||||
self.is_out_of_stock.data = form_filters.is_out_of_stock.data
|
||||
self.quantity_min.data = form_filters.quantity_min.data
|
||||
self.quantity_max.data = form_filters.quantity_max.data
|
||||
"""
|
||||
|
||||
Binary file not shown.
@@ -1,38 +0,0 @@
|
||||
from abc import abstractmethod
|
||||
from functools import wraps
|
||||
import inspect
|
||||
|
||||
def Interface_ABC(cls):
|
||||
abstract_methods = {}
|
||||
for name, value in vars(cls).items():
|
||||
if getattr(value, '__isabstractmethod__', False):
|
||||
if isinstance(value, classmethod):
|
||||
abstract_methods[name] = 'classmethod'
|
||||
elif isinstance(value, staticmethod):
|
||||
abstract_methods[name] = 'staticmethod'
|
||||
else:
|
||||
abstract_methods[name] = 'method'
|
||||
|
||||
def decorator(subclass):
|
||||
for method, method_type in abstract_methods.items():
|
||||
if not hasattr(subclass, method):
|
||||
raise NotImplementedError(
|
||||
f"'{subclass.__name__}' must implement abstract {method_type} '{method}' from interface '{cls.__name__}'"
|
||||
)
|
||||
|
||||
subclass_value = getattr(subclass, method)
|
||||
|
||||
if method_type == 'classmethod' and not isinstance(subclass_value, classmethod):
|
||||
raise TypeError(f"'{method}' must be a classmethod in '{subclass.__name__}'")
|
||||
elif method_type == 'staticmethod' and not isinstance(subclass_value, staticmethod):
|
||||
raise TypeError(f"'{method}' must be a staticmethod in '{subclass.__name__}'")
|
||||
elif method_type == 'method' and (isinstance(subclass_value, (classmethod, staticmethod)) or inspect.isfunction(subclass_value)):
|
||||
# For normal methods, we accept either functions or methods, as unbound methods are functions in Python 3
|
||||
pass
|
||||
else:
|
||||
raise TypeError(f"'{method}' has incorrect type in '{subclass.__name__}'")
|
||||
|
||||
return subclass
|
||||
|
||||
return decorator
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Helpers
|
||||
Feature: PostgreSQL Database Helper
|
||||
"""
|
||||
|
||||
# internal
|
||||
|
||||
# external
|
||||
import psycopg2
|
||||
# from psycopg2 import sql
|
||||
from pydantic import BaseModel
|
||||
from flask import Flask
|
||||
|
||||
class Helper_DB_PostgreSQL(BaseModel):
|
||||
|
||||
|
||||
app: Flask
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app=app)
|
||||
# self.app = app
|
||||
|
||||
def get_db_connection(self):
|
||||
return psycopg2.connect(
|
||||
dbname = self.app.config['DB_NAME'],
|
||||
user = self.app.config['DB_USER'],
|
||||
password = self.app.config['DB_PASSWORD'],
|
||||
host = self.app.config['DB_HOST'],
|
||||
port = self.app.config['DB_PORT']
|
||||
)
|
||||
@@ -12,7 +12,6 @@ Feature: App Helper
|
||||
# external
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from flask import current_app
|
||||
# from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
|
||||
class Helper_App(BaseModel):
|
||||
|
||||
@@ -13,7 +13,7 @@ Notes: This architecture does not work with Flask-SQLAlchemy - db connection mus
|
||||
|
||||
# external
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
import uuid
|
||||
|
||||
@@ -24,7 +24,6 @@ class Helper_DB_MySQL(BaseModel):
|
||||
|
||||
def __init__(self, app):
|
||||
super().__init__(app=app)
|
||||
# self.app = app
|
||||
|
||||
def get_db_connection(self):
|
||||
db = SQLAlchemy()
|
||||
|
||||
@@ -11,17 +11,7 @@ from helpers.helper_app import Helper_App
|
||||
from typing import Optional
|
||||
|
||||
def error_msg_str(v, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# return error message string for output of invalid argument / attribute to user
|
||||
# ARGUMENTS
|
||||
# str method - name of parent method which calls this function
|
||||
# str arg_name - name of argument throwing error
|
||||
# ? v - erroneous variable
|
||||
# str v_type - desired / expected variable type
|
||||
# str arg_type - e.g. argument, attribute
|
||||
# bool suppress_errors - should outputs not be raised as errors?
|
||||
# bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'error_msg_str'
|
||||
# suppress_errors
|
||||
if not val_bool(suppress_errors, 'suppress_errors', my_f):
|
||||
@@ -74,21 +64,10 @@ def error_msg_str(v, v_name, method, v_type, suppress_errors = False, suppress_c
|
||||
return error_msg
|
||||
else:
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return f"Invalid {method} {v_type} {v_arg_type} {v_name}. Type = {str(type(v))}. Value = {v}"
|
||||
|
||||
def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that myinput is of type bool
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) myinput
|
||||
# str v_name
|
||||
# str method
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
# validate bool inputs first
|
||||
v_type = "<class 'bool'>"
|
||||
my_f = 'val_bool'
|
||||
if str(type(suppress_errors)) != v_type:
|
||||
@@ -100,7 +79,6 @@ def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
v_type = "<class 'str'>"
|
||||
# method
|
||||
valid = True
|
||||
if str(type(method)) != v_type:
|
||||
valid = False
|
||||
@@ -153,23 +131,11 @@ def val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type str
|
||||
# ARGUMENTS
|
||||
# str (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional int min_len
|
||||
# optional int max_len
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_str'
|
||||
v_type = "<class 'str'>"
|
||||
# suppress_errors
|
||||
@@ -178,7 +144,6 @@ def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
print(error_msg_str(suppress_console_outputs, 'suppress_console_outputs', my_f, "<class 'bool'>", suppress_errors))
|
||||
return False
|
||||
# method
|
||||
valid = True
|
||||
if str(type(method)) != v_type:
|
||||
valid = False
|
||||
@@ -246,10 +211,8 @@ def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
v_type = "<class 'str'>"
|
||||
valid = True
|
||||
# METHODS
|
||||
if str(type(v_input)) != v_type:
|
||||
valid = False
|
||||
else:
|
||||
@@ -267,31 +230,11 @@ def val_str(v_input, v_name, method, min_len = -1, max_len = -1, suppress_errors
|
||||
print(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
# def val_none(v_input, v_name, method, v_arg_type = 'argument', suppress_errors = False, suppress_console_outputs = False):
|
||||
# # FUNCTION
|
||||
# # evaluate if v_input is None
|
||||
# # ARGUMENTS
|
||||
# # ARGUMENT VALIDATION
|
||||
# # VARIABLE INSTANTIATION
|
||||
# # METHODS
|
||||
# # RETURNS
|
||||
|
||||
def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optional[int] = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that myinput is of type int, and if not None, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# int (hopefully) myinput
|
||||
# str v_name
|
||||
# str method
|
||||
# optional int v_min
|
||||
# optional int v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_int'
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
@@ -315,10 +258,8 @@ def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optiona
|
||||
if not val_int(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
mytype = "<class 'int'>" # str(type(myinput))
|
||||
mytype = "<class 'int'>"
|
||||
error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# METHODS
|
||||
if not mytype == str(type(v_input)):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
@@ -346,23 +287,11 @@ def val_int(v_input, v_name, method, v_min: Optional[int] = None, v_max: Optiona
|
||||
print(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type float, and if not None, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# float (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_float'
|
||||
# suppress_errors
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
@@ -386,10 +315,8 @@ def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_erro
|
||||
if not val_float(v_max, 'v_max', my_f, None, None, suppress_errors, suppress_console_outputs):
|
||||
return False
|
||||
# v_input
|
||||
# VARIABLE INSTANTIATION
|
||||
mytype = "<class 'float'>" # str(type(myinput))
|
||||
mytype = "<class 'float'>"
|
||||
error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# METHODS
|
||||
if not mytype == str(type(v_input)):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
@@ -417,20 +344,10 @@ def val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_erro
|
||||
print(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
return False
|
||||
raise ValueError(error_msg + f"\nValue greater than maximum {v_max}.")
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
def input_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input valid str, int, or bool representation of bool, or else None
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional str v_arg_type
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_bool'
|
||||
if v_input is None: return False
|
||||
# suppress_errors
|
||||
@@ -446,7 +363,6 @@ def input_bool(v_input, v_name, method, suppress_errors = False, suppress_consol
|
||||
my_f = method + '.' + my_f
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return None
|
||||
# METHODS
|
||||
if not val_bool(v_input, v_name, my_f, True, True):
|
||||
if not val_int(v_input, v_name, my_f, 0, 1, True, True):
|
||||
# if str(type(v_input)) == "<class 'bytes'>":
|
||||
@@ -476,20 +392,10 @@ def input_bool(v_input, v_name, method, suppress_errors = False, suppress_consol
|
||||
raise ValueError(error_msg)
|
||||
else:
|
||||
return False if v_input == 0 else True
|
||||
# RETURNS
|
||||
return bool(v_input)
|
||||
|
||||
def full_val_bool(v_input, v_name, method, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that bool input is bool or valid equivalent
|
||||
# ARGUMENTS
|
||||
# bool (hopefully) my_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_bool'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -502,23 +408,11 @@ def full_val_bool(v_input, v_name, method, suppress_errors = False, suppress_con
|
||||
if not val_str(v_name, 'v_name', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# RETURNS
|
||||
return not (str(type(input_bool(v_input, v_name, method, suppress_errors, suppress_console_outputs, v_arg_type))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input int or valid equivalent, or else None
|
||||
# ARGUMENTS
|
||||
# int or str v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# v_min
|
||||
# v_min
|
||||
# bool suppress_errors
|
||||
# bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_int'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -539,7 +433,6 @@ def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_erro
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_int(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return None
|
||||
# METHODS
|
||||
error_msg = error_msg_str(v_input, v_name, method, "<class 'int'>", suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# v_input
|
||||
try:
|
||||
@@ -562,23 +455,11 @@ def input_int(v_input, v_name, method, v_min = None, v_max = None, suppress_erro
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
|
||||
return None
|
||||
# RETURNS
|
||||
return my_int
|
||||
|
||||
|
||||
def full_val_int(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is int or equivalent, else False, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# int (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_int'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -596,23 +477,11 @@ def full_val_int(v_input, v_name, method, v_min = None, v_max = None, suppress_e
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_int(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return False
|
||||
# RETURNS
|
||||
return not (str(type(input_int(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# input float, else return None
|
||||
# ARGUMENTS
|
||||
# float/int/str(numeric) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_min
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'input_float'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -633,7 +502,6 @@ def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_er
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_float(v_max, 'v_min', my_f, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return None
|
||||
# METHODS
|
||||
error_msg = error_msg_str(v_input, v_name, method, "<class 'float'>", suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
# v_input
|
||||
try:
|
||||
@@ -656,22 +524,11 @@ def input_float(v_input, v_name, method, v_min = None, v_max = None, suppress_er
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(f"{error_msg}\nInt input greater than maximum value. Value = {v_input}, maximum = {v_max}.")
|
||||
return None
|
||||
# RETURNS
|
||||
return my_float
|
||||
|
||||
|
||||
def full_val_float(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is numeric, and if not False, limited by v_min and v_max
|
||||
# ARGUMENTS
|
||||
# float (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional float v_min
|
||||
# optional float v_max
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'full_val_float'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -692,40 +549,22 @@ def full_val_float(v_input, v_name, method, v_min = None, v_max = None, suppress
|
||||
if not str(type(v_max)) == "<class 'NoneType'>":
|
||||
v_max = input_float(v_max, 'v_min', method, v_min, None, suppress_errors, suppress_console_outputs)
|
||||
if str(type(v_max)) == "<class 'NoneType'>": return False
|
||||
# RETURNS
|
||||
return not (str(type(input_float(v_input, v_name, method, v_min, v_max, suppress_errors, suppress_console_outputs))) == "<class 'NoneType'>")
|
||||
|
||||
|
||||
def make_ordinal(n):
|
||||
# FUNCTION
|
||||
# Get ordinal representation of number
|
||||
# ARGUMENTS
|
||||
# int n
|
||||
# ARGUMENT VALIDATION
|
||||
full_val_int(n, 'n', 'make_ordinal', 0)
|
||||
# VARIABLE INSTANTIATION
|
||||
n = int(n)
|
||||
# METHODS
|
||||
if 11 <= (n % 100):
|
||||
suffix= 'th'
|
||||
else:
|
||||
suffix = ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)]
|
||||
# RETURNS
|
||||
return str(n) + suffix
|
||||
|
||||
|
||||
def val_type(v_input, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type v_type
|
||||
# ARGUMENTS
|
||||
# v_type (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# str v_type
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_type'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -751,22 +590,11 @@ def val_type(v_input, v_name, method, v_type, suppress_errors = False, suppress_
|
||||
Helper_App.console_log(error_message)
|
||||
return False
|
||||
raise ValueError(error_message)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_instance(v_input, v_name, method, v_type, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type v_type
|
||||
# ARGUMENTS
|
||||
# v_type (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# type v_type
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_type'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -781,41 +609,25 @@ def val_instance(v_input, v_name, method, v_type, suppress_errors = False, suppr
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
error_message = error_msg_str(v_type, 'v_type', my_f, v_arg_type)
|
||||
if not isinstance(v_type, type): # mytype == v_type: # f"<class '{v_type}'>":
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_message)
|
||||
return False
|
||||
raise ValueError(error_message) # val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
error_message = error_msg_str(v_input, v_name, method, v_arg_type)
|
||||
# mytype = str(type(v_input))
|
||||
# if not (v_type == 'int' or v_type == 'bool' or v_type == 'float' or v_type == 'complex' or v_type == 'str' or v_type == 'NoneType'):
|
||||
if not isinstance(v_input, v_type): # mytype == v_type: # f"<class '{v_type}'>":
|
||||
if not isinstance(v_type, type):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_message)
|
||||
return False
|
||||
raise ValueError(error_message)
|
||||
# v_input
|
||||
error_message = error_msg_str(v_input, v_name, method, v_arg_type)
|
||||
if not isinstance(v_input, v_type):
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_message)
|
||||
return False
|
||||
raise ValueError(error_message)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, allow_nuns = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# str v_name - variable name
|
||||
# str method - parent method
|
||||
# str v_type - type of list items
|
||||
# int min_len - minimum length of list
|
||||
# int max_len - maximum length of list
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional bool allow_nuns
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_list'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -829,21 +641,14 @@ def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, s
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
# if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False
|
||||
if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len
|
||||
if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(min_len)) == "<class 'NoneType'>": return False
|
||||
# max_len
|
||||
if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False
|
||||
# if not str(type(max_len)) == "<class 'NoneType'>":
|
||||
# max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(max_len)) == "<class 'NoneType'>": return False
|
||||
# allow_nuns
|
||||
if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
# mytype = str(type(v_input))
|
||||
error_msg = error_msg_str(v_input, v_name, method, "<class 'list'>")
|
||||
if not str(type(v_input)) == "<class 'list'>":
|
||||
if suppress_errors:
|
||||
@@ -866,7 +671,6 @@ def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, s
|
||||
raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}')
|
||||
if v_type != '' and L > 0:
|
||||
for i in range(L):
|
||||
# mytype = str(type(v_input[i]))
|
||||
if not (val_type(v_input[i], f'{v_name}[{i}]', my_f, v_type, True) or allow_nuns and val_type(v_input[i], f'{v_name}[{i}]', my_f, "<class 'NoneType'>", True)): # mytype == v_type:
|
||||
error_msg = error_msg + '\n' + error_msg_str(v_input[i], f'{v_name}[{i}]', my_f, v_type, False, False, 'list element')
|
||||
if suppress_errors:
|
||||
@@ -874,25 +678,11 @@ def val_list(v_input, v_name, method, v_type = '', min_len = -1, max_len = -1, s
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_list_instances(v_input, v_name, method, v_type = None, min_len = -1, max_len = -1, suppress_errors = False, suppress_console_outputs: bool = False, allow_nuns = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# str v_name - variable name
|
||||
# str method - parent method
|
||||
# type v_type - type of list items
|
||||
# int min_len - minimum length of list
|
||||
# int max_len - maximum length of list
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional bool allow_nuns
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_list_instances'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -907,20 +697,12 @@ def val_list_instances(v_input, v_name, method, v_type = None, min_len = -1, max
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False
|
||||
# if not val_str(v_type, 'v_type', my_f, 6, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len
|
||||
if not full_val_int(min_len, 'min_len', my_f, None, None if max_len == -1 else max_len, suppress_errors, suppress_console_outputs): return False
|
||||
# min_len = input_int(min_len, 'min_len', method, None, max_len, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(min_len)) == "<class 'NoneType'>": return False
|
||||
# max_len
|
||||
if not full_val_int(max_len, 'max_len', my_f, None if max_len == -1 else (None if min_len == -1 else min_len), None, suppress_errors, suppress_console_outputs): return False
|
||||
# if not str(type(max_len)) == "<class 'NoneType'>":
|
||||
# max_len = input_int(max_len, 'max_len', method, min_len, None, suppress_errors, suppress_console_outputs)
|
||||
# if str(type(max_len)) == "<class 'NoneType'>": return False
|
||||
# allow_nuns
|
||||
if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
# mytype = str(type(v_input))
|
||||
error_msg = error_msg_str(v_input, v_name, method, "<class 'list'>")
|
||||
if not str(type(v_input)) == "<class 'list'>":
|
||||
if suppress_errors:
|
||||
@@ -943,38 +725,19 @@ def val_list_instances(v_input, v_name, method, v_type = None, min_len = -1, max
|
||||
raise ValueError(error_msg + f'\nInvalid list length. Minimum = {min_len}, length = {L}')
|
||||
if v_type != '' and L > 0:
|
||||
for i in range(L):
|
||||
# mytype = str(type(v_input[i]))
|
||||
if not (val_instance(v_input[i], f'{v_name}[{i}]', my_f, v_type, True) or allow_nuns and val_instance(v_input[i], f'{v_name}[{i}]', my_f, type(None), True)): # mytype == v_type:
|
||||
if not (val_instance(v_input[i], f'{v_name}[{i}]', my_f, v_type, True) or allow_nuns and val_instance(v_input[i], f'{v_name}[{i}]', my_f, type(None), True)):
|
||||
error_msg = error_msg + '\n' + error_msg_str(v_input[i], f'{v_name}[{i}]', my_f, v_type, False, False, 'list element')
|
||||
if suppress_errors:
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_nested_list(v_input, v_name, method, depth_i, depth_max, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs = [], suppress_errors = False, suppress_console_outputs = False, allow_nuns = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# for nested list of nested-index i
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# int depth_i - current depth of nesting of lists
|
||||
# int depth_max - maximum depth of nesting of lists - base 0
|
||||
# Optional[str] v_type - type of list items
|
||||
# Optional[int] v_min - minimum sublist size
|
||||
# Optional[list[int]] v_mins - minimum list sizes
|
||||
# Optional[int] v_max - maximum sublist size
|
||||
# Optional[list[int]] v_maxs - maximum list sizes
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional bool allow_nuns
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_nested_list'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -1017,7 +780,6 @@ def val_nested_list(v_input, v_name, method, depth_i, depth_max, v_type = '', v_
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
# METHODS
|
||||
L = len(v_input)
|
||||
if L == 0:
|
||||
if v_min > -1:
|
||||
@@ -1048,30 +810,12 @@ def val_nested_list(v_input, v_name, method, depth_i, depth_max, v_type = '', v_
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_nested_list_instances(v_input, v_name, method, depth_i, depth_max, v_type = '', v_min = -1, v_mins = [], v_max = -1, v_maxs = [], suppress_errors = False, suppress_console_outputs = False, allow_nuns = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# for nested list of nested-index i
|
||||
# ARGUMENTS
|
||||
# list[v_type] (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# int depth_i - current depth of nesting of lists
|
||||
# int depth_max - maximum depth of nesting of lists - base 0
|
||||
# Optional[str] v_type - type of list items
|
||||
# Optional[int] v_min - minimum sublist size
|
||||
# Optional[list[int]] v_mins - minimum list sizes
|
||||
# Optional[int] v_max - maximum sublist size
|
||||
# Optional[list[int]] v_maxs - maximum list sizes
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional bool allow_nuns
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_nested_list'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -1085,7 +829,6 @@ def val_nested_list_instances(v_input, v_name, method, depth_i, depth_max, v_typ
|
||||
# v_arg_type
|
||||
if not val_str(v_arg_type, 'v_arg_type', my_f, 1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# v_type
|
||||
# if not val_str(v_type, 'v_type', my_f, -1, -1, suppress_errors, suppress_console_outputs): return False
|
||||
if not val_type(v_type, 'v_type', my_f, type, suppress_errors, suppress_console_outputs): return False
|
||||
# v_min
|
||||
if not val_int(v_min, 'v_min', my_f, -1, None, suppress_errors, suppress_console_outputs): return False
|
||||
@@ -1108,13 +851,12 @@ def val_nested_list_instances(v_input, v_name, method, depth_i, depth_max, v_typ
|
||||
# allow_nuns
|
||||
if not val_bool(allow_nuns, 'allow_nuns', my_f, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
mytype = v_type if depth_i == depth_max else list # "<class 'list'>"
|
||||
mytype = v_type if depth_i == depth_max else list
|
||||
error_msg = error_msg_str(v_input, v_name, method, mytype, suppress_errors, suppress_console_outputs, v_arg_type)
|
||||
if not val_list_instances(v_input, v_name, method, mytype, v_min, v_max, suppress_errors, suppress_console_outputs, allow_nuns, v_arg_type):
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
# METHODS
|
||||
L = len(v_input)
|
||||
if L == 0:
|
||||
if v_min > -1:
|
||||
@@ -1145,23 +887,11 @@ def val_nested_list_instances(v_input, v_name, method, depth_i, depth_max, v_typ
|
||||
if not suppress_console_outputs:
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
def val_url(v_input, v_name, method, min_len = 12, max_len = -1, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type str
|
||||
# ARGUMENTS
|
||||
# str (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional int min_len
|
||||
# optional int max_len
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
_m = 'val_url'
|
||||
v_type = "<class 'str'>"
|
||||
val_bool(suppress_errors, 'suppress_errors', _m)
|
||||
@@ -1181,7 +911,6 @@ def val_url(v_input, v_name, method, min_len = 12, max_len = -1, suppress_errors
|
||||
if not val_int(max_len, 'max_len', _m, -1, None, suppress_errors, suppress_console_outputs): return False
|
||||
# v_input
|
||||
if not val_str(v_input, v_name, method, min_len, -1, suppress_errors, suppress_console_outputs): return False
|
||||
# METHODS
|
||||
error_msg = error_msg_str(v_input, 'v_input', _m, "<class 'str'>")
|
||||
if not (v_input[:8] == r'https://' or v_input[:7] == r'http://'):
|
||||
if suppress_errors:
|
||||
@@ -1189,40 +918,11 @@ def val_url(v_input, v_name, method, min_len = 12, max_len = -1, suppress_errors
|
||||
Helper_App.console_log(error_msg)
|
||||
return False
|
||||
raise ValueError(error_msg)
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
# def val_nparray(v_input, v_name, method, v_min = None, v_max = None, suppress_errors = False, suppress_console_outputs = False, v_arg_type = 'argument'):
|
||||
# # FUNCTION
|
||||
# # validate v_input is numpy ndarray
|
||||
# # ARGUMENTS
|
||||
# # numpy.ndarray v_input
|
||||
# # str v_name
|
||||
# # str method
|
||||
# #
|
||||
# # ARGUMENT VALIDATION
|
||||
# # METHODS
|
||||
# # RETURNS
|
||||
|
||||
|
||||
def val_DataFrame(v_input, v_name, method, v_types=[], min_col=-1, max_col=-1, cols=[], min_sz=-1, max_sz=-1, suppress_errors=False, suppress_console_outputs=False, v_arg_type='argument'):
|
||||
# FUNCTION
|
||||
# validate that v_input is of type list, and if defined: has v_len elements of type v_type
|
||||
# for nested list of nested-index i
|
||||
# ARGUMENTS
|
||||
# pandas.DataFrame (hopefully) v_input
|
||||
# str v_name
|
||||
# str method
|
||||
# optional list[str] v_type - column datatypes
|
||||
# optional int min_col - minimum number of columns
|
||||
# optional int max_col - maximum number of columns
|
||||
# optional list[str] cols - column names
|
||||
# optional int min_sz - minimum length of columns
|
||||
# optional int max_sz - maximum length of columns
|
||||
# optional bool suppress_errors
|
||||
# optional bool suppress_console_outputs
|
||||
# optional str v_arg_type
|
||||
# ARGUMENT VALIDATION
|
||||
my_f = 'val_DataFrame'
|
||||
val_bool(suppress_errors, 'suppress_errors', my_f)
|
||||
if not val_bool(suppress_console_outputs, 'suppress_console_outputs', my_f, suppress_errors):
|
||||
@@ -1259,7 +959,6 @@ def val_DataFrame(v_input, v_name, method, v_types=[], min_col=-1, max_col=-1, c
|
||||
raise ValueError(error_msg)
|
||||
# v_input
|
||||
if not val_type(v_input, v_name, my_f, "<class 'pandas.core.frame.DataFrame'>", suppress_errors, suppress_console_outputs, v_arg_type): return False
|
||||
# METHODS
|
||||
error_msg = error_msg_str(v_input, v_name, my_f, "<class 'pandas.core.frame.DataFrame'>", v_arg_type=v_arg_type)
|
||||
n_c = len(v_input.columns)
|
||||
if (min_col > 0 and n_c < min_col) or (max_col > 0 and n_c > max_col):
|
||||
@@ -1291,7 +990,6 @@ def val_DataFrame(v_input, v_name, method, v_types=[], min_col=-1, max_col=-1, c
|
||||
Helper_App.console_log(error_msg + f'\nInvalid column heading for column {v_input.columns[col_i]}')
|
||||
return False
|
||||
raise ValueError(error_msg + f'\nInvalid column heading for column {v_input.columns[col_i]}')
|
||||
# RETURNS
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -1,35 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created on Thu Apr 27 12:33:59 2023
|
||||
|
||||
@author: Edward Middleton-Smith
|
||||
|
||||
Argument Validation
|
||||
"""
|
||||
|
||||
# CLASSES
|
||||
# ATTRIBUTE DECLARATION
|
||||
# METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# ATTRIBUTE + VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# NORMAL METHODS
|
||||
# FUNCTION
|
||||
# ARGUMENTS
|
||||
# ARGUMENT VALIDATION
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
# RETURNS
|
||||
|
||||
# IMPORTS
|
||||
|
||||
# CLASSES
|
||||
|
||||
# METHODS
|
||||
def get_enum_member_by_text(enum_class, text):
|
||||
for member in enum_class.__members__.values():
|
||||
if member.name == text:
|
||||
|
||||
182
pay_stripe.py
182
pay_stripe.py
@@ -1,182 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: App General
|
||||
Feature: App
|
||||
|
||||
Description:
|
||||
Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles.
|
||||
"""
|
||||
|
||||
# IMPORTS
|
||||
# VARIABLE INSTANTIATION
|
||||
# METHODS
|
||||
|
||||
# IMPORTS
|
||||
import os
|
||||
import stripe
|
||||
import json
|
||||
from flask import Flask, render_template, render_template_string, jsonify, request, send_from_directory, redirect
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
|
||||
from config import app_config
|
||||
|
||||
# VARIABLE INSTANTIATION
|
||||
key_secret = os.environ.get("KEY_SECRET_STRIPE")
|
||||
key_public = os.environ.get("KEY_PUBLIC_STRIPE") # 'pk_test_51OGrxlL7BuLKjoMpfpfw7bSmZZK1MhqMoQ5VhW2jUj7YtoEejO4vqnxKPiqTHHuh9U4qqkywbPCSI9TpFKtr4SYH007KHMWs68'
|
||||
|
||||
# METHODS
|
||||
def create_product_price():
|
||||
print(f'stripe.api_key = {stripe.api_key}')
|
||||
starter_subscription = stripe.Product.create(
|
||||
name="Starter Subscription",
|
||||
description="$12/Month subscription",
|
||||
)
|
||||
|
||||
starter_subscription_price = stripe.Price.create(
|
||||
unit_amount=1200,
|
||||
currency="usd",
|
||||
recurring={"interval": "month"},
|
||||
product=starter_subscription['id'],
|
||||
)
|
||||
|
||||
# Save these identifiers
|
||||
print(f"Success! Here is your starter subscription product id: {starter_subscription.id}")
|
||||
print(f"Success! Here is your starter subscription price id: {starter_subscription_price.id}")
|
||||
|
||||
return starter_subscription_price.id
|
||||
|
||||
def get_file_str(f_address):
|
||||
f = open(f_address)
|
||||
return f.read()
|
||||
|
||||
# Ensure environment variables are set.
|
||||
price = os.getenv('PRICE')
|
||||
if price is None or price == 'price_12345' or price == '':
|
||||
print('You must set a Price ID in .env. Please see the README.')
|
||||
exit(0)
|
||||
|
||||
# For sample support and debugging, not required for production:
|
||||
stripe.set_app_info(
|
||||
'stripe-samples/checkout-one-time-payments',
|
||||
version='0.0.1',
|
||||
url='https://github.com/stripe-samples/checkout-one-time-payments')
|
||||
|
||||
# stripe.api_version = '2020-08-27'
|
||||
stripe.api_key = key_secret # os.getenv('KEY_SECRET_STRIPE')
|
||||
|
||||
# app_dir = str(os.path.abspath(os.path.join(
|
||||
# __file__, "..", "..")))
|
||||
# static_dir = str(os.path.abspath(os.path.join(
|
||||
# app_dir, os.getenv("STATIC_DIR"))))
|
||||
# template_dir = str(os.path.abspath(os.path.join(
|
||||
# app_dir, os.getenv("TEMPLATE_DIR"))))
|
||||
app = Flask(__name__) # , static_folder=static_dir,
|
||||
# static_url_path="", template_folder=template_dir)
|
||||
app.config.from_object(app_config)
|
||||
|
||||
@app.route('/', methods=['GET'])
|
||||
def home():
|
||||
# return render_template(f'{app_dir}\\templates\\_home.html') # f'{app_dir}\\templates\\layout.html')
|
||||
# return render_template_string(get_file_str(f'{app_dir}\\templates\\_home.html')) # f'{app_dir}\\templates\\layout.html')
|
||||
return render_template('_home.html', title='Home')
|
||||
|
||||
@app.route('/store', methods=['GET'])
|
||||
def store_home():
|
||||
return render_template('_store_home.html', title='Store Home')
|
||||
|
||||
@app.route('/contact')
|
||||
def contact():
|
||||
return render_template('_contact.html', title='Contact Us')
|
||||
|
||||
|
||||
@app.route('/config', methods=['GET'])
|
||||
def get_publishable_key():
|
||||
price = stripe.Price.retrieve(os.getenv('PRICE'))
|
||||
return jsonify({
|
||||
'publicKey': key_public, # os.getenv('KEY_PUBLIC_STRIPE'),
|
||||
'unitAmount': price['unit_amount'],
|
||||
'currency': price['currency']
|
||||
})
|
||||
|
||||
# Fetch the Checkout Session to display the JSON result on the success page
|
||||
@app.route('/checkout-session', methods=['GET'])
|
||||
def get_checkout_session():
|
||||
id = request.args.get('sessionId')
|
||||
print(f'checkout session id: {id}')
|
||||
checkout_session = stripe.checkout.Session.retrieve(id)
|
||||
return jsonify(checkout_session)
|
||||
|
||||
|
||||
@app.route('/create-checkout-session', methods=['POST'])
|
||||
def create_checkout_session():
|
||||
quantity = request.form.get('quantity', 1)
|
||||
domain_url = os.getenv('DOMAIN')
|
||||
|
||||
try:
|
||||
# Create new Checkout Session for the order
|
||||
# Other optional params include:
|
||||
# [billing_address_collection] - to display billing address details on the page
|
||||
# [customer] - if you have an existing Stripe Customer ID
|
||||
# [payment_intent_data] - lets capture the payment later
|
||||
# [customer_email] - lets you prefill the email input in the form
|
||||
# [automatic_tax] - to automatically calculate sales tax, VAT and GST in the checkout page
|
||||
# For full details see https://stripe.com/docs/api/checkout/sessions/create
|
||||
|
||||
# ?session_id={CHECKOUT_SESSION_ID} means the redirect will have the session ID set as a query param
|
||||
checkout_session = stripe.checkout.Session.create(
|
||||
success_url=domain_url + '/success.html?session_id={CHECKOUT_SESSION_ID}',
|
||||
cancel_url=domain_url + '/canceled.html',
|
||||
mode='subscription', # 'payment',
|
||||
# automatic_tax={'enabled': True},
|
||||
line_items=[{
|
||||
'price': os.getenv('PRICE'),
|
||||
'quantity': quantity,
|
||||
}]
|
||||
)
|
||||
return redirect(checkout_session.url, code=303)
|
||||
except Exception as e:
|
||||
return jsonify(error=str(e)), 403
|
||||
|
||||
|
||||
@app.route('/webhook', methods=['POST'])
|
||||
def webhook_received():
|
||||
# You can use webhooks to receive information about asynchronous payment events.
|
||||
# For more about our webhook events check out https://stripe.com/docs/webhooks.
|
||||
webhook_secret = os.getenv('STRIPE_WEBHOOK_SECRET')
|
||||
request_data = json.loads(request.data)
|
||||
|
||||
if webhook_secret:
|
||||
# Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
|
||||
signature = request.headers.get('stripe-signature')
|
||||
try:
|
||||
event = stripe.Webhook.construct_event(
|
||||
payload=request.data, sig_header=signature, secret=webhook_secret)
|
||||
data = event['data']
|
||||
except Exception as e:
|
||||
return e
|
||||
# Get the type of webhook event sent - used to check the status of PaymentIntents.
|
||||
event_type = event['type']
|
||||
else:
|
||||
data = request_data['data']
|
||||
event_type = request_data['type']
|
||||
data_object = data['object']
|
||||
|
||||
print('event ' + event_type)
|
||||
|
||||
if event_type == 'checkout.session.completed':
|
||||
print('🔔 Payment succeeded!')
|
||||
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# stripe.api_key = key_secret
|
||||
|
||||
# create_product_price()
|
||||
|
||||
# Setup Stripe python client library.
|
||||
load_dotenv(find_dotenv())
|
||||
app.run(port=4242, debug=True)
|
||||
@@ -1,3 +1,5 @@
|
||||
User-agent: *
|
||||
Disallow: /qa
|
||||
Disallow: /dev
|
||||
Disallow: /dev
|
||||
Disallow: /contact
|
||||
Disallow: /*.partsltd.co.uk/
|
||||
54
routes.py
54
routes.py
@@ -1,54 +0,0 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Backend
|
||||
Feature: Controller - Webpage routing
|
||||
|
||||
Description:
|
||||
Defines the routes and view functions for each page.
|
||||
Manages the interaction between the frontend and backend.
|
||||
"""
|
||||
|
||||
from flask import render_template, url_for, Blueprint
|
||||
from app import app
|
||||
from app.forms import Form_Contact
|
||||
# from forms import MyForm
|
||||
# from app import MyForm
|
||||
from model_view_contact import Model_View_Contact
|
||||
|
||||
"""
|
||||
@app.route('/', methods=['GET'])
|
||||
def home():
|
||||
return render_template('_home.html', title='Home')
|
||||
|
||||
@app.route('/store', methods=['GET'])
|
||||
def store_home():
|
||||
return render_template('_store_home.html', title='Store Home')
|
||||
|
||||
@app.route('/contact', methods=['GET', 'POST'])
|
||||
def contact():
|
||||
form = Form_Contact()
|
||||
if form.validate_on_submit():
|
||||
# Handle form submission
|
||||
email = form.sender_email.data
|
||||
CC = form.sender_CC.data
|
||||
name = form.sender_name.data
|
||||
msg = form.sender_message.data
|
||||
# return render_template('contact.html', form=form)
|
||||
# return render_template('_contact.html', title='Contact Us')
|
||||
return render_template('contact.html', model=Model_View_Contact(form))
|
||||
|
||||
@app.route('/about')
|
||||
def about():
|
||||
return render_template('about.html')
|
||||
|
||||
@app.route('/contact', methods=['GET', 'POST'])
|
||||
def contact():
|
||||
form = MyForm()
|
||||
if form.validate_on_submit():
|
||||
# Handle form submission
|
||||
pass
|
||||
return render_template('contact.html', form=form)
|
||||
"""
|
||||
6
run.py
6
run.py
@@ -11,7 +11,11 @@ Runs project.
|
||||
"""
|
||||
|
||||
from app import app
|
||||
import os
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
|
||||
load_dotenv(find_dotenv())
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
app.run(debug=(os.getenv('FLASK_ENV') == 'development'))
|
||||
# app.run(debug=True, host="0.0.0.0", port=5000)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,293 +0,0 @@
|
||||
|
||||
/* Clear Store DataBase */
|
||||
|
||||
|
||||
|
||||
-- Drop dependencies
|
||||
DROP TABLE IF EXISTS Shop_Calc_User_Temp;
|
||||
DROP TABLE IF EXISTS tmp_Msg_Error;
|
||||
DROP TABLE IF EXISTS tmp_Currency;
|
||||
DROP TABLE IF EXISTS tmp_Delivery_Region;
|
||||
DROP TABLE IF EXISTS tmp_Region;
|
||||
DROP TABLE IF EXISTS tmp_Shop_User;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Order;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Product;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Product_p_shop_calc_user;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Image;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Variation;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Discount;
|
||||
DROP TABLE IF EXISTS tmp_Discount;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Product_Category;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Region_Link;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Product_Currency_Link;
|
||||
DROP TABLE IF EXISTS tmp_User_Role_Link;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Basket;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Supplier_Purchase_Order_Product_Link;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Supplier_Purchase_Order;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Supplier;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Manufacturing_Purchase_Order_Product_Link;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Manufacturing_Purchase_Order;
|
||||
DROP TABLE IF EXISTS tmp_Shop_Customer;
|
||||
|
||||
|
||||
|
||||
-- Delete old tables
|
||||
DROP TABLE IF EXISTS Shop_Customer_Sales_Order_Product_Link_Temp;
|
||||
DROP TABLE IF EXISTS Shop_Customer_Sales_Order_Product_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Customer_Sales_Order_Product_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Customer_Sales_Order_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Customer_Sales_Order;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Customer_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Customer;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Manufacturing_Purchase_Order_Product_Link_Temp;
|
||||
DROP TABLE IF EXISTS Shop_Manufacturing_Purchase_Order_Product_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Manufacturing_Purchase_Order_Product_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Manufacturing_Purchase_Order_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Manufacturing_Purchase_Order;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Purchase_Order_Product_Link_Temp;
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Purchase_Order_Product_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Purchase_Order_Product_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Purchase_Order_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Purchase_Order;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Unit_Measurement_Conversion_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Unit_Measurement_Conversion;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Unit_Measurement_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Unit_Measurement;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Supplier_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Supplier;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Order_Product_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User_Order_Product_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Order_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User_Order;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Order_Status_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User_Order_Status;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Basket_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User_Basket;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Address_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Address;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Role_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User_Role_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_User_Audit;
|
||||
DROP TABLE IF EXISTS Shop_User;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Role_Permission_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Role_Permission_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Role_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Role;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Permission_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Permission;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Permission_Group_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Permission_Group;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Discount_Region_Currency_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Discount_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Discount;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation_Delivery_Option_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation_Delivery_Option_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Option_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Option;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Image_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Image;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Image_Type_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Image_Type;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Currency_Region_Link;
|
||||
DROP TABLE IF EXISTS Shop_Product_Currency_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Currency_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Variation_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Variation_Link;
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation_Variation_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Permutation;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Variation_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Variation;
|
||||
DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Variation_Type_Link;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Variation_Type_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Variation_Type;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Tax_Or_Surcharge;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Currency_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Currency;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Region_Branch_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Region_Branch;
|
||||
DROP TABLE IF EXISTS Shop_Region_Branch_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Region_Branch;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Region_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Delivery_Region;
|
||||
DROP TABLE IF EXISTS Shop_Region_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Region;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Interval_Recurrence_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Interval_Recurrence;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Category_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Product_Category;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_General_Audit;
|
||||
DROP TABLE IF EXISTS Shop_General;
|
||||
|
||||
DROP TABLE IF EXISTS File_Type_Audit;
|
||||
DROP TABLE IF EXISTS File_Type;
|
||||
|
||||
DROP TABLE IF EXISTS Msg_Error_Type;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Access_Level_Audit;
|
||||
DROP TABLE IF EXISTS Shop_Access_Level;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Sales_And_Purchasing_Change_Set;
|
||||
DROP TABLE IF EXISTS Shop_User_Change_Set;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Msg_Error_Type;
|
||||
|
||||
DROP TABLE IF EXISTS Shop_Product_Change_Set;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
RAISE NOTICE 'TABLE DELETION COMPLETE';
|
||||
END $$;
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_user_eval;
|
||||
DROP FUNCTION IF EXISTS p_shop_calc_user;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_user_eval;
|
||||
DROP PROCEDURE IF EXISTS p_shop_calc_user;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_product;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_product;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_product;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_product;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_supplier;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_supplier;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_supplier;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_supplier;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_supplier_purchase_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_supplier_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_supplier_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_supplier_purchase_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_manufacturing_purchase_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_manufacturing_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_manufacturing_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_manufacturing_purchase_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_customer;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_customer;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_customer;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_customer;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_customer_sales_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_customer_sales_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_customer_sales_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_customer_sales_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_user;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_user;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_user;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_user;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_save_user_basket;
|
||||
DROP FUNCTION IF EXISTS p_shop_save_user_basket;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_save_user_basket;
|
||||
DROP PROCEDURE IF EXISTS p_shop_save_user_basket;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_product;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_product;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_product;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_product;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_role_permission;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_role_permission;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_role_permission;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_role_permission;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_currency;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_currency;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_currency;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_currency;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_region;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_region;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_region;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_region;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_user_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_user_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_user_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_user_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_stripe_product_new;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_stripe_product_new;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_stripe_product_new;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_product_new;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_stripe_price_new;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_stripe_price_new;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_stripe_price_new;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_stripe_price_new;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_supplier;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_supplier;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_supplier;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_supplier;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_supplier_purchase_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_supplier_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_supplier_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_supplier_purchase_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_manufacturing_purchase_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_manufacturing_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_manufacturing_purchase_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_manufacturing_purchase_order;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_customer;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_customer;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_customer;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_customer;
|
||||
|
||||
DROP FUNCTION IF EXISTS fn_shop_get_many_customer_sales_order;
|
||||
DROP FUNCTION IF EXISTS p_shop_get_many_customer_sales_order;
|
||||
DROP PROCEDURE IF EXISTS fn_shop_get_many_customer_sales_order;
|
||||
DROP PROCEDURE IF EXISTS p_shop_get_many_customer_sales_order;
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
-- Product Change Sets
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Change_Set';
|
||||
|
||||
CREATE TABLE Shop_Product_Change_Set (
|
||||
id_change_set INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
comment VARCHAR(4000),
|
||||
updated_last_on TIMESTAMP,
|
||||
updated_last_by VARCHAR(100)
|
||||
);
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
-- User Change Sets
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_User_Change_Set';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_User_Change_Set (
|
||||
id_change_set INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
comment VARCHAR(4000),
|
||||
updated_last_on TIMESTAMP,
|
||||
updated_last_by VARCHAR(100)
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
-- Access Levels
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Access_Level (
|
||||
id_access_level INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
priority INTEGER NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Access_Level_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_User_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
-- Sales And Purchasing Change Sets
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Sales_And_Purchasing_Change_Set';
|
||||
|
||||
CREATE TABLE Shop_Sales_And_Purchasing_Change_Set (
|
||||
id_change_set INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
comment VARCHAR(4000),
|
||||
updated_last_on TIMESTAMP,
|
||||
updated_last_by VARCHAR(100)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Access Level Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Access_Level_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Access_Level_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_access_level INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Access_Level_Audit_id_access_level
|
||||
FOREIGN KEY (id_access_level)
|
||||
REFERENCES Shop_Access_Level(id_access_level)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(255),
|
||||
value_new VARCHAR(255),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Access_Level_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_User_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
-- Error Message Type
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Msg_Error_Type';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Msg_Error_Type (
|
||||
id_type INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
description VARCHAR(1000)
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
-- File Types
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS File_Type (
|
||||
id_type INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(100),
|
||||
extension VARCHAR(50),
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
updated_last_on TIMESTAMP,
|
||||
updated_last_by VARCHAR(100)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- File Type Audit
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'File_Type_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS File_Type_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_type INTEGER NOT NULL,
|
||||
CONSTRAINT FK_File_Type_Audit_id_type
|
||||
FOREIGN KEY (id_type)
|
||||
REFERENCES File_Type(id_type)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(100),
|
||||
value_new VARCHAR(100),
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
updated_last_on TIMESTAMP,
|
||||
updated_last_by VARCHAR(100)
|
||||
);
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
-- Generic / shared properties
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_General (
|
||||
id_general INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
quantity_max REAL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT CHK_Shop_General_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Shop General Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_General_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_General_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_general INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_General_Audit_id_general
|
||||
FOREIGN KEY (id_general)
|
||||
REFERENCES Shop_General(id_general)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(100),
|
||||
value_new VARCHAR(100),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_General_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
-- Categories
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Category';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Category (
|
||||
id_category INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
description VARCHAR(4000),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_Category_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Category Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Category_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Category_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_category INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Category_Audit_id_category
|
||||
FOREIGN KEY (id_category)
|
||||
REFERENCES Shop_Product_Category(id_category)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(4000),
|
||||
value_new VARCHAR(4000),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Category_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
-- Recurrence Interval
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Interval_Recurrence';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Interval_Recurrence (
|
||||
id_interval INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
name_plural VARCHAR(256),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Interval_Recurrence_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Recurrence Interval Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Interval_Recurrence_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Interval_Recurrence_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_interval INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Interval_Recurrence_Audit_id_interval
|
||||
FOREIGN KEY (id_interval)
|
||||
REFERENCES Shop_Interval_Recurrence(id_interval)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(256),
|
||||
value_new VARCHAR(256),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Interval_Recurrence_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
-- Regions
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Region (
|
||||
id_region INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Region_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Region Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Region_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_region INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Audit_id_region
|
||||
FOREIGN KEY (id_region)
|
||||
REFERENCES Shop_Region(id_region)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(64) NOT NULL,
|
||||
value_prev VARCHAR(200),
|
||||
value_new VARCHAR(200),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,29 +0,0 @@
|
||||
|
||||
-- Region Branchs
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Region_Branch (
|
||||
id_branch INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_region_parent INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Branch_id_region_parent
|
||||
FOREIGN KEY (id_region_parent)
|
||||
REFERENCES Shop_Region(id_region)
|
||||
ON UPDATE RESTRICT,
|
||||
id_region_child INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Branch_id_region_child
|
||||
FOREIGN KEY (id_region_child)
|
||||
REFERENCES Shop_Region(id_region)
|
||||
ON UPDATE RESTRICT,
|
||||
-- depth INTEGER NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Region_Branch_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Region Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Region_Branch_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Region_Branch_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_branch INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Branch_Audit_id_branch
|
||||
FOREIGN KEY (id_branch)
|
||||
REFERENCES Shop_Region_Branch(id_branch)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(64) NOT NULL,
|
||||
value_prev VARCHAR(10),
|
||||
value_new VARCHAR(10),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Region_Branch_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
-- Currencies
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Currency (
|
||||
id_currency INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
symbol VARCHAR(1) NOT NULL,
|
||||
factor_from_GBP REAL NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Currency_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
ON UPDATE RESTRICT
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
-- Currency Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Currency_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Currency_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_currency INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Currency_Audit_id_currency
|
||||
FOREIGN KEY (id_currency)
|
||||
REFERENCES Shop_Currency(id_currency)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(255),
|
||||
value_new VARCHAR(255),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Currency_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_User_Change_Set(id_change_set)
|
||||
ON UPDATE RESTRICT
|
||||
);
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
-- Taxes and Surcharges
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge';
|
||||
|
||||
CREATE TABLE Shop_Tax_Or_Surcharge (
|
||||
id_tax INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50) NOT NULL,
|
||||
name VARCHAR(200) NOT NULL,
|
||||
id_region_buyer INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_buyer
|
||||
FOREIGN KEY (id_region_buyer)
|
||||
REFERENCES Shop_Region(id_region),
|
||||
id_region_seller INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_region_seller
|
||||
FOREIGN KEY (id_region_seller)
|
||||
REFERENCES Shop_Region(id_region),
|
||||
id_currency INTEGER,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_currency
|
||||
FOREIGN KEY (id_currency)
|
||||
REFERENCES Shop_Currency(id_currency)
|
||||
ON UPDATE RESTRICT,
|
||||
fixed_fee REAL NOT NULL DEFAULT 0,
|
||||
multiplier REAL NOT NULL DEFAULT 1 CHECK (multiplier > 0),
|
||||
apply_fixed_fee_before_multiplier BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
quantity_min REAL NOT NULL DEFAULT 0,
|
||||
quantity_max REAL NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
-- Tax Or Surcharge Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Tax_Or_Surcharge_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Tax_Or_Surcharge_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_tax INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_discount
|
||||
FOREIGN KEY (id_tax)
|
||||
REFERENCES Shop_Tax_Or_Surcharge(id_tax)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(200),
|
||||
value_new VARCHAR(200),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Tax_Or_Surcharge_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
ON UPDATE RESTRICT
|
||||
);
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
-- Products
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product (
|
||||
id_product INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
-- description VARCHAR(4000),
|
||||
id_category INTEGER NOT NULL,
|
||||
has_variations BOOLEAN NOT NULL,
|
||||
/*
|
||||
price_GBP_full REAL,
|
||||
price_GBP_min REAL,
|
||||
-- ratio_discount_overall REAL NOT NULL DEFAULT 0,
|
||||
CONSTRAINT FK_Shop_Product_id_category
|
||||
FOREIGN KEY (id_category)
|
||||
REFERENCES Shop_Product_Category(id_category)
|
||||
ON UPDATE RESTRICT,
|
||||
latency_manuf INTEGER,
|
||||
quantity_min REAL,
|
||||
quantity_max REAL,
|
||||
quantity_step REAL,
|
||||
quantity_stock REAL,
|
||||
is_subscription BOOLEAN,
|
||||
id_unit_measurement_interval_recurrence INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_id_unit_measurement_interval_recurrence
|
||||
FOREIGN KEY (id_unit_measurement_interval_recurrence)
|
||||
REFERENCES Shop_Interval_Recurrence(id_interval),
|
||||
count_interval_recurrence INTEGER,
|
||||
*/
|
||||
id_access_level_required INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_id_access_level_required
|
||||
FOREIGN KEY (id_access_level_required)
|
||||
REFERENCES Shop_Access_Level(id_access_level),
|
||||
-- id_stripe_product VARCHAR(100),
|
||||
-- id_stripe_price VARCHAR(100) NOT NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Products
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_product INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Audit_id_product
|
||||
FOREIGN KEY (id_product)
|
||||
REFERENCES Shop_Product(id_product)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(255),
|
||||
value_new VARCHAR(255),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
-- Variation Types
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Variation_Type (
|
||||
id_type INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
name_plural VARCHAR(256),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Variation_Type_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Variation Type Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Type_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Variation_Type_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_type INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Variation_Type_Audit_id_type
|
||||
FOREIGN KEY (id_type)
|
||||
REFERENCES Shop_Variation_Type(id_type)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(256),
|
||||
value_new VARCHAR(256),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Variation_Type_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
-- Variations
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation';
|
||||
|
||||
CREATE TABLE Shop_Variation (
|
||||
id_variation INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_type INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Variation_id_type
|
||||
FOREIGN KEY (id_type)
|
||||
REFERENCES Shop_Variation_Type(id_type)
|
||||
ON UPDATE RESTRICT,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Variation_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Variation Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Variation_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Variation_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_variation INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Variation_Audit_id_variation
|
||||
FOREIGN KEY (id_variation)
|
||||
REFERENCES Shop_Variation(id_variation)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(255),
|
||||
value_new VARCHAR(255),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Variation_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,47 +0,0 @@
|
||||
|
||||
-- Product Permutation
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Permutation (
|
||||
id_permutation INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_product INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Variation_Link_id_product
|
||||
FOREIGN KEY (id_product)
|
||||
REFERENCES Shop_Product(id_product)
|
||||
ON UPDATE RESTRICT,
|
||||
-- name VARCHAR(255) NOT NULL,
|
||||
description VARCHAR(4000) NOT NULL,
|
||||
cost_local REAL NOT NULL,
|
||||
id_currency_cost INTEGER NOT NULL,
|
||||
profit_local_min REAL NOT NULL,
|
||||
-- id_currency_profit_min INTEGER NOT NULL,
|
||||
latency_manufacture INTEGER NOT NULL,
|
||||
quantity_min REAL NOT NULL,
|
||||
quantity_max REAL NOT NULL,
|
||||
quantity_step REAL NOT NULL,
|
||||
quantity_stock REAL NOT NULL,
|
||||
is_subscription BOOLEAN NOT NULL,
|
||||
id_unit_measurement_interval_recurrence INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_id_unit_measurement_interval_recurrence
|
||||
FOREIGN KEY (id_unit_measurement_interval_recurrence)
|
||||
REFERENCES Shop_Interval_Recurrence(id_interval),
|
||||
count_interval_recurrence INTEGER,
|
||||
/*
|
||||
id_access_level_required INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_id_access_level_required
|
||||
FOREIGN KEY (id_access_level_required)
|
||||
REFERENCES Shop_Access_Level(id_access_level),
|
||||
*/
|
||||
id_stripe_product VARCHAR(100) NULL,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_Variation_Link_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
-- Product Permutation Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_permutation INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Audit_id_permutation
|
||||
FOREIGN KEY (id_permutation)
|
||||
REFERENCES Shop_Product_Permutation(id_permutation)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(4000),
|
||||
value_new VARCHAR(4000),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
ON UPDATE RESTRICT
|
||||
);
|
||||
@@ -1,28 +0,0 @@
|
||||
|
||||
-- Product Permutation Variation Link
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link (
|
||||
id_link INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_permutation INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_permutation
|
||||
FOREIGN KEY (id_permutation)
|
||||
REFERENCES Shop_Product_Permutation(id_permutation)
|
||||
ON UPDATE RESTRICT,
|
||||
id_variation INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_variation
|
||||
FOREIGN KEY (id_variation)
|
||||
REFERENCES Shop_Variation(id_variation)
|
||||
ON UPDATE RESTRICT,
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,23 +0,0 @@
|
||||
|
||||
-- Product Permutation Variation Link Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Permutation_Variation_Link_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Permutation_Variation_Link_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_link INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_link
|
||||
FOREIGN KEY (id_link)
|
||||
REFERENCES Shop_Product_Permutation_Variation_Link(id_link)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(10),
|
||||
value_new VARCHAR(10),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Permutation_Variation_Link_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
ON UPDATE RESTRICT
|
||||
);
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
-- Product Currency Region link
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link (
|
||||
id_link INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_product INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_product
|
||||
FOREIGN KEY (id_product)
|
||||
REFERENCES Shop_Product(id_product)
|
||||
ON UPDATE RESTRICT,
|
||||
id_permutation INTEGER NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_permutation
|
||||
FOREIGN KEY (id_permutation)
|
||||
REFERENCES Shop_Product_Permutation(id_permutation)
|
||||
ON UPDATE RESTRICT,
|
||||
id_currency INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_currency
|
||||
FOREIGN KEY (id_currency)
|
||||
REFERENCES Shop_Currency(id_currency)
|
||||
ON UPDATE RESTRICT,
|
||||
id_region_purchase INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_region_purchase
|
||||
FOREIGN KEY (id_region_purchase)
|
||||
REFERENCES Shop_Region(id_region)
|
||||
ON UPDATE RESTRICT,
|
||||
price_local_VAT_incl REAL NULL,
|
||||
price_local_VAT_excl REAL NULL,
|
||||
id_stripe_price VARCHAR(200),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Product Currency Region Link Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Product_Currency_Region_Link_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Product_Currency_Region_Link_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_link INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_link
|
||||
FOREIGN KEY (id_link)
|
||||
REFERENCES Shop_Product_Currency_Region_Link(id_link)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(10),
|
||||
value_new VARCHAR(10),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Product_Currency_Region_Link_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
-- Image Types
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Image_Type (
|
||||
id_type INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
code VARCHAR(50),
|
||||
name VARCHAR(255),
|
||||
name_plural VARCHAR(256),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Image_Type_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
-- Image Type Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Type_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Image_Type_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_type INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_Type_Audit_id_type
|
||||
FOREIGN KEY (id_type)
|
||||
REFERENCES Shop_Image_Type(id_type)
|
||||
ON UPDATE RESTRICT,
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(256),
|
||||
value_new VARCHAR(256),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_Type_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,35 +0,0 @@
|
||||
|
||||
-- Images
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Image (
|
||||
id_image INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_type_image INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_id_type_image
|
||||
FOREIGN KEY (id_type_image)
|
||||
REFERENCES Shop_Image_Type(id_type),
|
||||
id_type_file INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_id_type_file
|
||||
FOREIGN KEY (id_type_file)
|
||||
REFERENCES File_Type(id_type),
|
||||
id_product INTEGER NULL,
|
||||
CONSTRAINT FK_Shop_Image_id_product
|
||||
FOREIGN KEY (id_product)
|
||||
REFERENCES Shop_Product(id_product),
|
||||
id_permutation INTEGER NULL,
|
||||
CONSTRAINT FK_Shop_Image_id_permutation
|
||||
FOREIGN KEY (id_permutation)
|
||||
REFERENCES Shop_Product_Permutation(id_permutation),
|
||||
url VARCHAR(255),
|
||||
active BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
display_order INTEGER NOT NULL,
|
||||
created_on TIMESTAMP,
|
||||
created_by INT,
|
||||
id_change_set INTEGER,
|
||||
CONSTRAINT FK_Shop_Image_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
-- Image Type Audits
|
||||
|
||||
|
||||
|
||||
SELECT CONCAT('WARNING: Table ', TABLE_NAME, ' already exists.') AS msg_warning FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Shop_Image_Audit';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS Shop_Image_Audit (
|
||||
id_audit INTEGER NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
|
||||
id_image INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_Audit_id_image
|
||||
FOREIGN KEY (id_image)
|
||||
REFERENCES Shop_Image(id_image),
|
||||
name_field VARCHAR(50),
|
||||
value_prev VARCHAR(10),
|
||||
value_new VARCHAR(10),
|
||||
id_change_set INTEGER NOT NULL,
|
||||
CONSTRAINT FK_Shop_Image_Audit_id_change_set
|
||||
FOREIGN KEY (id_change_set)
|
||||
REFERENCES Shop_Product_Change_Set(id_change_set)
|
||||
);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user