Complete system for getting + saving Product Categories with new database, server, and client architecture.

This commit is contained in:
2024-09-01 21:57:46 +01:00
parent f9cd9ec33a
commit c9dda91dc9
303 changed files with 4358 additions and 2885 deletions

View File

@@ -18,8 +18,9 @@ Base data model for views
# internal
# from routes import bp_home
import lib.argument_validation as av
from forms import Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency
from forms.forms import Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency
from datastores.datastore_user import DataStore_User
from business_objects.store.store_base import Store_Base
from business_objects.user import User, User_Filters
# external
from abc import ABC, abstractmethod
@@ -28,36 +29,41 @@ from flask import Flask, session, current_app
from pydantic import BaseModel, ConfigDict
from typing import ClassVar
# VARIABLE INSTANTIATION
# CLASSES
class Model_View_Base(BaseModel, ABC):
# Global constants
# ATTR_FOR: ClassVar[str] = 'for'
ATTR_TEXT_COLLAPSED: ClassVar[str] = 'textCollapsed'
ATTR_TEXT_EXPANDED: ClassVar[str] = 'textExpanded'
ATTR_VALUE_CURRENT: ClassVar[str] = 'current-value'
ATTR_VALUE_PREVIOUS: ClassVar[str] = 'previous-value'
FLAG_ACTIVE: ClassVar[str] = 'active'
FLAG_ACTIVE: ClassVar[str] = Store_Base.FLAG_ACTIVE
FLAG_ADD: ClassVar[str] = 'add'
FLAG_CANCEL: ClassVar[str] = 'button-cancel'
# FLAG_CONTACT_US: ClassVar[str] = 'button-contact'
FLAG_CLOSE_TEMPORARY_ELEMENT: ClassVar[str] = 'button-temporary-element-close'
FLAG_CARD: ClassVar[str] = 'card'
FLAG_CODE: ClassVar[str] = Store_Base.FLAG_CODE
FLAG_COLLAPSED: ClassVar[str] = 'collapsed'
FLAG_COLLAPSIBLE: ClassVar[str] = 'collapsible'
FLAG_COLUMN: ClassVar[str] = 'column'
FLAG_COMMENT: ClassVar[str] = 'comment'
FLAG_CONTAINER: ClassVar[str] = 'container'
FLAG_CONTAINER_INPUT: ClassVar[str] = FLAG_CONTAINER + '-input'
FLAG_DELETE: ClassVar[str] = 'delete'
FLAG_DESCRIPTION: ClassVar[str] = Store_Base.FLAG_DESCRIPTION
FLAG_DETAIL: ClassVar[str] = 'detail'
FLAG_DIALOG: ClassVar[str] = 'dialog' # try <dialog> element
FLAG_DIRTY: ClassVar[str] = 'dirty'
FLAG_DISPLAY_ORDER: ClassVar[str] = Store_Base.FLAG_DISPLAY_ORDER
FLAG_ERROR: ClassVar[str] = 'error'
FLAG_EXPANDED: ClassVar[str] = 'expanded'
FLAG_FILTER: ClassVar[str] = 'filter'
FLAG_HAMBURGER: ClassVar[str] = 'hamburger'
FLAG_IMAGE_LOGO: ClassVar[str] = 'image-logo'
FLAG_INITIALISED: ClassVar[str] = 'initialised'
FLAG_MODAL: ClassVar[str] = 'modal'
FLAG_NAME: ClassVar[str] = Store_Base.FLAG_NAME
FLAG_NAV_ADMIN_HOME: ClassVar[str] = 'navAdminHome'
FLAG_NAV_ADMIN_STORE_STRIPE_PRICES: ClassVar[str] = 'navAdminStoreStripePrices'
FLAG_NAV_ADMIN_STORE_STRIPE_PRODUCTS: ClassVar[str] = 'navAdminStoreStripeProducts'
@@ -80,7 +86,9 @@ class Model_View_Base(BaseModel, ABC):
FLAG_PAGE_BODY: ClassVar[str] = 'page-body'
FLAG_ROW: ClassVar[str] = 'row'
FLAG_ROW_NEW: ClassVar[str] = 'row-new'
FLAG_SAVE: ClassVar[str] = 'save'
FLAG_SCROLLABLE: ClassVar[str] = 'scrollable'
FLAG_SLIDER: ClassVar[str] = 'slider'
FLAG_SUBMIT: ClassVar[str] = 'submit'
FLAG_SUBMITTED: ClassVar[str] = 'submitted'
# flagIsDatePicker: ClassVar[str] = 'is-date-picker'
@@ -110,8 +118,8 @@ class Model_View_Base(BaseModel, ABC):
HASH_PAGE_USER_ADMIN: ClassVar[str] = '/user/admin'
HASH_PAGE_USER_LOGIN: ClassVar[str] = '/login'
HASH_PAGE_USER_LOGOUT: ClassVar[str] = '/logout'
HASH_SAVE_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_save'
ID_BUTTON_ADD: ClassVar[str] = 'buttonAdd'
ID_BUTTON_APPLY_FILTERS: ClassVar[str] = 'buttonApplyFilters'
ID_BUTTON_CANCEL: ClassVar[str] = 'buttonCancel'
ID_BUTTON_HAMBURGER: ClassVar[str] = 'buttonHamburger'
ID_BUTTON_SAVE: ClassVar[str] = 'buttonSave'
@@ -143,6 +151,7 @@ class Model_View_Base(BaseModel, ABC):
ID_BUTTON_NAV_USER_LOGOUT: ClassVar[str] = 'navUserLogout'
"""
ID_OVERLAY_CONFIRM: ClassVar[str] = 'overlayConfirm'
ID_OVERLAY_ERROR: ClassVar[str] = 'overlayError'
ID_OVERLAY_HAMBURGER: ClassVar[str] = 'overlayHamburger'
ID_PAGE_BODY: ClassVar[str] = 'pageBody'
ID_TABLE_MAIN: ClassVar[str] = 'tableMain'

View File

@@ -14,7 +14,7 @@ Data model for contact view
from models.model_view_base import Model_View_Base
# from routes import bp_home
from lib import argument_validation as av
from forms import Form_Contact
from forms.forms import Form_Contact
# external
from flask_wtf import FlaskForm
from abc import abstractproperty

View File

@@ -18,13 +18,13 @@ Parent data model for store views
# internal
# from context import models
from models.model_view_base import Model_View_Base
from business_objects.store.product import Product, Product_Filters, Product_Permutation # Product_Image_Filters,
from business_objects.store.product import Product, Filters_Product, Product_Permutation # Product_Image_Filters,
from business_objects.store.image import Resolution_Level_Enum
import lib.argument_validation as av
from datastores.datastore_store_base import DataStore_Store_Base
from datastores.datastore_user import DataStore_User
from datastores.datastore_store_basket import DataStore_Store_Basket
from forms import Form_Basket_Edit, Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency
from forms.forms import Form_Basket_Edit, Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency
from business_objects.store.basket import Basket_Item, Basket
from business_objects.store.product_category import Product_Category
from business_objects.store.product_variation import Product_Variation_Filters, Product_Variation
@@ -71,6 +71,10 @@ class Model_View_Store(Model_View_Base):
HASH_STORE_BASKET_DELETE : ClassVar[str] = '/store/basket_delete'
HASH_STORE_BASKET_EDIT : ClassVar[str] = '/store/basket_edit'
HASH_STORE_BASKET_LOAD : ClassVar[str] = '/store/basket_load'
HASH_GET_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/category_get'
HASH_GET_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_get'
HASH_SAVE_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/category_save'
HASH_SAVE_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_save'
HASH_STORE_SET_CURRENCY : ClassVar[str] = '/store/set_currency'
HASH_STORE_SET_DELIVERY_REGION : ClassVar[str] = '/store/set_delivery_region'
HASH_STORE_SET_IS_INCLUDED_VAT : ClassVar[str] = '/store/set_is_included_VAT'
@@ -158,7 +162,7 @@ class Model_View_Store(Model_View_Base):
def get_many_product(self, product_filters): # category_ids = '', product_ids = '', get_all_category = True, get_all_product = True, max_products_per_category = -1):
_m = 'Model_View_Store.get_many_product'
av.val_instance(product_filters, 'product_filters', _m, Product_Filters)
av.val_instance(product_filters, 'product_filters', _m, Filters_Product)
"""
av.val_str(category_ids, 'category_ids', _m)
av.val_str(product_ids, 'product_ids', _m)
@@ -288,7 +292,7 @@ class Model_View_Store(Model_View_Base):
is_included_VAT = basket[self.KEY_IS_INCLUDED_VAT]
print(f'json basket items: {items}')
product_ids, permutation_ids, item_index_dict = self._get_json_basket_id_CSVs_product_permutation(items)
category_list, errors = DataStore_Store_Base().get_many_product(Product_Filters(
category_list, errors = DataStore_Store_Base().get_many_product(Filters_Product(
self.id_user, # :a_id_user
True, '', False, # :a_get_all_category, :a_ids_category, :a_get_inactive_category
False, product_ids, False, False, # :a_get_all_product, :a_ids_product, :a_get_inactive_product, :a_get_first_product_only
@@ -335,7 +339,7 @@ class Model_View_Store(Model_View_Base):
"""
ids_permutation_unavailable = self.basket.get_ids_permutation_unavailable()
if len(ids_permutation_unavailable) > 0:
category_list_unavailable, errors_unavailable = DataStore_Store().get_many_product(Product_Filters(
category_list_unavailable, errors_unavailable = DataStore_Store().get_many_product(Filters_Product(
self.id_user, # :a_id_user
True, '', False, # :a_get_all_category, :a_ids_category, :a_get_inactive_category
False, '', False, False, # :a_get_all_product, :a_ids_product, :a_get_inactive_product, :a_get_first_product_only

View File

@@ -19,7 +19,7 @@ Data model for store basket view
from models.model_view_store import Model_View_Store
# from routes import bp_home
from business_objects.store.product import Product
from forms import Form_Billing # Form_Product
from forms.forms import Form_Billing # Form_Product
# external

View File

@@ -20,7 +20,7 @@ from models.model_view_store import Model_View_Store
from models.model_view_store_basket import Model_View_Store_Basket
# from routes import bp_home
from business_objects.store.product import Product
from forms import Form_Billing # Form_Product
from forms.forms import Form_Billing # Form_Product
import lib.argument_validation as av
# from datastores.datastore_store_base import DataStore_Store
# external

View File

@@ -20,7 +20,7 @@ from models.model_view_store import Model_View_Store
from models.model_view_store_checkout import Model_View_Store_Checkout
# from routes import bp_home
from business_objects.store.product import Product
from forms import Form_Billing # Form_Product
from forms.forms import Form_Billing # Form_Product
import lib.argument_validation as av
# from datastores.datastore_store_base import DataStore_Store
# external

View File

@@ -19,7 +19,7 @@ Data model for store home view
from models.model_view_store import Model_View_Store
# from routes import bp_home
from business_objects.store.product import Product
from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product
from forms.forms import Form_Basket_Add, Form_Basket_Edit # Form_Product
# external

View File

@@ -19,7 +19,7 @@ Data model for store product view
from models.model_view_store import Model_View_Store
from datastores.datastore_store_base import DataStore_Store_Base
# from routes import bp_home
from business_objects.store.product import Product, Product_Filters
from business_objects.store.product import Product, Filters_Product
import lib.argument_validation as av
# external
@@ -44,7 +44,7 @@ class Model_View_Store_Product(Model_View_Store):
super().__init__(hash_page_current=hash_page_current, id_currency=id_currency, id_region_delivery=id_region_delivery, is_included_VAT=is_included_VAT)
print('supered')
category_list = DataStore_Store_Base().get_many_product(Product_Filters(
category_list = DataStore_Store_Base().get_many_product(Filters_Product(
self.info_user['sub'],
True, '', False,
True, '', False, False,

View File

@@ -14,10 +14,11 @@ Data model for store permutations view
from models.model_view_store import Model_View_Store
# from datastores.datastore_store_base import DataStore_Store_Base
from datastores.datastore_store_product_category import DataStore_Store_Product_Category
from business_objects.store.product_category import Container_Product_Category
from forms import Form_Filters_Permutation
from business_objects.store.product_category import Container_Product_Category, Filters_Product_Category
from forms.forms import Form_Filters_Permutation
from forms.store.product_category import Form_Filters_Product_Category
# from routes import bp_home
from business_objects.store.product import Product, Product_Filters, Product_Permutation
from business_objects.store.product import Product, Filters_Product, Product_Permutation
from business_objects.store.product_variation import Product_Variation_List
import lib.argument_validation as av
@@ -26,56 +27,29 @@ from pydantic import BaseModel
from typing import ClassVar
class Model_View_Store_Product_Category(Model_View_Store):
ID_FILTER_CATEGORY: ClassVar[str] = 'id_category'
ID_FILTER_PRODUCT: ClassVar[str] = 'id_product'
ID_FILTER_IS_OUT_OF_STOCK: ClassVar[str] = 'is_out_of_stock'
ID_FILTER_QUANTITY_MIN: ClassVar[str] = 'quantity_min'
ID_FILTER_QUANTITY_MAX: ClassVar[str] = 'quantity_max'
ID_Form_Filters_Permutation: ClassVar[str] = 'Form_Filters_Permutation'
KEY_PERMUTATIONS: ClassVar[str] = 'permutations'
FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is-not-empty'
ID_FORM_FILTERS_PRODUCT_CATEGORY: ClassVar[str] = 'Form_Filters_Product_Category'
KEY_CATEGORIES: ClassVar[str] = 'categories'
category_list: Container_Product_Category = None # (str)
filters_product: Product_Filters
form_filters: Form_Filters_Permutation = None
permutation_blank: Product_Permutation = None
variations: Product_Variation_List = None
filters_category: Filters_Product_Category
form_filters: Form_Filters_Product_Category = None
@property
def title(self):
return 'Product Category'
def __init__(self, filters_product, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCT_PERMUTATIONS):
def __init__(self, filters_category, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCT_CATEGORIES):
_m = 'Model_View_Store_Product_Category.__init__'
print(f'{_m}\nstarting...')
super().__init__(hash_page_current=hash_page_current, filters_product=filters_product)
super().__init__(hash_page_current=hash_page_current, filters_category=filters_category)
# BaseModel.__init__(self, app=app, filters_product=filters_product, **kwargs)
self.form_filters = Form_Filters_Permutation()
datastore_store = DataStore_Store_Product_Category()
self.form_filters = Form_Filters_Product_Category.from_filters_product_category(filters_category)
filters_product = Filters_Product.from_filters_product_category(filters_category)
self.category_list, errors = datastore_store.get_many_product(filters_product)
category_list_filters, errors_filters = datastore_store.get_many_product(
Product_Filters(
# self.info_user['sub'],
True, False, False, '',
True, False, False, '',
True, False, False, '',
False, False, False, '',
False, False, False, '',
False, False, False, '',
False, False, '',
filters_product.get_products_quantity_stock_below_min
)
)
print(f'category_list_filters: {category_list_filters.categories}')
self.form_filters.id_category.choices = [('0', 'All')] + [(str(category.id_category), category.name) for category in category_list_filters.categories]
print(f'category options: {self.form_filters.id_category.choices}')
product_list = category_list_filters.to_list_products()
print(f'product_list: {product_list}')
self.form_filters.id_product.choices = [('0', 'All')] + [(str(product['value']), product['text']) for product in product_list]
self.permutation_blank = Product_Permutation()
print(f'category options: {self.form_filters.id_category.choices}')
variations, errors = self.get_many_product_variation()
self.variations = variations
def save_categories(self, comment, list_categories):
_m = 'Model_View_Store_Product_Category.save_categories'
@classmethod
def save_categories(cls, comment, list_categories):
_m = f'{cls.__name__}.save_categories'
DataStore_Store_Product_Category().save_categories(comment, list_categories)

View File

@@ -14,9 +14,9 @@ Data model for store permutations view
from models.model_view_store import Model_View_Store
from datastores.datastore_store_product_permutation import DataStore_Store_Product_Permutation
from business_objects.store.product_category import Container_Product_Category
from forms import Form_Filters_Permutation
from forms.forms import Form_Filters_Permutation
# from routes import bp_home
from business_objects.store.product import Product, Product_Filters, Product_Permutation
from business_objects.store.product import Product, Filters_Product, Product_Permutation
from business_objects.store.product_variation import Product_Variation_List
import lib.argument_validation as av
@@ -34,7 +34,7 @@ class Model_View_Store_Product_Permutation(Model_View_Store):
KEY_PERMUTATIONS: ClassVar[str] = 'permutations'
category_list: Container_Product_Category = None # (str)
filters_product: Product_Filters
filters_product: Filters_Product
form_filters: Form_Filters_Permutation = None
permutation_blank: Product_Permutation = None
variations: Product_Variation_List = None
@@ -52,7 +52,7 @@ class Model_View_Store_Product_Permutation(Model_View_Store):
datastore_store = DataStore_Store_Product_Permutation()
self.category_list, errors = datastore_store.get_many_product(filters_product)
category_list_filters, errors_filters = datastore_store.get_many_product(
Product_Filters(
Filters_Product(
# self.info_user['sub'],
True, False, '',
True, False, '',

View File

@@ -14,9 +14,9 @@ Data model for store stock items view
from models.model_view_store import Model_View_Store
from datastores.datastore_store_stock_item import DataStore_Store_Stock_Item
from business_objects.store.product_category import Container_Product_Category
from forms import Form_Filters_Stock_Item
from forms.forms import Form_Filters_Stock_Item
# from routes import bp_home
from business_objects.store.product import Product, Product_Filters, Product_Permutation
from business_objects.store.product import Product, Filters_Product, Product_Permutation
from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
import lib.argument_validation as av

View File

@@ -15,7 +15,7 @@ from models.model_view_base import Model_View_Base
from models.model_view_store import Model_View_Store
# from routes import bp_home
from lib import argument_validation as av
from forms import Form_Supplier
from forms.forms import Form_Supplier
# external