1. Refactoring form objects and database objects to use inheritance and abstract base class for consistency and reduced redundancy.\n2. Contact us page button links updated to resolve error of missing link causing page refresh instead of expected functionality.
This commit is contained in:
54
DEPRECATED - routes.py
Normal file
54
DEPRECATED - routes.py
Normal file
@@ -0,0 +1,54 @@
|
||||
"""
|
||||
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 models.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)
|
||||
"""
|
||||
@@ -252,12 +252,12 @@ def basket_add():
|
||||
print(f'editing basket:')
|
||||
model.basket_item_edit(permutation_id, quantity, True) # new_basket =
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
html_block = render_template('_block_store_basket.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) # 'items': [b_i.to_json() for b_i in model.basket]}})
|
||||
return jsonify({'status': 'failure', 'Message': 'Invalid quantities'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Invalid quantities'})
|
||||
|
||||
|
||||
|
||||
@@ -285,12 +285,12 @@ def basket_edit():
|
||||
permutation_id, quantity = model.import_JSON_basket_item(data, form)
|
||||
model.basket_item_edit(permutation_id, quantity, False) # new_basket =
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
html_block = render_template('_block_store_basket.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}})
|
||||
return jsonify({'status': 'failure', 'Message': 'Invalid quantities'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Invalid quantities'})
|
||||
|
||||
@app.route('/store/basket_delete', methods=['POST'])
|
||||
def basket_delete():
|
||||
@@ -307,7 +307,7 @@ def basket_delete():
|
||||
permutation_id, quantity = model.import_JSON_basket_item(data)
|
||||
model.basket_item_edit(permutation_id, 0, False) # new_basket =
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
html_block = render_template('_block_store_basket.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
@@ -320,7 +320,7 @@ def basket_delete():
|
||||
item_deleted = True
|
||||
break
|
||||
if not item_deleted:
|
||||
return jsonify({'status': 'failure', 'Message': 'Basket item removal failure: product not found in basket.'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Basket item removal failure: product not found in basket.'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
html_block = render_template('_block_store_basket.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
@@ -345,7 +345,7 @@ def store_basket():
|
||||
print('importing basket')
|
||||
model.import_JSON_basket(data)
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad basket data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad basket data received by controller'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
html_block = render_template('_page_store_billing.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
@@ -390,7 +390,7 @@ def basket_info():
|
||||
data_info[model.key_info_identical] = form.identical
|
||||
print(f'identical: {data_info[model.key_info_identical]}')
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad form data received by controller'})
|
||||
# return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket })
|
||||
# html_block = render_template('_block_store_basket.html', model = model)
|
||||
# print(f'html_block:\n{html_block}')
|
||||
@@ -398,7 +398,7 @@ def basket_info():
|
||||
data[model.key_info_type] = model.key_info_billing if (info_type == model.key_info_billing) else model.key_info_delivery
|
||||
data[info_type] = data_info
|
||||
return jsonify(Success = True, data = data)
|
||||
return jsonify({'status': 'failure', 'Message': f'Invalid address information\n{form.errors}'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': f'Invalid address information\n{form.errors}'})
|
||||
|
||||
|
||||
@app.route('/store/product?permutationId=<permutation_id>regionId=&<region_id>¤cyId=<currency_id>&isIncludedVAT=<is_included_VAT>', methods=['GET']) # <product_id>&
|
||||
@@ -507,7 +507,7 @@ def create_checkout_session():
|
||||
code_currency = 'GBP' # data[model.key_code_currency]
|
||||
print(f'currency code: {code_currency}')
|
||||
except:
|
||||
return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad form data received by controller'})
|
||||
items = []
|
||||
for item in model.basket.items:
|
||||
permutation = item.product.get_permutation_selected()
|
||||
|
||||
2
README
2
README
@@ -7,4 +7,4 @@ host for machine:
|
||||
python -m flask run
|
||||
|
||||
host for local network:
|
||||
python -m flask run --host=0.0.0.0
|
||||
python -m flask run --host=0.0.0.0
|
||||
|
||||
Binary file not shown.
5
app.py
5
app.py
@@ -39,6 +39,8 @@ import lib.argument_validation as av
|
||||
"""
|
||||
from routing.core import routes_core
|
||||
from routing.legal import routes_legal
|
||||
from routing.store.store import routes_store
|
||||
from routing.store.product import routes_store_product
|
||||
from routing.store.product_category import routes_store_product_category
|
||||
from routing.store.product_permutation import routes_store_product_permutation
|
||||
from routing.store.stock_item import routes_store_stock_item
|
||||
@@ -100,7 +102,8 @@ with app.app_context():
|
||||
|
||||
app.register_blueprint(routes_core)
|
||||
app.register_blueprint(routes_legal)
|
||||
# app.register_blueprint(routes_store_product)
|
||||
app.register_blueprint(routes_store)
|
||||
app.register_blueprint(routes_store_product)
|
||||
app.register_blueprint(routes_store_product_category)
|
||||
app.register_blueprint(routes_store_product_permutation)
|
||||
app.register_blueprint(routes_store_stock_item)
|
||||
|
||||
BIN
business_objects/__pycache__/base.cpython-312.pyc
Normal file
BIN
business_objects/__pycache__/base.cpython-312.pyc
Normal file
Binary file not shown.
BIN
business_objects/__pycache__/db_base.cpython-312.pyc
Normal file
BIN
business_objects/__pycache__/db_base.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
73
business_objects/db_base.py
Normal file
73
business_objects/db_base.py
Normal file
@@ -0,0 +1,73 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Database Base Business Objects
|
||||
|
||||
Description:
|
||||
Abstract business object for database objects
|
||||
"""
|
||||
|
||||
# internal
|
||||
# from helpers.DEPRECATED.helper_abc import Interface_ABC
|
||||
from extensions import db
|
||||
import lib.argument_validation as av
|
||||
# external
|
||||
from typing import ClassVar
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.ext.declarative import DeclarativeMeta
|
||||
# from flask_sqlalchemy import SQLAlchemy
|
||||
|
||||
|
||||
class Get_Many_Parameters_Base(BaseModel, metaclass=ABCMeta):
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def get_default(cls):
|
||||
pass
|
||||
@abstractmethod
|
||||
def to_json(self):
|
||||
pass
|
||||
@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):
|
||||
pass
|
||||
def to_json(self):
|
||||
pass
|
||||
@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):
|
||||
return {
|
||||
column.name: getattr(self, column.name)
|
||||
for column in self.__table__.columns
|
||||
if column.name not in excluded_attributes
|
||||
}
|
||||
BIN
business_objects/store/__pycache__/access_level.cpython-312.pyc
Normal file
BIN
business_objects/store/__pycache__/access_level.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: Business Objects
|
||||
Feature: Product Category Business Object
|
||||
|
||||
Description:
|
||||
Business object for product
|
||||
"""
|
||||
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.store_base import Store_Base
|
||||
from extensions import db
|
||||
# external
|
||||
from pydantic import BaseModel
|
||||
from typing import ClassVar
|
||||
|
||||
|
||||
class Access_Level(db.Model, Store_Base):
|
||||
__tablename__ = 'Shop_Access_Level_Temp'
|
||||
id_access_level = db.Column(db.Integer, primary_key=True)
|
||||
code = db.Column(db.String(50))
|
||||
name = db.Column(db.String(255))
|
||||
description = db.Column(db.String(4000))
|
||||
priority = db.Column(db.Integer)
|
||||
display_order = db.Column(db.Integer)
|
||||
active = db.Column(db.Boolean)
|
||||
created_on = db.Column(db.DateTime)
|
||||
created_by = db.Column(db.Integer)
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
Store_Base.__init__(self)
|
||||
def from_DB_access_level(query_row):
|
||||
access_level = Access_Level()
|
||||
access_level.id_access_level = query_row[0]
|
||||
access_level.code = query_row[1]
|
||||
access_level.name = query_row[2]
|
||||
access_level.priority = query_row[3]
|
||||
access_level.display_order = query_row[4]
|
||||
access_level.active = query_row[5]
|
||||
return access_level
|
||||
def __repr__(self):
|
||||
return f'''
|
||||
id: {self.id_access_level[0] if isinstance(self.id_access_level, tuple) else self.id_access_level}
|
||||
code: {self.code[0] if isinstance(self.code, tuple) else self.code}
|
||||
name: {self.name[0] if isinstance(self.name, tuple) else self.name}
|
||||
description: {self.description[0] if isinstance(self.description, tuple) else self.description}
|
||||
priority: {self.priority[0] if isinstance(self.priority, tuple) else self.priority}
|
||||
display_order: {self.display_order}
|
||||
active: {self.active}
|
||||
'''
|
||||
def to_json(self):
|
||||
return {
|
||||
self.ATTR_ID_ACCESS_LEVEL: self.id_access_level[0] if isinstance(self.id_access_level, tuple) else self.id_access_level,
|
||||
self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code,
|
||||
self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name,
|
||||
self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description,
|
||||
self.FLAG_PRIORITY: self.priority[0] if isinstance(self.priority, tuple) else self.priority,
|
||||
self.FLAG_DISPLAY_ORDER: self.display_order,
|
||||
self.FLAG_ACTIVE: self.active
|
||||
}
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_access_level,
|
||||
'text': self.name
|
||||
}
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
print(f'Access Level.from_json: {json}')
|
||||
access_level = cls()
|
||||
access_level.id_access_level = json[cls.ATTR_ID_ACCESS_LEVEL],
|
||||
access_level.code = json[cls.FLAG_CODE],
|
||||
access_level.name = json[cls.FLAG_NAME],
|
||||
access_level.priority = json[cls.FLAG_PRIORITY],
|
||||
access_level.description = json[cls.FLAG_DESCRIPTION],
|
||||
access_level.display_order = json[cls.FLAG_DISPLAY_ORDER]
|
||||
access_level.active = json[cls.FLAG_ACTIVE]
|
||||
return access_level
|
||||
|
||||
class Filters_Access_Level(BaseModel):
|
||||
get_inactive_access_level: bool
|
||||
def __init__(self, get_inactive_access_level = False):
|
||||
super().__init__(get_inactive_access_level = get_inactive_access_level)
|
||||
def to_json(self):
|
||||
return {
|
||||
'a_get_inactive_access_level': self.get_inactive_access_level
|
||||
}
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
filters = cls()
|
||||
filters.get_inactive_access_level = json['a_get_inactive_access_level']
|
||||
return filters
|
||||
@@ -61,8 +61,8 @@ class Basket_Item():
|
||||
basket_item.is_included_VAT = is_included_VAT
|
||||
return basket_item
|
||||
|
||||
def add_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Basket_Item.add_discount', Discount, v_arg_type='class attribute')
|
||||
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):
|
||||
|
||||
@@ -66,8 +66,8 @@ class Currency(db.Model):
|
||||
currency.display_order = query_row[5]
|
||||
return currency
|
||||
"""
|
||||
def from_DB_product(query_row):
|
||||
_m = 'Currency.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Currency.from_DB_get_many_product_catalogue'
|
||||
v_arg_type = 'class attribute'
|
||||
currency = Currency()
|
||||
currency.id_permutation = query_row[0]
|
||||
|
||||
@@ -63,7 +63,7 @@ class Delivery_Option(db.Model):
|
||||
display_order = db.Column(db.Integer)
|
||||
def __init__(self):
|
||||
self.delivery_regions = []
|
||||
def from_DB_product(query_row):
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
option = Delivery_Option()
|
||||
option.id_option = query_row[0]
|
||||
option.id_product = query_row[1]
|
||||
|
||||
@@ -59,7 +59,7 @@ class Delivery_Region(db.Model):
|
||||
self.code = code
|
||||
self.display_order = display_order
|
||||
"""
|
||||
def from_DB_product(query_row):
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
region = Delivery_Region()
|
||||
region.id_region = query_row[0]
|
||||
region.name = query_row[1]
|
||||
|
||||
@@ -37,7 +37,7 @@ class Discount(db.Model):
|
||||
|
||||
def __init__(self):
|
||||
self.delivery_regions = []
|
||||
def from_DB_product(query_row):
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
discount = Discount()
|
||||
discount.id_discount = query_row[0]
|
||||
discount.id_category = query_row[1]
|
||||
|
||||
@@ -73,8 +73,8 @@ class Image(db.Model):
|
||||
self.display_order = display_order
|
||||
super().__init__()
|
||||
"""
|
||||
def from_DB_product(query_row):
|
||||
_m = 'Image.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Image.from_DB_get_many_product_catalogue'
|
||||
# print(f'image: {query_row}')
|
||||
image = Image()
|
||||
image.id_image = query_row[0]
|
||||
|
||||
@@ -14,6 +14,7 @@ Business object for product
|
||||
import lib.argument_validation as av
|
||||
from lib import data_types
|
||||
from forms.forms import Form_Basket_Add, Form_Basket_Edit, Form_Filters_Permutation
|
||||
from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base
|
||||
from business_objects.store.delivery_option import Delivery_Option
|
||||
from business_objects.store.discount import Discount
|
||||
from business_objects.store.image import Image
|
||||
@@ -24,6 +25,7 @@ from business_objects.store.stock_item import Stock_Item
|
||||
from business_objects.store.product_variation import Product_Variation
|
||||
from business_objects.store.product_variation_tree import Product_Variation_Tree
|
||||
from extensions import db
|
||||
from forms.store.product import Form_Filters_Product
|
||||
# external
|
||||
from dataclasses import dataclass
|
||||
from typing import ClassVar, List
|
||||
@@ -49,7 +51,7 @@ class Enum_Status_Stock(Enum):
|
||||
return data_types.get_enum_member_by_text(Enum_Status_Stock, text.upper())
|
||||
|
||||
"""
|
||||
class Product(db.Model, Store_Base):
|
||||
class Product(SQLAlchemy_ABC, Store_Base):
|
||||
FLAG_NAME: ClassVar[str] = 'name-product'
|
||||
FLAG_DISPLAY_ORDER: ClassVar[str] = 'display-order-product'
|
||||
FLAG_CAN_VIEW: ClassVar[str] = 'can-view-product'
|
||||
@@ -83,9 +85,10 @@ class Product(db.Model, Store_Base):
|
||||
Store_Base.__init__(self)
|
||||
self.form_basket_add = Form_Basket_Add()
|
||||
self.form_basket_edit = Form_Basket_Edit()
|
||||
self.name_access_level_required = None
|
||||
|
||||
def from_DB_product(query_row):
|
||||
_m = 'Product.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Product.from_DB_get_many_product_catalogue'
|
||||
v_arg_type = 'class attribute'
|
||||
product = Product()
|
||||
product.id_product = query_row[0]
|
||||
@@ -93,11 +96,12 @@ class Product(db.Model, Store_Base):
|
||||
product.name = query_row[2]
|
||||
product.has_variations = av.input_bool(query_row[3], "has_variations", _m, v_arg_type=v_arg_type)
|
||||
product.id_access_level_required = query_row[4]
|
||||
product.active = av.input_bool(query_row[5], "active", _m, v_arg_type=v_arg_type)
|
||||
product.display_order = query_row[6]
|
||||
product.can_view = av.input_bool(query_row[7], "can_view", _m, v_arg_type=v_arg_type)
|
||||
product.can_edit = av.input_bool(query_row[8], "can_edit", _m, v_arg_type=v_arg_type)
|
||||
product.can_admin = av.input_bool(query_row[9], "can_admin", _m, v_arg_type=v_arg_type)
|
||||
product.name_access_level_required = query_row[5]
|
||||
product.active = av.input_bool(query_row[6], "active", _m, v_arg_type=v_arg_type)
|
||||
product.display_order = query_row[7]
|
||||
product.can_view = av.input_bool(query_row[8], "can_view", _m, v_arg_type=v_arg_type)
|
||||
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):
|
||||
@@ -117,8 +121,8 @@ class Product(db.Model, Store_Base):
|
||||
# product.get_variation_trees()
|
||||
return product
|
||||
"""
|
||||
def add_permutation(self, permutation):
|
||||
_m = 'Product.add_permutation'
|
||||
def add_product_permutation(self, permutation):
|
||||
_m = 'Product.add_product_permutation'
|
||||
av.val_instance(permutation, 'permutation', _m, Product_Permutation)
|
||||
try:
|
||||
self.permutation_index[permutation.id_permutation]
|
||||
@@ -159,7 +163,8 @@ class Product(db.Model, Store_Base):
|
||||
def get_variation_trees(self):
|
||||
self.variation_trees = []
|
||||
for index_permutation in range(len(self.permutations)):
|
||||
variation_tree = Product_Variation_Tree.from_product_permutation(self.permutations[index_permutation])
|
||||
permutation = self.permutations[index_permutation]
|
||||
variation_tree = permutation.variation_tree # Product_Variation_Tree.from_product_permutation(permutation)
|
||||
found_variation_tree_match = False
|
||||
for index_tree in range(len(self.variation_trees)):
|
||||
if self.variation_trees[index_tree].is_equal(variation_tree):
|
||||
@@ -245,27 +250,27 @@ class Product(db.Model, Store_Base):
|
||||
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_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product.add_variation', Product_Variation)
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product.add_product_variation', Product_Variation)
|
||||
# print(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_variation(variation)
|
||||
def add_price(self, price):
|
||||
av.val_instance(price, 'price', 'Product.add_price', Product_Price)
|
||||
self.permutations[index_permutation].add_product_variation(variation)
|
||||
def add_product_price(self, price):
|
||||
av.val_instance(price, 'price', 'Product.add_product_price', Product_Price)
|
||||
index_permutation = self.permutation_index[price.id_permutation] # self.get_index_permutation_from_id(price.id_permutation)
|
||||
self.permutations[index_permutation].add_price(price)
|
||||
def add_image(self, image):
|
||||
av.val_instance(image, 'image', 'Product.add_image', Image)
|
||||
self.permutations[index_permutation].add_product_price(price)
|
||||
def add_product_image(self, image):
|
||||
av.val_instance(image, 'image', 'Product.add_product_image', Image)
|
||||
index_permutation = self.permutation_index[image.id_permutation] # self.get_index_permutation_from_id(image.id_permutation)
|
||||
self.permutations[index_permutation].add_image(image)
|
||||
self.permutations[index_permutation].add_product_image(image)
|
||||
def add_delivery_option(self, delivery_option):
|
||||
av.val_instance(delivery_option, 'delivery_option', 'Product.add_delivery_option', Delivery_Option)
|
||||
index_permutation = self.permutation_index[delivery_option.id_permutation] # self.get_index_permutation_from_id(delivery_option.id_permutation)
|
||||
self.permutations[index_permutation].add_delivery_option(delivery_option)
|
||||
def add_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Product.add_discount', Discount)
|
||||
def add_product_price_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Product.add_product_price_discount', Discount)
|
||||
index_permutation = self.permutation_index[discount.id_permutation] # self.get_index_permutation_from_id(discount.id_permutation)
|
||||
self.permutations[index_permutation].add_discount(discount)
|
||||
self.permutations[index_permutation].add_product_price_discount(discount)
|
||||
def add_stock_item(self, stock_item):
|
||||
av.val_instance(stock_item, 'stock_item', 'Product.add_stock_item', Stock_Item)
|
||||
index_permutation = self.permutation_index[stock_item.id_permutation]
|
||||
@@ -279,7 +284,7 @@ class Product(db.Model, Store_Base):
|
||||
if permutation.is_available():
|
||||
return True
|
||||
return False
|
||||
def to_list_rows_permutation(self):
|
||||
def to_permutation_row_list(self):
|
||||
list_rows = []
|
||||
for permutation in self.permutations:
|
||||
list_rows.append(permutation.to_row_permutation())
|
||||
@@ -317,6 +322,35 @@ class Product(db.Model, Store_Base):
|
||||
self.ATTR_ID_PRODUCT_PERMUTATION: [permutation.to_json() for permutation in self.permutations],
|
||||
self.FLAG_VARIATION_TREES: [tree.to_json() for tree in self.variation_trees]
|
||||
}
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_product,
|
||||
'text': self.name
|
||||
}
|
||||
def get_variation_types_unique(self):
|
||||
list_types = []
|
||||
for tree in self.variation_trees:
|
||||
for type in tree.get_types_unique():
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class Filters_Product():
|
||||
@@ -386,7 +420,44 @@ class Filters_Product():
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def from_form(form):
|
||||
def from_form_filters_product(form):
|
||||
# if not (form is Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Filters_Product.from_form', 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", "Filters_Product.from_form_filters_product")
|
||||
active = av.input_bool(form.active.data, "active", "Filters_Product.from_form_filters_product")
|
||||
return Filters_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,
|
||||
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 Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Permutation)
|
||||
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '')
|
||||
@@ -494,7 +565,7 @@ class Filters_Product():
|
||||
def from_filters_product_category(cls, filters_category):
|
||||
return cls(
|
||||
get_all_product_category = True,
|
||||
get_inactive_product_category = filters_category.active_only,
|
||||
get_inactive_product_category = filters_category.active,
|
||||
ids_product_category = '',
|
||||
get_all_product = True,
|
||||
get_inactive_product = False,
|
||||
@@ -506,4 +577,234 @@ class Filters_Product():
|
||||
get_inactive_image = False,
|
||||
ids_image = '',
|
||||
get_products_quantity_stock_below_min = False
|
||||
)
|
||||
|
||||
|
||||
class Filters_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, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
'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 Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Filters_Product.from_form', 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", "Filters_Product.from_form_filters_product")
|
||||
active = av.input_bool(form.active.data, "active", "Filters_Product.from_form_filters_product")
|
||||
return Filters_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,
|
||||
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 Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
|
||||
av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Permutation)
|
||||
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '')
|
||||
has_product_filter = not (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", "Filters_Product.from_form")
|
||||
print(f'form question: {type(form.is_out_of_stock)}\nbool interpretted: {get_permutations_stock_below_min}\type form: {type(form)}')
|
||||
return Filters_Product(
|
||||
get_all_product_category = not has_category_filter,
|
||||
get_inactive_product_category = False,
|
||||
# get_first_product_category_only = False,
|
||||
ids_product_category = form.id_category.data,
|
||||
get_all_product = not has_product_filter,
|
||||
get_inactive_product = False,
|
||||
# get_first_product_only = False,
|
||||
ids_product = form.id_product.data,
|
||||
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
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def get_default():
|
||||
return Filters_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
|
||||
)
|
||||
|
||||
@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
|
||||
)
|
||||
@@ -12,6 +12,7 @@ Business object for product category
|
||||
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base
|
||||
from business_objects.store.product import Product, Product_Permutation, Product_Price
|
||||
from business_objects.store.product_variation import Product_Variation
|
||||
from business_objects.store.image import Image
|
||||
@@ -24,36 +25,16 @@ from extensions import db
|
||||
from pydantic import BaseModel
|
||||
from typing import ClassVar
|
||||
|
||||
"""
|
||||
class Enum_Product_Category(Enum):
|
||||
ASSISTIVE_DEVICES = 0
|
||||
HOME_DECOR = 1
|
||||
MISCELLANEOUS = 99
|
||||
|
||||
def text(self):
|
||||
return Enum_Product_Category.Enum_Product_Category_Text(self)
|
||||
|
||||
def Enum_Product_Category_Text(category):
|
||||
av.val_instance(category, 'category', 'Product_Category_Enum_Text', Enum_Product_Category)
|
||||
if category == Enum_Product_Category.ASSISTIVE_DEVICES:
|
||||
return 'Assistive devices'
|
||||
elif category == Enum_Product_Category.HOME_DECOR:
|
||||
return 'Home decor'
|
||||
else:
|
||||
return 'Other'
|
||||
|
||||
def get_member_by_text(text):
|
||||
av.val_str(text, 'text', 'Enum_Product_Category.get_member_by_text')
|
||||
return data_types.get_enum_member_by_text(Enum_Product_Category, text.upper())
|
||||
"""
|
||||
|
||||
class Product_Category(db.Model, Store_Base):
|
||||
class Product_Category(SQLAlchemy_ABC, Store_Base):
|
||||
FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'id_access_level_required'
|
||||
__tablename__ = 'Shop_Product_Category_Temp'
|
||||
id_category = db.Column(db.Integer, primary_key=True)
|
||||
code = db.Column(db.String(50))
|
||||
name = db.Column(db.String(255))
|
||||
description = db.Column(db.String(4000))
|
||||
id_access_level_required = db.Column(db.Integer)
|
||||
name_access_level_required = db.Column(db.String(255))
|
||||
display_order = db.Column(db.Integer)
|
||||
active = db.Column(db.Boolean)
|
||||
can_view = db.Column(db.Boolean)
|
||||
@@ -61,39 +42,25 @@ class Product_Category(db.Model, Store_Base):
|
||||
can_admin = db.Column(db.Boolean)
|
||||
created_on = db.Column(db.DateTime)
|
||||
created_by = db.Column(db.Integer)
|
||||
"""
|
||||
def __new__(cls, id, name, description, display_order):
|
||||
_m = 'Category.__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=4001, v_arg_type=v_arg_type)
|
||||
av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type)
|
||||
return super(Category, cls).__new__(cls)
|
||||
"""
|
||||
def __init__(self): # , id, name, description, display_order):
|
||||
"""
|
||||
self.id_category = id
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.display_order = display_order
|
||||
"""
|
||||
def __init__(self):
|
||||
self.products = []
|
||||
self.product_index = {}
|
||||
super().__init__()
|
||||
Store_Base.__init__(self)
|
||||
def from_DB_product(query_row):
|
||||
self.name_access_level_required = None
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
category = Product_Category()
|
||||
category.id_category = query_row[0]
|
||||
category.code = query_row[1]
|
||||
category.name = query_row[2]
|
||||
category.description = query_row[3]
|
||||
category.id_access_level_required = query_row[4]
|
||||
category.display_order = query_row[5]
|
||||
category.active = query_row[6]
|
||||
category.can_view = query_row[7]
|
||||
category.can_edit = query_row[8]
|
||||
category.can_admin = query_row[9]
|
||||
category.name_access_level_required = query_row[5]
|
||||
category.display_order = query_row[6]
|
||||
category.active = query_row[7]
|
||||
category.can_view = query_row[8]
|
||||
category.can_edit = query_row[9]
|
||||
category.can_admin = query_row[10]
|
||||
return category
|
||||
"""
|
||||
def key_product_index_from_ids_product_permutation(id_product, id_permutation):
|
||||
@@ -128,39 +95,39 @@ class Product_Category(db.Model, Store_Base):
|
||||
except KeyError:
|
||||
self.product_index[product.id_product] = len(self.products)
|
||||
self.products.append(product)
|
||||
def add_permutation(self, permutation):
|
||||
_m = 'Category.add_permutation'
|
||||
def add_product_permutation(self, permutation):
|
||||
_m = 'Category.add_product_permutation'
|
||||
av.val_instance(permutation, 'permutation', _m, Product_Permutation)
|
||||
# self.product_index.append(len(self.products))
|
||||
# self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products)
|
||||
index_product = self.get_index_product_from_id(permutation.id_product)
|
||||
# index_product = self.product_index[permutation.id_product]
|
||||
self.products[index_product].add_permutation(permutation)
|
||||
def add_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Category.add_variation', Product_Variation)
|
||||
self.products[index_product].add_product_permutation(permutation)
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Category.add_product_variation', Product_Variation)
|
||||
index_product = self.get_index_product_from_id(variation.id_product)
|
||||
self.products[index_product].add_variation(variation)
|
||||
def add_price(self, price):
|
||||
av.val_instance(price, 'price', 'Category.add_price', Product_Price)
|
||||
self.products[index_product].add_product_variation(variation)
|
||||
def add_product_price(self, price):
|
||||
av.val_instance(price, 'price', 'Category.add_product_price', Product_Price)
|
||||
index_product = self.get_index_product_from_id(price.id_product)
|
||||
self.products[index_product].add_price(price)
|
||||
def add_image(self, image):
|
||||
av.val_instance(image, 'image', 'Category.add_image', Image)
|
||||
self.products[index_product].add_product_price(price)
|
||||
def add_product_image(self, image):
|
||||
av.val_instance(image, 'image', 'Category.add_product_image', Image)
|
||||
index_product = self.get_index_product_from_id(image.id_product)
|
||||
self.products[index_product].add_image(image)
|
||||
self.products[index_product].add_product_image(image)
|
||||
def add_delivery_option(self, delivery_option):
|
||||
av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option)
|
||||
index_product = self.get_index_product_from_id(delivery_option.id_product)
|
||||
self.products[index_product].add_delivery_option(delivery_option)
|
||||
def add_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Category.add_discount', Discount)
|
||||
def add_product_price_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Category.add_product_price_discount', Discount)
|
||||
index_product = self.get_index_product_from_id(discount.id_product)
|
||||
self.products[index_product].add_discount(discount)
|
||||
self.products[index_product].add_product_price_discount(discount)
|
||||
def add_stock_item(self, stock_item):
|
||||
av.val_instance(stock_item, 'stock_item', 'Category.add_stock_item', Stock_Item)
|
||||
index_product = self.get_index_product_from_id(stock_item.id_product)
|
||||
self.products[index_product].add_stock_item(stock_item)
|
||||
def get_all_variation_trees(self):
|
||||
def get_all_product_variation_trees(self):
|
||||
for product in self.products:
|
||||
if product.has_variations:
|
||||
print(f'product with id:{product.id_product} has variations')
|
||||
@@ -181,14 +148,17 @@ class Product_Category(db.Model, Store_Base):
|
||||
code: {self.code[0] if isinstance(self.code, tuple) else self.code}
|
||||
name: {self.name[0] if isinstance(self.name, tuple) else self.name}
|
||||
description: {self.description[0] if isinstance(self.description, tuple) else self.description}
|
||||
access_level: {self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required}
|
||||
display_order: {self.display_order}
|
||||
active: {self.active}
|
||||
products: {self.products}
|
||||
'''
|
||||
"""
|
||||
def get_permutation_first(self):
|
||||
if not (len(self.products) == 0):
|
||||
print(f'getting first permutation from product')
|
||||
return None if len(self.products) == 0 else self.products[0].get_permutation_selected()
|
||||
"""
|
||||
def is_available(self):
|
||||
if len(self.products) == 0:
|
||||
return False
|
||||
@@ -196,22 +166,25 @@ class Product_Category(db.Model, Store_Base):
|
||||
if product.is_available():
|
||||
return True
|
||||
return False
|
||||
def to_list_rows_permutation(self):
|
||||
def to_permutation_row_list(self):
|
||||
list_rows = []
|
||||
for product in self.products:
|
||||
list_rows += product.to_list_rows_permutation()
|
||||
list_rows += product.to_permutation_row_list()
|
||||
return list_rows
|
||||
def to_list_products(self):
|
||||
def to_product_option_list(self):
|
||||
list_products = []
|
||||
for product in self.products:
|
||||
list_products.append({'value': product.id_product, 'text': product.name})
|
||||
return list_products
|
||||
def to_json(self):
|
||||
return {
|
||||
self.FLAG_KEY_PRIMARY: self.ATTR_ID_PRODUCT_CATEGORY,
|
||||
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category[0] if isinstance(self.id_category, tuple) else self.id_category,
|
||||
self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code,
|
||||
self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name,
|
||||
self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description,
|
||||
self.ATTR_ID_ACCESS_LEVEL: self.id_access_level_required[0] if isinstance(self.id_access_level_required, tuple) else self.id_access_level_required,
|
||||
self.FLAG_ACCESS_LEVEL_REQUIRED: self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required,
|
||||
self.FLAG_DISPLAY_ORDER: self.display_order,
|
||||
self.FLAG_ACTIVE: self.active,
|
||||
self.FLAG_CAN_VIEW: self.can_view,
|
||||
@@ -222,31 +195,42 @@ class Product_Category(db.Model, Store_Base):
|
||||
def from_json(cls, json):
|
||||
print(f' Category.from_json: {json}')
|
||||
category = cls()
|
||||
category.id_category = json.get(cls.ATTR_ID_PRODUCT_CATEGORY),
|
||||
category.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY],
|
||||
category.code = json[cls.FLAG_CODE],
|
||||
category.name = json[cls.FLAG_NAME],
|
||||
category.description = json[cls.FLAG_DESCRIPTION],
|
||||
category.id_access_level_required = json[cls.ATTR_ID_ACCESS_LEVEL],
|
||||
category.name_access_level_required = json.get(cls.FLAG_ACCESS_LEVEL_REQUIRED, ''),
|
||||
category.display_order = json[cls.FLAG_DISPLAY_ORDER]
|
||||
category.active = json[cls.FLAG_ACTIVE]
|
||||
category.can_view = json.get(cls.FLAG_CAN_VIEW, False)
|
||||
category.can_edit = json.get(cls.FLAG_CAN_EDIT, False)
|
||||
category.can_admin = json.get(cls.FLAG_CAN_ADMIN, False)
|
||||
return category
|
||||
"""
|
||||
def to_json_str(self):
|
||||
return {
|
||||
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category[0] if isinstance(self.id_category, tuple) else self.id_category,
|
||||
self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code,
|
||||
self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name,
|
||||
self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description,
|
||||
self.ATTR_ID_ACCESS_LEVEL: self.id_access_level_required[0] if isinstance(self.id_access_level_required, tuple) else self.id_access_level_required,
|
||||
self.FLAG_ACCESS_LEVEL_REQUIRED: self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required,
|
||||
self.FLAG_DISPLAY_ORDER: self.display_order,
|
||||
self.FLAG_ACTIVE: self.output_bool(self.active),
|
||||
self.FLAG_CAN_VIEW: self.output_bool(self.can_view),
|
||||
self.FLAG_CAN_EDIT: self.output_bool(self.can_edit),
|
||||
self.FLAG_CAN_ADMIN: self.output_bool(self.can_admin)
|
||||
}
|
||||
"""
|
||||
@staticmethod
|
||||
def output_bool(value):
|
||||
return av.input_bool(value, 'Product_Category bool attribute', 'Product_Category.output_bool')
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_category,
|
||||
'text': self.name
|
||||
}
|
||||
"""
|
||||
class Filters_Product_Category(BaseModel, Store_Base):
|
||||
ids_product_category: str
|
||||
@@ -284,42 +268,45 @@ class Filters_Product_Category(BaseModel, Store_Base):
|
||||
filters = cls()
|
||||
filters.ids_product_category = json['a_ids_product_category'],
|
||||
filters.ids_product = json['a_ids_product']
|
||||
"""
|
||||
class Filters_Product_Category(BaseModel, Store_Base):
|
||||
is_not_empty_only: bool
|
||||
active_only: bool
|
||||
def __init__(self, is_not_empty_only, active_only):
|
||||
super().__init__(is_not_empty_only=is_not_empty_only, active_only=active_only)
|
||||
|
||||
|
||||
class Filters_Product_Category(Get_Many_Parameters_Base):
|
||||
FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is_not_empty'
|
||||
is_not_empty: bool
|
||||
active: bool
|
||||
def __init__(self, is_not_empty, active):
|
||||
super().__init__(is_not_empty=is_not_empty, active=active)
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
return cls(
|
||||
is_not_empty_only = False,
|
||||
active_only = True
|
||||
is_not_empty = False,
|
||||
active = True
|
||||
)
|
||||
def to_json(self):
|
||||
return {
|
||||
'is_not_empty_only': self.is_not_empty_only,
|
||||
'active_only': self.active_only
|
||||
self.FLAG_IS_NOT_EMPTY: self.is_not_empty,
|
||||
self.FLAG_ACTIVE: self.active
|
||||
}
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
return cls(
|
||||
is_not_empty_only = json['is_not_empty_only'],
|
||||
active_only = json['active_only']
|
||||
is_not_empty = json['is_not_empty'],
|
||||
active = json['active']
|
||||
)
|
||||
@classmethod
|
||||
def from_form(cls, form):
|
||||
return cls(
|
||||
is_not_empty_only = av.input_bool(form.is_not_empty.data, 'is_not_empty', 'Filters_Product_Category.from_form'),
|
||||
active_only = av.input_bool(form.active.data, 'active', 'Filters_Product_Category.from_form')
|
||||
is_not_empty = av.input_bool(form.is_not_empty.data, 'is_not_empty', 'Filters_Product_Category.from_form'),
|
||||
active = av.input_bool(form.active.data, 'active', 'Filters_Product_Category.from_form')
|
||||
)
|
||||
"""
|
||||
|
||||
class Container_Product_Category(Store_Base):
|
||||
class Product_Category_Container(Store_Base):
|
||||
categories: list
|
||||
def __init__(self):
|
||||
self.categories = []
|
||||
def add_category(self, category):
|
||||
av.val_instance(category, 'category', 'Container_Product_Categories.add_category', Product_Category)
|
||||
def add_product_category(self, category):
|
||||
av.val_instance(category, 'category', 'Container_Product_Categories.add_product_category', Product_Category)
|
||||
self.categories.append(category)
|
||||
def get_index_category_from_id(self, id_category):
|
||||
for index_category in range(len(self.categories)):
|
||||
@@ -340,73 +327,89 @@ class Container_Product_Category(Store_Base):
|
||||
av.val_instance(product, 'product', 'Container_Product_Categories.add_product', Product)
|
||||
index_category = self.get_index_category_from_id(product.id_category)
|
||||
self.categories[index_category].add_product(product)
|
||||
def add_permutation(self, permutation):
|
||||
av.val_instance(permutation, 'permutation', 'Container_Product_Categories.add_permutation', Product_Permutation)
|
||||
def add_product_permutation(self, permutation):
|
||||
av.val_instance(permutation, 'permutation', 'Container_Product_Categories.add_product_permutation', Product_Permutation)
|
||||
index_category = self.get_index_category_from_id(permutation.id_category)
|
||||
self.categories[index_category].add_permutation(permutation)
|
||||
def add_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Container_Product_Categories.add_variation', Product_Variation)
|
||||
self.categories[index_category].add_product_permutation(permutation)
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Container_Product_Categories.add_product_variation', Product_Variation)
|
||||
index_category = self.get_index_category_from_id(variation.id_category)
|
||||
self.categories[index_category].add_variation(variation)
|
||||
def add_price(self, price):
|
||||
av.val_instance(price, 'price', 'Container_Product_Categories.add_price', Product_Price)
|
||||
self.categories[index_category].add_product_variation(variation)
|
||||
def add_product_price(self, price):
|
||||
av.val_instance(price, 'price', 'Container_Product_Categories.add_product_price', Product_Price)
|
||||
index_category = self.get_index_category_from_id(price.id_category)
|
||||
self.categories[index_category].add_price(price)
|
||||
def add_image(self, image):
|
||||
av.val_instance(image, 'image', 'Container_Product_Categories.add_image', Image)
|
||||
self.categories[index_category].add_product_price(price)
|
||||
def add_product_image(self, image):
|
||||
av.val_instance(image, 'image', 'Container_Product_Categories.add_product_image', Image)
|
||||
index_category = self.get_index_category_from_id(image.id_category)
|
||||
self.categories[index_category].add_image(image)
|
||||
self.categories[index_category].add_product_image(image)
|
||||
def add_delivery_option(self, delivery_option):
|
||||
av.val_instance(delivery_option, 'delivery_option', 'Container_Product_Categories.add_delivery_option', Delivery_Option)
|
||||
index_category = self.get_index_category_from_id(delivery_option.id_category)
|
||||
self.categories[index_category].add_delivery_option(delivery_option)
|
||||
def add_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Container_Product_Categories.add_discount', Discount)
|
||||
def add_product_price_discount(self, discount):
|
||||
av.val_instance(discount, 'discount', 'Container_Product_Categories.add_product_price_discount', Discount)
|
||||
index_category = self.get_index_category_from_id(discount.id_category)
|
||||
self.categories[index_category].add_discount(discount)
|
||||
self.categories[index_category].add_product_price_discount(discount)
|
||||
def add_stock_item(self, stock_item):
|
||||
av.val_instance(stock_item, 'stock_item', 'Container_Product_Categories.add_stock_item', Stock_Item)
|
||||
index_category = self.get_index_category_from_id(stock_item.id_category)
|
||||
self.categories[index_category].add_stock_item(stock_item)
|
||||
def get_all_variation_trees(self):
|
||||
def get_all_product_variation_trees(self):
|
||||
for category in self.categories:
|
||||
category.get_all_variation_trees()
|
||||
category.get_all_product_variation_trees()
|
||||
def __repr__(self):
|
||||
return f'categories: {self.categories}'
|
||||
"""
|
||||
def get_permutation_first(self):
|
||||
print(f'getting first permutation from category list')
|
||||
if not (len(self.categories) == 0):
|
||||
print(f'getting first permutation from category')
|
||||
return None if len(self.categories) == 0 else self.categories[0].get_permutation_first()
|
||||
def get_count_categories(self):
|
||||
"""
|
||||
def get_category_count(self):
|
||||
return len(self.categories)
|
||||
def to_list_rows_permutation(self):
|
||||
def to_permutation_row_list(self):
|
||||
list_rows = []
|
||||
for category in self.categories:
|
||||
list_rows += category.to_list_rows_permutation()
|
||||
list_rows += category.to_permutation_row_list()
|
||||
return list_rows
|
||||
def to_list_category_options(self):
|
||||
def to_category_option_list(self):
|
||||
list_categories = []
|
||||
for category in self.categories:
|
||||
list_categories.append({'value': category.id_category, 'text': category.name})
|
||||
return list_categories
|
||||
def to_list_products(self):
|
||||
def to_product_option_list(self):
|
||||
list_products = []
|
||||
for category in self.categories:
|
||||
# list_products.append(category.to_list_products())
|
||||
# list_products.append(category.to_product_option_list())
|
||||
for product in category.products:
|
||||
list_products.append({'value': product.id_product, 'text': product.name, Product.ATTR_ID_PRODUCT_CATEGORY: product.id_category})
|
||||
return list_products
|
||||
def to_dict_lists_products(self):
|
||||
def get_product_option_lists_by_category(self):
|
||||
dict_lists_products = {}
|
||||
for category in self.categories:
|
||||
dict_lists_products[category.id_category] = category.to_list_products()
|
||||
dict_lists_products[category.id_category] = category.to_product_option_list()
|
||||
return dict_lists_products
|
||||
def to_json(self):
|
||||
return {
|
||||
'categories': [category.to_json() for category in self.categories]
|
||||
f'{self.FLAG_ROWS}': [category.to_json() for category in self.categories]
|
||||
}
|
||||
"""
|
||||
def to_json_str(self):
|
||||
return {
|
||||
'categories': [category.to_json_str() for category in self.categories]
|
||||
}
|
||||
f'{self.FLAG_ROWS}': [category.to_json_str() for category in self.categories]
|
||||
}
|
||||
"""
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
return None
|
||||
def to_json_option(self):
|
||||
return None
|
||||
def to_temporary_record(self):
|
||||
excluded_attributes = {
|
||||
column.name: getattr(self, column.name)
|
||||
for column in self.__table__.columns
|
||||
if column.name not in ['created_on', 'created_by']
|
||||
}
|
||||
return self.to_object_with_missing_attributes(excluded_attributes)
|
||||
@@ -21,6 +21,7 @@ from business_objects.store.product_price import Product_Price
|
||||
from business_objects.store.stock_item import Stock_Item
|
||||
from business_objects.store.store_base import Store_Base
|
||||
from business_objects.store.product_variation import Product_Variation
|
||||
from business_objects.store.product_variation_tree import Product_Variation_Tree
|
||||
from extensions import db
|
||||
# external
|
||||
from datetime import datetime, timedelta
|
||||
@@ -64,6 +65,7 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
# form_basket_edit: Form_Basket_Edit
|
||||
# is_unavailable_in_currency_or_region: bool
|
||||
# is_available: bool
|
||||
# variation_tree
|
||||
|
||||
def __init__(self):
|
||||
self.variations = []
|
||||
@@ -84,9 +86,10 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
self.form_basket_edit = Form_Basket_Edit()
|
||||
self.is_unavailable_in_currency_or_region = False
|
||||
# self.is_available = False
|
||||
self.variation_tree = None
|
||||
|
||||
def from_DB_product(query_row):
|
||||
_m = 'Product_Permutation.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Product_Permutation.from_DB_get_many_product_catalogue'
|
||||
v_arg_type = 'class attribute'
|
||||
print(f'query_row: {query_row}')
|
||||
permutation = Product_Permutation()
|
||||
@@ -155,7 +158,7 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
if permutation.has_variations:
|
||||
for jsonProductVariation in json[cls.ATTR_ID_PRODUCT_VARIATION]:
|
||||
variation = Product_Variation.from_json(jsonProductVariation)
|
||||
permutation.add_variation(variation)
|
||||
permutation.add_product_variation(variation)
|
||||
permutation.quantity_stock = json[cls.FLAG_QUANTITY_STOCK]
|
||||
permutation.quantity_min = json[cls.FLAG_QUANTITY_MIN]
|
||||
permutation.quantity_max = json[cls.FLAG_QUANTITY_MAX]
|
||||
@@ -185,6 +188,13 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
'delivery_options': {self.delivery_options},
|
||||
'prices': {self.prices}
|
||||
}
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_permutation,
|
||||
'text': self.get_name_variations()
|
||||
}
|
||||
def get_name_variations(self):
|
||||
return self.variation_tree.get_name_variations()
|
||||
def is_available(self):
|
||||
return len(self.prices) > 0
|
||||
def get_price(self):
|
||||
@@ -270,8 +280,9 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
price_GBP_min: {self.price_GBP_min}
|
||||
"""
|
||||
|
||||
def add_variation(self, variation):
|
||||
_m = 'Product_Permutation.add_variation'
|
||||
def add_product_variation(self, variation):
|
||||
_m = 'Product_Permutation.add_product_variation'
|
||||
"""
|
||||
av.val_instance(variation, 'variation', _m, Product_Variation)
|
||||
try:
|
||||
self.variation_index[variation.id_variation]
|
||||
@@ -279,8 +290,13 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
except KeyError:
|
||||
self.variation_index[variation.id_variation] = len(self.variations)
|
||||
self.variations.append(variation)
|
||||
def add_price(self, price):
|
||||
_m = 'Product_Permutation.add_price'
|
||||
"""
|
||||
if self.variation_tree is None:
|
||||
self.variation_tree = Product_Variation_Tree.from_product_variation(variation)
|
||||
else:
|
||||
self.variation_tree.add_product_variation(variation)
|
||||
def add_product_price(self, price):
|
||||
_m = 'Product_Permutation.add_product_price'
|
||||
av.val_instance(price, 'price', _m, Product_Price)
|
||||
try:
|
||||
self.price_index[price.display_order]
|
||||
@@ -288,8 +304,8 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
except KeyError:
|
||||
self.price_index[price.display_order] = len(self.prices)
|
||||
self.prices.append(price)
|
||||
def add_image(self, image):
|
||||
_m = 'Product_Permutation.add_image'
|
||||
def add_product_image(self, image):
|
||||
_m = 'Product_Permutation.add_product_image'
|
||||
av.val_instance(image, 'image', _m, Image)
|
||||
try:
|
||||
self.image_index[image.id_image]
|
||||
@@ -306,8 +322,8 @@ class Product_Permutation(db.Model, Store_Base):
|
||||
except KeyError:
|
||||
self.delivery_option_index[delivery_option.id_option] = len(self.delivery_options)
|
||||
self.delivery_options.append(delivery_option)
|
||||
def add_discount(self, discount):
|
||||
_m = 'Product_Permutation.add_discount'
|
||||
def add_product_price_discount(self, discount):
|
||||
_m = 'Product_Permutation.add_product_price_discount'
|
||||
av.val_instance(discount, 'discount', _m, Discount)
|
||||
try:
|
||||
self.discount_index[discount.display_order]
|
||||
@@ -352,8 +368,8 @@ class Permutation_Product_Variation_Link(db.Model):
|
||||
id_category = db.Column(db.Integer)
|
||||
id_variation = db.Column(db.Integer)
|
||||
|
||||
def from_DB_product(query_row):
|
||||
_m = 'Permutation_Product_Variation_Link.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
_m = 'Permutation_Product_Variation_Link.from_DB_get_many_product_catalogue'
|
||||
v_arg_type = 'class attribute'
|
||||
link = Permutation_Product_Variation_Link()
|
||||
link.id_permutation = query_row[0]
|
||||
|
||||
@@ -42,8 +42,8 @@ class Product_Price(db.Model, Store_Base):
|
||||
super().__init__()
|
||||
Store_Base.__init__(self)
|
||||
|
||||
def from_DB_product(query_row):
|
||||
# _m = 'Product_Price.from_DB_product'
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
# _m = 'Product_Price.from_DB_get_many_product_catalogue'
|
||||
price = Product_Price()
|
||||
price.id_price = query_row[0]
|
||||
price.id_permutation = query_row[1]
|
||||
@@ -90,6 +90,11 @@ class Product_Price(db.Model, Store_Base):
|
||||
self.FLAG_VALUE_LOCAL_VAT_EXCL: {self.value_local_VAT_excl},
|
||||
self.FLAG_DISPLAY_ORDER: {self.display_order}
|
||||
}
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_price,
|
||||
'text': f'{self.symbol_currency} {self.value_local_VAT_incl}'
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
|
||||
@@ -56,7 +56,7 @@ class Product_Variation(db.Model, Store_Base):
|
||||
super().__init__()
|
||||
Store_Base.__init__(self)
|
||||
|
||||
def from_DB_product(query_row):
|
||||
def from_DB_get_many_product_catalogue(query_row):
|
||||
variation = Product_Variation.from_DB_variation(query_row)
|
||||
variation.id_product = query_row[11]
|
||||
variation.id_permutation = query_row[12]
|
||||
@@ -122,6 +122,11 @@ class Product_Variation(db.Model, Store_Base):
|
||||
self.KEY_ACTIVE_VARIATION_TYPE: self.active_variation_type,
|
||||
self.KEY_ACTIVE_VARIATION: self.active_variation,
|
||||
}
|
||||
def to_json_option(self):
|
||||
return {
|
||||
'value': self.id_variation,
|
||||
'text': self.name_variation
|
||||
}
|
||||
|
||||
def to_json_variation_type(self):
|
||||
return {
|
||||
@@ -159,7 +164,7 @@ class Product_Variation_Filters():
|
||||
@staticmethod
|
||||
def from_form(form):
|
||||
av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_Product_Variation)
|
||||
get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form")
|
||||
get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form")
|
||||
id_user = form.id_user.data
|
||||
return User_Filters(
|
||||
get_all_user = (id_user is None),
|
||||
@@ -197,8 +202,8 @@ class Product_Variation_Filters():
|
||||
class Product_Variation_List(BaseModel):
|
||||
variations: list = []
|
||||
|
||||
def add_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product_Variation_List.add_variation', Product_Variation)
|
||||
def add_product_variation(self, variation):
|
||||
av.val_instance(variation, 'variation', 'Product_Variation_List.add_product_variation', Product_Variation)
|
||||
self.variations.append(variation)
|
||||
|
||||
def __repr__(self):
|
||||
|
||||
@@ -38,24 +38,19 @@ class Product_Variation_Tree_Node():
|
||||
|
||||
class Product_Variation_Tree():
|
||||
node_root: Product_Variation_Tree_Node
|
||||
def from_node_root(node_root):
|
||||
tree = Product_Variation_Tree()
|
||||
@classmethod
|
||||
def from_node_root(cls, node_root):
|
||||
tree = cls()
|
||||
tree.node_root = node_root
|
||||
return tree
|
||||
def get_variation_type_list(self):
|
||||
variation_types = []
|
||||
node = self.node_root
|
||||
at_leaf_node = node.is_leaf()
|
||||
while not at_leaf_node:
|
||||
variation_types.append(node.variation.name_variation_type)
|
||||
at_leaf_node = node.is_leaf()
|
||||
if not at_leaf_node:
|
||||
node = node.nodes_child[0]
|
||||
return variation_types
|
||||
@classmethod
|
||||
def from_variation_root(cls, variation_root):
|
||||
node_root = Product_Variation_Tree_Node.from_variation_and_node_parent(variation_root, None)
|
||||
return cls.from_node_root(node_root)
|
||||
def is_equal(self, tree):
|
||||
my_type_list = self.get_variation_type_list()
|
||||
my_type_list = self.get_product_variations()
|
||||
sz_me = len(my_type_list)
|
||||
other_type_list = tree.get_variation_type_list()
|
||||
other_type_list = tree.get_product_variations()
|
||||
sz_other = len(other_type_list)
|
||||
is_equal = (sz_me == sz_other)
|
||||
if is_equal:
|
||||
@@ -71,3 +66,44 @@ class Product_Variation_Tree():
|
||||
for depth in range(depth_max - 1):
|
||||
node = Product_Variation_Tree_Node.from_variation_and_node_parent(product_permutation.variations[depth + 1], node)
|
||||
return Product_Variation_Tree.from_node_root(node_root)
|
||||
def from_product_variation(product_variation):
|
||||
node_root = Product_Variation_Tree_Node.from_variation_and_node_parent(product_variation, None)
|
||||
return Product_Variation_Tree.from_node_root(node_root)
|
||||
def get_name_variations(self):
|
||||
node = self.node_root
|
||||
name = node.variation.name_variation_type
|
||||
at_leaf_node = node.is_leaf()
|
||||
while not at_leaf_node:
|
||||
node = node.nodes_child[0]
|
||||
name += f', {node.variation.name_variation_type}'
|
||||
at_leaf_node = node.is_leaf()
|
||||
return name
|
||||
def get_node_leaf(self):
|
||||
node = self.node_root
|
||||
at_leaf_node = node.is_leaf()
|
||||
while not at_leaf_node:
|
||||
node = node.nodes_child[0]
|
||||
at_leaf_node = node.is_leaf()
|
||||
return node
|
||||
def add_product_variation(self, variation):
|
||||
node_leaf = self.get_node_leaf()
|
||||
node_new = Product_Variation_Tree_Node.from_variation_and_node_parent(variation, node_leaf)
|
||||
node_leaf.add_child(node_new)
|
||||
def get_product_variation_types(self):
|
||||
types = []
|
||||
node = self.node_root
|
||||
at_leaf_node = node.is_leaf()
|
||||
while not at_leaf_node:
|
||||
types.append(node.variation.name_variation_type)
|
||||
node = node.nodes_child[0]
|
||||
at_leaf_node = node.is_leaf()
|
||||
return types
|
||||
def get_product_variations(self):
|
||||
variations = []
|
||||
node = self.node_root
|
||||
at_leaf_node = node.is_leaf()
|
||||
while not at_leaf_node:
|
||||
variations.append(node.variation)
|
||||
node = node.nodes_child[0]
|
||||
at_leaf_node = node.is_leaf()
|
||||
return variations
|
||||
@@ -173,6 +173,19 @@ class Stock_Item(db.Model, Store_Base):
|
||||
permutations: {self.permutations}
|
||||
variation trees: {self.variation_trees}
|
||||
'''
|
||||
def to_json(self):
|
||||
return {
|
||||
self.ATTR_ID_PRODUCT: {self.id_product},
|
||||
self.ATTR_ID_PRODUCT_CATEGORY: {self.id_category},
|
||||
self.FLAG_NAME: {self.name},
|
||||
self.FLAG_DISPLAY_ORDER: {self.display_order},
|
||||
self.FLAG_CAN_VIEW: {self.can_view},
|
||||
self.FLAG_CAN_EDIT: {self.can_edit},
|
||||
self.FLAG_CAN_ADMIN: {self.can_admin},
|
||||
self.FLAG_HAS_VARIATIONS: {self.has_variations},
|
||||
self.FLAG_PERMUTATIONS: {self.permutations},
|
||||
self.FLAG_VARIATION_TREES: {self.variation_trees},
|
||||
}
|
||||
def has_permutations(self):
|
||||
return len(self.permutations) > 0
|
||||
def is_available(self):
|
||||
@@ -183,12 +196,17 @@ class Stock_Item(db.Model, Store_Base):
|
||||
return True
|
||||
return False
|
||||
"""
|
||||
def to_list_rows_permutation(self):
|
||||
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
|
||||
}
|
||||
|
||||
@dataclass
|
||||
class Stock_Item_Filters():
|
||||
|
||||
@@ -11,10 +11,52 @@ Abstract business object for store objects
|
||||
"""
|
||||
|
||||
# internal
|
||||
# from helpers.DEPRECATED.helper_abc import Interface_ABC
|
||||
from extensions import db
|
||||
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():
|
||||
ATTR_ID_ACCESS_LEVEL: ClassVar[str] = 'id_access_level'
|
||||
ATTR_ID_CURRENCY: ClassVar[str] = 'id_currency'
|
||||
# ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost'
|
||||
ATTR_ID_DELIVERY_REGION: ClassVar[str] = 'id_delivery_region'
|
||||
@@ -28,6 +70,7 @@ class Store_Base():
|
||||
ATTR_ID_PRODUCT_VARIATION: ClassVar[str] = 'id_variation'
|
||||
ATTR_ID_PRODUCT_VARIATION_TYPE: ClassVar[str] = 'id_variation_type'
|
||||
ATTR_ID_STOCK_ITEM: ClassVar[str] = 'id_stock_item'
|
||||
FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required'
|
||||
FLAG_ACTIVE: ClassVar[str] = 'active'
|
||||
FLAG_CAN_ADMIN: ClassVar[str] = 'can_admin'
|
||||
FLAG_CAN_EDIT: ClassVar[str] = 'can_edit'
|
||||
@@ -35,31 +78,17 @@ class Store_Base():
|
||||
FLAG_CODE: ClassVar[str] = 'code'
|
||||
FLAG_DESCRIPTION: ClassVar[str] = 'description'
|
||||
FLAG_DISPLAY_ORDER: ClassVar[str] = 'display_order'
|
||||
FLAG_HAS_VARIATIONS: ClassVar[str] = 'has_variations'
|
||||
FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is_not_empty'
|
||||
FLAG_KEY_PRIMARY: ClassVar[str] = 'key_primary'
|
||||
FLAG_NAME: ClassVar[str] = 'name'
|
||||
|
||||
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)
|
||||
|
||||
def __repr__(self):
|
||||
pass
|
||||
FLAG_PERMUTATIONS: ClassVar[str] = 'permutations'
|
||||
FLAG_PRIORITY: ClassVar[str] = 'priority'
|
||||
FLAG_ROWS: ClassVar[str] = 'rows'
|
||||
FLAG_VARIATION_TREES: ClassVar[str] = 'variation_trees'
|
||||
@classmethod
|
||||
def from_json(cls, json):
|
||||
pass
|
||||
def to_json(self):
|
||||
pass
|
||||
|
||||
def output_bool(cls, value):
|
||||
return av.input_bool(value, f'{cls.__name__} bool attribute', f'{cls.__name__}.output_bool')
|
||||
@staticmethod
|
||||
def convert_list_objects_to_list_options(objects):
|
||||
return [object.to_json_option() for object in objects]
|
||||
|
||||
@@ -153,7 +153,7 @@ class Stripe_Product(db.Model):
|
||||
delivery_options: {self.delivery_options}
|
||||
'''
|
||||
|
||||
def add_discount(self, discount):
|
||||
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))
|
||||
|
||||
@@ -160,7 +160,7 @@ class User_Filters():
|
||||
@staticmethod
|
||||
def from_form(form):
|
||||
av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_User)
|
||||
get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form")
|
||||
get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form")
|
||||
id_user = form.id_user.data
|
||||
return User_Filters(
|
||||
get_all_user = (id_user is None),
|
||||
@@ -212,7 +212,7 @@ class User_Filters():
|
||||
@staticmethod
|
||||
def from_form(form):
|
||||
av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_User)
|
||||
get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form")
|
||||
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,
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -13,8 +13,9 @@ Datastore for Store
|
||||
# internal
|
||||
# from routes import bp_home
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.access_level import Access_Level, Filters_Access_Level
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -26,7 +27,7 @@ from business_objects.sql_error import SQL_Error
|
||||
from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
@@ -164,17 +165,52 @@ class DataStore_Base(BaseModel):
|
||||
def get_user_auth0():
|
||||
return User.from_json_auth0(session.get(current_app.config['ID_TOKEN_USER']))
|
||||
@staticmethod
|
||||
def upload_bulk(objects, objectType, batch_size):
|
||||
def upload_bulk(permanent_table_name, records, batch_size):
|
||||
_m = 'DataStore_Base.upload_bulk'
|
||||
print(f'{_m}\nstarting...')
|
||||
try:
|
||||
for i in range(0, len(objects), batch_size):
|
||||
batch = objects[i:i+batch_size]
|
||||
for i in range(0, len(records), batch_size):
|
||||
batch = records[i:i+batch_size]
|
||||
data = [object.to_json() for object in batch]
|
||||
print(f'batch: {batch}\ndata: {data}')
|
||||
db.session.bulk_insert_mappings(objectType, data)
|
||||
db.session.bulk_insert_mappings(permanent_table_name, data)
|
||||
db.session.commit()
|
||||
except Exception as e:
|
||||
print(f'{_m}\n{e}')
|
||||
db.session.rollback()
|
||||
raise e
|
||||
raise e
|
||||
@classmethod
|
||||
def get_many_access_level(cls, filters):
|
||||
_m = 'DataStore_Store_Base.get_many_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
|
||||
print(f'argument_dict: {argument_dict}')
|
||||
print('executing p_shop_get_many_access_level')
|
||||
result = cls.db_procedure_execute('p_shop_get_many_access_level', argument_dict)
|
||||
cursor = result.cursor
|
||||
print('data received')
|
||||
|
||||
# access_levels
|
||||
result_set_1 = cursor.fetchall()
|
||||
print(f'raw access levels: {result_set_1}')
|
||||
access_levels = []
|
||||
for row in result_set_1:
|
||||
new_access_level = Access_Level.from_DB_access_level(row)
|
||||
access_levels.append(new_access_level)
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
result_set_e = cursor.fetchall()
|
||||
print(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])
|
||||
for error in errors:
|
||||
print(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
DataStore_Base.db_cursor_clear(cursor)
|
||||
cursor.close()
|
||||
|
||||
return access_levels, errors
|
||||
@@ -13,8 +13,9 @@ Datastore for Store
|
||||
# internal
|
||||
# from routes import bp_home
|
||||
import lib.argument_validation as av
|
||||
# from business_objects.store.access_level import Access_Level, Filters_Access_Level
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +28,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_base import DataStore_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
@@ -69,7 +70,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
print('data received')
|
||||
|
||||
|
||||
category_list = Container_Product_Category()
|
||||
category_list = Product_Category_Container()
|
||||
# Categories
|
||||
result_set_1 = cursor.fetchall()
|
||||
print(f'raw categories: {result_set_1}')
|
||||
@@ -77,10 +78,10 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
# categories = []
|
||||
# category_index = {}
|
||||
for row in result_set_1:
|
||||
new_category = Product_Category.from_DB_product(row) # Product_Category(row[0], row[1], row[2], row[3])
|
||||
new_category = Product_Category.from_DB_get_many_product_catalogue(row) # Product_Category(row[0], row[1], row[2], row[3])
|
||||
# category_index[new_category.id_category] = len(categories)
|
||||
# categories.append(new_category)
|
||||
category_list.add_category(new_category)
|
||||
category_list.add_product_category(new_category)
|
||||
# print(f'categories: {[c.id_category for c in categories]}')
|
||||
|
||||
# Products
|
||||
@@ -90,7 +91,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
# products = [] # [Product(**row) for row in result_set_2]
|
||||
# product_index = {}
|
||||
for row in result_set_2:
|
||||
new_product = Product.from_DB_product(row) # (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])
|
||||
new_product = Product.from_DB_get_many_product_catalogue(row) # (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])
|
||||
index_category = category_list.get_index_category_from_id(new_product.id_category)
|
||||
category = category_list.categories[index_category]
|
||||
category_list.add_product(new_product)
|
||||
@@ -104,10 +105,10 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
permutations = [] # [Product(**row) for row in result_set_2]
|
||||
# permutation_index = {}
|
||||
for row in result_set_3:
|
||||
new_permutation = Product_Permutation.from_DB_product(row) # (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])
|
||||
new_permutation = Product_Permutation.from_DB_get_many_product_catalogue(row) # (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])
|
||||
index_category = category_list.get_index_category_from_id(new_permutation.id_category)
|
||||
category = category_list.categories[index_category]
|
||||
category_list.add_permutation(new_permutation)
|
||||
category_list.add_product_permutation(new_permutation)
|
||||
print(f'category_list: {category_list}')
|
||||
|
||||
# Product_Variations
|
||||
@@ -117,13 +118,13 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
# variations = [Product_Variation(**row) for row in result_set_4]
|
||||
variations = []
|
||||
for row in result_set_4:
|
||||
new_variation = Product_Variation.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7])
|
||||
new_variation = Product_Variation.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7])
|
||||
variations.append(new_variation)
|
||||
# products[product_index[new_variation.id_product]].variations.append(new_variation)
|
||||
# index_category = category_index[new_variation.id_category]
|
||||
# index_product = categories[index_category].index_product_from_ids_product_permutation(new_variation.id_product, new_variation.id_permutation)
|
||||
# categories[index_category].products[index_product].variations.append(new_variation)
|
||||
category_list.add_variation(new_variation)
|
||||
category_list.add_product_variation(new_variation)
|
||||
# print(f'variations: {variations}')
|
||||
# print(f'products: {[p.id_product for p in products]}')
|
||||
|
||||
@@ -134,7 +135,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
# images = [Image(**row) for row in result_set_5]
|
||||
images = []
|
||||
for row in result_set_5:
|
||||
new_image = Image.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4])
|
||||
new_image = Image.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4])
|
||||
images.append(new_image)
|
||||
# products[product_index[new_image.id_product]].images.append(new_image)
|
||||
"""
|
||||
@@ -142,7 +143,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
index_product = categories[index_category].index_product_from_ids_product_permutation(new_image.id_product, new_image.id_permutation)
|
||||
categories[index_category].products[index_product].images.append(new_image)
|
||||
"""
|
||||
category_list.add_image(new_image)
|
||||
category_list.add_product_image(new_image)
|
||||
# print(f'images: {images}')
|
||||
# print(f'products: {[p.id_product for p in products]}')
|
||||
|
||||
@@ -156,7 +157,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
for error in errors:
|
||||
print(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
category_list.get_all_variation_trees()
|
||||
category_list.get_all_product_variation_trees()
|
||||
"""
|
||||
for category in category_list.categories:
|
||||
print(f'category: {category.name}')
|
||||
@@ -283,7 +284,7 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
variations = Product_Variation_List()
|
||||
for row in result_set:
|
||||
new_variation = Product_Variation.from_DB_variation(row)
|
||||
variations.add_variation(new_variation)
|
||||
variations.add_product_variation(new_variation)
|
||||
|
||||
errors = []
|
||||
cursor.nextset()
|
||||
@@ -298,4 +299,5 @@ class DataStore_Store_Base(DataStore_Base):
|
||||
|
||||
cursor.close()
|
||||
|
||||
return variations, errors
|
||||
return variations, errors
|
||||
|
||||
@@ -14,7 +14,7 @@ Datastore for Store Baskets
|
||||
# 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_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
|
||||
129
datastores/datastore_store_product.py
Normal file
129
datastores/datastore_store_product.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
Project: PARTS Website
|
||||
Author: Edward Middleton-Smith
|
||||
Precision And Research Technology Systems Limited
|
||||
|
||||
Technology: DataStores
|
||||
Feature: Store Product DataStore
|
||||
|
||||
Description:
|
||||
Datastore for Store Products
|
||||
"""
|
||||
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
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.delivery_region import Delivery_Region
|
||||
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, Filters_Product
|
||||
from business_objects.sql_error import SQL_Error
|
||||
from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
# from datastores.datastore_base import Table_Shop_Product_Category, Table_Shop_Product_Category_Temp
|
||||
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
|
||||
# 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_category': self.id_category,
|
||||
'name': self.name,
|
||||
'id_access_level_required': self.id_access_level_required,
|
||||
'active': self.active,
|
||||
'display_order': self.display_order,
|
||||
'guid': self.guid,
|
||||
}
|
||||
|
||||
|
||||
class DataStore_Store_Product(DataStore_Store_Base):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@classmethod
|
||||
def save_categories(cls, comment, categories):
|
||||
_m = 'DataStore_Store_Product_Category.save_categories'
|
||||
print(f'{_m}\nstarting...')
|
||||
print(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()
|
||||
user = cls.get_user_session()
|
||||
rows = []
|
||||
id_category_new = 0
|
||||
for category in categories:
|
||||
row = Row_Shop_Product_Temp.from_product(category)
|
||||
if row.id_category == '':
|
||||
id_category_new -= 1
|
||||
row.id_category = id_category_new
|
||||
else:
|
||||
print(f'row.id_category: {row.id_category}')
|
||||
row.guid = guid
|
||||
rows.append(row)
|
||||
|
||||
print(f'rows: {rows}')
|
||||
|
||||
DataStore_Store_Base.upload_bulk(rows, Row_Shop_Product_Temp, 1000)
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': user.id_user,
|
||||
'a_guid': guid,
|
||||
'a_comment': comment,
|
||||
}
|
||||
save_result = cls.db_procedure_execute('p_shop_save_product', argument_dict_list)
|
||||
save_result.close()
|
||||
print('save procedure executed')
|
||||
|
||||
@@ -13,7 +13,7 @@ Datastore for Store Product Categories
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -63,11 +63,12 @@ class Row_Shop_Product_Category_Temp(db.Model):
|
||||
code: str = db.Column(db.String(50))
|
||||
name: str = db.Column(db.String(255))
|
||||
description: str = db.Column(db.String(4000))
|
||||
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))
|
||||
created_on: datetime = db.Column(db.DateTime)
|
||||
created_by: int = db.Column(db.Integer)
|
||||
# created_on: datetime = db.Column(db.DateTime)
|
||||
# created_by: int = db.Column(db.Integer)
|
||||
|
||||
@classmethod
|
||||
def from_product_category(cls, product_category):
|
||||
@@ -76,6 +77,7 @@ class Row_Shop_Product_Category_Temp(db.Model):
|
||||
row.code = product_category.code[0] if isinstance(product_category.code, tuple) else product_category.code
|
||||
row.name = product_category.name[0] if isinstance(product_category.name, tuple) else product_category.name
|
||||
row.description = product_category.description[0] if isinstance(product_category.description, tuple) else product_category.description
|
||||
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
|
||||
"""
|
||||
@@ -90,12 +92,15 @@ class Row_Shop_Product_Category_Temp(db.Model):
|
||||
'code': self.code,
|
||||
'name': self.name,
|
||||
'description': self.description,
|
||||
'id_access_level_required': self.id_access_level_required,
|
||||
'active': self.active,
|
||||
'display_order': self.display_order,
|
||||
'guid': self.guid,
|
||||
'created_on': self.created_on,
|
||||
'created_by': self.created_by
|
||||
}
|
||||
"""
|
||||
'created_on': self.created_on,
|
||||
'created_by': self.created_by
|
||||
"""
|
||||
|
||||
|
||||
class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
@@ -115,7 +120,8 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
rows = []
|
||||
id_category_new = 0
|
||||
for category in categories:
|
||||
row = Row_Shop_Product_Category_Temp.from_product_category(category)
|
||||
# row = Row_Shop_Product_Category_Temp.from_product_category(category)
|
||||
row = category.to_temporary_record()
|
||||
# id_tmp =
|
||||
if row.id_category == '':
|
||||
id_category_new -= 1
|
||||
@@ -123,8 +129,8 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
else:
|
||||
print(f'row.id_category: {row.id_category}')
|
||||
row.guid = guid
|
||||
row.created_on = now
|
||||
row.created_by = user.id_user
|
||||
# row.created_on = now
|
||||
# row.created_by = user.id_user
|
||||
rows.append(row)
|
||||
|
||||
print(f'rows: {rows}')
|
||||
@@ -141,7 +147,7 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
|
||||
cursor.close()
|
||||
print('cursor closed')
|
||||
"""
|
||||
DataStore_Store_Base.upload_bulk(rows, Row_Shop_Product_Category_Temp, 1000)
|
||||
DataStore_Store_Base.upload_bulk(rows, Product_Category.__tablename__, 1000)
|
||||
|
||||
argument_dict_list = {
|
||||
'a_id_user': user.id_user,
|
||||
|
||||
@@ -13,7 +13,7 @@ Datastore for Store Product Permutations
|
||||
# internal
|
||||
import lib.argument_validation as av
|
||||
from business_objects.store.basket import Basket, Basket_Item
|
||||
from business_objects.store.product_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -26,7 +26,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
|
||||
@@ -14,7 +14,7 @@ Datastore for Store Product Variations
|
||||
# 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_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
@@ -83,7 +83,7 @@ class DataStore_Store_Product_Variation(DataStore_Store_Base):
|
||||
variations = Product_Variation_List()
|
||||
for row in result_set:
|
||||
new_variation = Product_Variation.from_DB_variation(row)
|
||||
variations.add_variation(new_variation)
|
||||
variations.add_product_variation(new_variation)
|
||||
|
||||
errors = []
|
||||
cursor.nextset()
|
||||
|
||||
@@ -14,7 +14,7 @@ Datastore for Store Stock Items
|
||||
# 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_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
@@ -73,7 +73,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
|
||||
def input_many_stock_item(cursor):
|
||||
_m = 'DataStore_Store_Stock_Item.input_many_stock_item'
|
||||
category_list = Container_Product_Category()
|
||||
category_list = Product_Category_Container()
|
||||
# Categories
|
||||
result_set_1 = cursor.fetchall()
|
||||
print(f'raw categories: {result_set_1}')
|
||||
@@ -95,12 +95,12 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
except KeyError:
|
||||
permutation = Product_Permutation.from_DB_stock_item(row)
|
||||
permutation.add_stock_item(new_stock_item)
|
||||
product.add_permutation(permutation)
|
||||
product.add_product_permutation(permutation)
|
||||
except KeyError:
|
||||
product = Product.from_DB_stock_item(row)
|
||||
permutation = Product_Permutation.from_DB_stock_item(row)
|
||||
permutation.add_stock_item(new_stock_item)
|
||||
product.add_permutation(permutation)
|
||||
product.add_product_permutation(permutation)
|
||||
category_list.add_product(product)
|
||||
"""
|
||||
except KeyError:
|
||||
@@ -109,10 +109,10 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
product = Product.from_DB_stock_item(row)
|
||||
permutation = Product_Permutation.from_DB_stock_item(row)
|
||||
permutation.add_stock_item(new_stock_item)
|
||||
product.add_permutation(permutation)
|
||||
product.add_product_permutation(permutation)
|
||||
new_category.add_product(product)
|
||||
"""
|
||||
category_list.add_category(new_category)
|
||||
category_list.add_product_category(new_category)
|
||||
try:
|
||||
index_product = category.get_index_product_from_id(new_stock_item.id_product)
|
||||
product = category.products[index_product]
|
||||
@@ -125,7 +125,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
permutation.add_stock_item(new_stock_item)
|
||||
except KeyError:
|
||||
new_permutation = Product_Permutation.from_DB_stock_item(row)
|
||||
product.add_permutation(new_permutation)
|
||||
product.add_product_permutation(new_permutation)
|
||||
category_list.add_stock_item(new_stock_item)
|
||||
|
||||
# Product_Variations
|
||||
@@ -133,9 +133,9 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
result_set_3 = cursor.fetchall()
|
||||
variations = []
|
||||
for row in result_set_3:
|
||||
new_variation = Product_Variation.from_DB_product(row)
|
||||
new_variation = Product_Variation.from_DB_get_many_product_catalogue(row)
|
||||
variations.append(new_variation)
|
||||
category_list.add_variation(new_variation)
|
||||
category_list.add_product_variation(new_variation)
|
||||
|
||||
# Errors
|
||||
cursor.nextset()
|
||||
@@ -147,7 +147,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
|
||||
for error in errors:
|
||||
print(f"Error [{error.code}]: {error.msg}")
|
||||
|
||||
category_list.get_all_variation_trees()
|
||||
category_list.get_all_product_variation_trees()
|
||||
"""
|
||||
for category in category_list.categories:
|
||||
print(f'category: {category.name}')
|
||||
|
||||
@@ -14,7 +14,7 @@ Datastore for Store Stripe service
|
||||
# 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_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_store_base import DataStore_Store_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
|
||||
@@ -14,7 +14,7 @@ Datastore for Users
|
||||
# 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_category import Container_Product_Category, Product_Category
|
||||
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
|
||||
@@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
|
||||
from business_objects.user import User, User_Filters, User_Permission_Evaluation
|
||||
from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List
|
||||
from datastores.datastore_base import DataStore_Base
|
||||
from helpers.helper_db_mysql import Helper_DB_MySQL
|
||||
# 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
|
||||
|
||||
1
env_web/Lib/site-packages/pip-23.0.1.dist-info/INSTALLER
Normal file
1
env_web/Lib/site-packages/pip-23.0.1.dist-info/INSTALLER
Normal file
@@ -0,0 +1 @@
|
||||
pip
|
||||
20
env_web/Lib/site-packages/pip-23.0.1.dist-info/LICENSE.txt
Normal file
20
env_web/Lib/site-packages/pip-23.0.1.dist-info/LICENSE.txt
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
88
env_web/Lib/site-packages/pip-23.0.1.dist-info/METADATA
Normal file
88
env_web/Lib/site-packages/pip-23.0.1.dist-info/METADATA
Normal file
@@ -0,0 +1,88 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: pip
|
||||
Version: 23.0.1
|
||||
Summary: The PyPA recommended tool for installing Python packages.
|
||||
Home-page: https://pip.pypa.io/
|
||||
Author: The pip developers
|
||||
Author-email: distutils-sig@python.org
|
||||
License: MIT
|
||||
Project-URL: Documentation, https://pip.pypa.io
|
||||
Project-URL: Source, https://github.com/pypa/pip
|
||||
Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Topic :: Software Development :: Build Tools
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3 :: Only
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: 3.8
|
||||
Classifier: Programming Language :: Python :: 3.9
|
||||
Classifier: Programming Language :: Python :: 3.10
|
||||
Classifier: Programming Language :: Python :: 3.11
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
||||
Requires-Python: >=3.7
|
||||
License-File: LICENSE.txt
|
||||
|
||||
pip - The Python Package Installer
|
||||
==================================
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/pip.svg
|
||||
:target: https://pypi.org/project/pip/
|
||||
|
||||
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest
|
||||
:target: https://pip.pypa.io/en/latest
|
||||
|
||||
pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
|
||||
|
||||
Please take a look at our documentation for how to install and use pip:
|
||||
|
||||
* `Installation`_
|
||||
* `Usage`_
|
||||
|
||||
We release updates regularly, with a new version every 3 months. Find more details in our documentation:
|
||||
|
||||
* `Release notes`_
|
||||
* `Release process`_
|
||||
|
||||
In pip 20.3, we've `made a big improvement to the heart of pip`_; `learn more`_. We want your input, so `sign up for our user experience research studies`_ to help us do it right.
|
||||
|
||||
**Note**: pip 21.0, in January 2021, removed Python 2 support, per pip's `Python 2 support policy`_. Please migrate to Python 3.
|
||||
|
||||
If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
|
||||
|
||||
* `Issue tracking`_
|
||||
* `Discourse channel`_
|
||||
* `User IRC`_
|
||||
|
||||
If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
|
||||
|
||||
* `GitHub page`_
|
||||
* `Development documentation`_
|
||||
* `Development IRC`_
|
||||
|
||||
Code of Conduct
|
||||
---------------
|
||||
|
||||
Everyone interacting in the pip project's codebases, issue trackers, chat
|
||||
rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
|
||||
|
||||
.. _package installer: https://packaging.python.org/guides/tool-recommendations/
|
||||
.. _Python Package Index: https://pypi.org
|
||||
.. _Installation: https://pip.pypa.io/en/stable/installation/
|
||||
.. _Usage: https://pip.pypa.io/en/stable/
|
||||
.. _Release notes: https://pip.pypa.io/en/stable/news.html
|
||||
.. _Release process: https://pip.pypa.io/en/latest/development/release-process/
|
||||
.. _GitHub page: https://github.com/pypa/pip
|
||||
.. _Development documentation: https://pip.pypa.io/en/latest/development
|
||||
.. _made a big improvement to the heart of pip: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html
|
||||
.. _learn more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020
|
||||
.. _sign up for our user experience research studies: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html
|
||||
.. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support
|
||||
.. _Issue tracking: https://github.com/pypa/pip/issues
|
||||
.. _Discourse channel: https://discuss.python.org/c/packaging
|
||||
.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
|
||||
.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
|
||||
.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
|
||||
1002
env_web/Lib/site-packages/pip-23.0.1.dist-info/RECORD
Normal file
1002
env_web/Lib/site-packages/pip-23.0.1.dist-info/RECORD
Normal file
File diff suppressed because it is too large
Load Diff
5
env_web/Lib/site-packages/pip-23.0.1.dist-info/WHEEL
Normal file
5
env_web/Lib/site-packages/pip-23.0.1.dist-info/WHEEL
Normal file
@@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.38.4)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[console_scripts]
|
||||
pip = pip._internal.cli.main:main
|
||||
pip3 = pip._internal.cli.main:main
|
||||
pip3.9 = pip._internal.cli.main:main
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user