1. View, filter, and save Product Permutation. \n 2. Synchronised with Product Category page and all common functionality moved into base and base table css, js, and python files.

This commit is contained in:
2024-09-24 23:25:52 +01:00
parent 2954b2050c
commit 45ac0405b4
243 changed files with 6596 additions and 4460 deletions

View File

@@ -13,7 +13,8 @@ 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.access_level import Access_Level
"""
from business_objects.store.basket import Basket, Basket_Item
from business_objects.store.product_category import Product_Category_Container, Product_Category
from business_objects.store.currency import Currency
@@ -23,13 +24,17 @@ 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 # Permutation_Variation_Link
"""
from business_objects.sql_error import SQL_Error
from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters
from business_objects.unit_measurement import Unit_Measurement
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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
# from helpers.helper_db_mysql import Helper_DB_MySQL
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
from extensions import db
from forms.access_level import Filters_Access_Level
from forms.unit_measurement import Filters_Unit_Measurement
# external
# from abc import ABC, abstractmethod, abstractproperty
from flask_sqlalchemy import SQLAlchemy
@@ -105,8 +110,8 @@ class DataStore_Base(BaseModel):
while cursor.nextset():
print(f'new result set: {cursor.fetchall()}')
@classmethod
def get_regions_and_currencies(cls):
_m = 'DataStore_Base.get_regions_and_currencies'
def get_many_region_and_currency(cls):
_m = 'DataStore_Base.get_many_region_and_currency'
_m_db_currency = 'p_shop_get_many_currency'
_m_db_region = 'p_shop_get_many_region'
@@ -168,20 +173,45 @@ class DataStore_Base(BaseModel):
def upload_bulk(permanent_table_name, records, batch_size):
_m = 'DataStore_Base.upload_bulk'
print(f'{_m}\nstarting...')
print(f'permanent_table_name: {permanent_table_name}')
if db.session.dirty or db.session.new or db.session.deleted:
print("Session is not clean")
return
# Assuming `permanent_table_name` is a string representing the table name
table_object = db.metadata.tables.get(permanent_table_name)
if table_object is None:
print(f"Table {permanent_table_name} not found in metadata.")
return
else:
expected_columns = set(column.name for column in db.inspect(table_object).columns)
print(f'expected_columns: {expected_columns}')
try:
for i in range(0, len(records), batch_size):
batch = records[i:i+batch_size]
print(f'batch: {batch}')
db.session.bulk_save_objects(batch)
"""
data = [object.to_json() for object in batch]
print(f'batch: {batch}\ndata: {data}')
db.session.bulk_insert_mappings(permanent_table_name, data)
print(f'data: {data}')
for row in data:
row_keys = set(row.keys())
if row_keys != expected_columns:
print(f"Column mismatch in row: {row}")
print(f'missing columns: {expected_columns - row_keys}')
print(f'extra columns: {row_keys - expected_columns}')
# 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
@classmethod
def get_many_access_level(cls, filters):
def get_many_access_level(cls, filters=None):
_m = 'DataStore_Store_Base.get_many_access_level'
if filters is None:
filters = Filters_Access_Level()
av.val_instance(filters, 'filters', _m, Filters_Access_Level)
argument_dict = filters.to_json()
# user = cls.get_user_session()
@@ -213,4 +243,41 @@ class DataStore_Base(BaseModel):
DataStore_Base.db_cursor_clear(cursor)
cursor.close()
return access_levels, errors
return access_levels, errors
@classmethod
def get_many_unit_measurement(cls, filters=None):
_m = 'DataStore_Store_Base.get_many_unit_measurement'
if filters is None:
filters = Filters_Unit_Measurement()
av.val_instance(filters, 'filters', _m, Filters_Unit_Measurement)
argument_dict = filters.to_json()
# user = cls.get_user_session()
# argument_dict['a_id_user'] = 1 # 'auth0|6582b95c895d09a70ba10fef' # id_user
print(f'argument_dict: {argument_dict}')
print('executing p_shop_get_many_unit_measurement')
result = cls.db_procedure_execute('p_shop_get_many_unit_measurement', argument_dict)
cursor = result.cursor
print('data received')
# units of measurement
result_set_1 = cursor.fetchall()
print(f'raw units of measurement: {result_set_1}')
units = []
for row in result_set_1:
new_unit = Unit_Measurement.from_DB_unit_measurement(row)
units.append(new_unit)
# 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 units, errors

View File

@@ -12,8 +12,6 @@ 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 Product_Category_Container, Product_Category
from business_objects.store.currency import Currency
@@ -26,11 +24,12 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation_Type, Product_Variation, Product_Variation_Filters, Product_Variation_Container
from datastores.datastore_base import DataStore_Base
# from helpers.helper_db_mysql import Helper_DB_MySQL
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
from extensions import db
from helpers.helper_db_mysql import Helper_DB_MySQL
import lib.argument_validation as av
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!
# external
# from abc import ABC, abstractmethod, abstractproperty
from flask_sqlalchemy import SQLAlchemy
@@ -118,12 +117,8 @@ 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_get_many_product_catalogue(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)
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_product_variation(new_variation)
# print(f'variations: {variations}')
# print(f'products: {[p.id_product for p in products]}')
@@ -209,17 +204,13 @@ class DataStore_Store_Base(DataStore_Base):
ids_permutation.append(msg_error_availability[:index_comma])
return ids_permutation
@classmethod
def get_regions_and_currencies(cls):
_m = 'DataStore_Store_Base.get_regions_and_currencies'
def get_many_currency(cls):
_m = 'DataStore_Store_Base.get_many_currency'
_m_db_currency = 'p_shop_get_many_currency'
_m_db_region = 'p_shop_get_many_region'
argument_dict_list_currency = {
'a_get_inactive_currency': 0
}
argument_dict_list_region = {
'a_get_inactive_currency': 0
}
print(f'executing {_m_db_currency}')
result = cls.db_procedure_execute(_m_db_currency, argument_dict_list_currency)
@@ -235,6 +226,17 @@ class DataStore_Store_Base(DataStore_Base):
print(f'currencies: {currencies}')
DataStore_Store_Base.db_cursor_clear(cursor)
return currencies
@classmethod
def get_many_region(cls):
_m = 'DataStore_Store_Base.get_many_region'
_m_db_region = 'p_shop_get_many_region'
argument_dict_list_region = {
'a_get_inactive_currency': 0
}
print(f'executing {_m_db_region}')
result = cls.db_procedure_execute(_m_db_region, argument_dict_list_region)
cursor = result.cursor
@@ -250,7 +252,15 @@ class DataStore_Store_Base(DataStore_Base):
DataStore_Store_Base.db_cursor_clear(cursor)
cursor.close()
return regions
@classmethod
def get_many_region_and_currency(cls):
_m = 'DataStore_Store_Base.get_many_region_and_currency'
currencies = cls.get_many_currency()
regions = cls.get_many_region()
return regions, currencies
@classmethod
def get_many_product_variation(cls, variation_filters):
_m = 'DataStore_Store_Base.get_many_product_variation'
@@ -278,13 +288,30 @@ class DataStore_Store_Base(DataStore_Base):
result = cls.db_procedure_execute('p_shop_get_many_product_variation', argument_dict_list)
cursor = result.cursor
result_set = cursor.fetchall()
result_set_vt = cursor.fetchall()
# Product_Variation Types
# variation_container = Product_Variation_Container()
variation_types = []
variation_types_dict = {}
for row in result_set_vt:
new_variation_type = Product_Variation_Type.from_DB_get_many_product_variation(row)
# variation_container.add_product_variation_type(new_variation_type)
variation_types.append(new_variation_type)
variation_types_dict[new_variation_type.id_type] = new_variation_type
print(f'variation_types_dict: {variation_types_dict}')
# Product_Variations
variations = Product_Variation_List()
for row in result_set:
new_variation = Product_Variation.from_DB_variation(row)
variations.add_product_variation(new_variation)
cursor.nextset()
result_set_v = cursor.fetchall()
# variations = Product_Variation_Container()
variations = []
for row in result_set_v:
new_variation = Product_Variation.from_DB_get_many_product_variation(row)
new_variation.variation_type = variation_types_dict[new_variation.id_type]
# variation_container.add_product_variation(new_variation)
variations.append(new_variation)
errors = []
cursor.nextset()
@@ -299,5 +326,5 @@ class DataStore_Store_Base(DataStore_Base):
cursor.close()
return variations, errors
return variation_types, variations, errors

View File

@@ -25,7 +25,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
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!

View File

@@ -24,7 +24,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
# 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
@@ -83,7 +83,7 @@ class Row_Shop_Product_Temp(db.Model):
'id_category': self.id_category,
'name': self.name,
'id_access_level_required': self.id_access_level_required,
'active': self.active,
'active': av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json'),
'display_order': self.display_order,
'guid': self.guid,
}

View File

@@ -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 Product_Category_Container, Product_Category
from business_objects.store.product_category import Product_Category_Container, Product_Category, Product_Category_Temp
from business_objects.store.currency import Currency
from business_objects.store.image import Image
from business_objects.store.delivery_option import Delivery_Option
@@ -24,7 +24,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
# 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
@@ -41,67 +41,6 @@ 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_Category_Temp(db.Model):
__tablename__ = 'Shop_Product_Category_Temp'
__table_args__ = { 'extend_existing': True }
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))
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)
@classmethod
def from_product_category(cls, product_category):
row = cls()
row.id_category = product_category.id_category[0] if isinstance(product_category.id_category, tuple) else product_category.id_category
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
"""
row.guid = product_category.guid
row.created_on = product_category.created_on
row.created_by = product_category.created_by
"""
return row
def to_json(self):
return {
'id_category': self.id_category,
'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
"""
class DataStore_Store_Product_Category(DataStore_Store_Base):
def __init__(self):
@@ -120,8 +59,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 = category.to_temporary_record()
row = Product_Category_Temp.from_product_category(category)
# row = category.to_temporary_record()
# id_tmp =
if row.id_category == '':
id_category_new -= 1
@@ -147,7 +86,7 @@ class DataStore_Store_Product_Category(DataStore_Store_Base):
cursor.close()
print('cursor closed')
"""
DataStore_Store_Base.upload_bulk(rows, Product_Category.__tablename__, 1000)
DataStore_Store_Base.upload_bulk(Product_Category_Temp.__tablename__, rows, 1000)
argument_dict_list = {
'a_id_user': user.id_user,

View File

@@ -12,21 +12,10 @@ 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 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 business_objects.store.store_base import Store_Base
from business_objects.store.product_permutation import Product_Permutation, Product_Permutation_Temp
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
@@ -43,35 +32,72 @@ from datetime import datetime
# db = SQLAlchemy()
class DataStore_Store_Product_Permutation(DataStore_Store_Base):
def __init__(self):
super().__init__()
def save_permutations(self, comment, permutations):
_m = 'DataStore_Store_Base.save_permutations'
@classmethod
def save_permutations(cls, comment, permutations):
_m = 'DataStore_Store_Product_Permutation.save_permutations'
av.val_str(comment, 'comment', _m)
av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
guid = Helper_DB_MySQL.create_guid()
guid = Helper_DB_MySQL.create_guid_str()
now = datetime.now()
user = self.get_user_session()
user = cls.get_user_session()
rows = []
for permutation in permutations:
setattr(permutation, 'guid', guid)
setattr(permutation, 'created_on', now)
setattr(permutation, 'created_by', user.id_user)
# row = permutation.to_temporary_record()
row = Product_Permutation_Temp.from_product_permutation(permutation)
row.guid = guid
rows.append(row)
cursor = self.db.cursor()
print(f'rows: {rows}')
"""
cursor = db.cursor()
print('cursor created')
cursor.executemany(
'INSERT INTO Shop_Product_Permutation_Temp (id_permutation, id_product, description, cost_local, id_currency_cost, profit_local_min, latency_manufacture, quantity_min, quantity_max, quantity_step, quantity_stock, is_subscription, id_recurrence_interval, count_recurrence_interval, id_stripe_product, active, display_order, guid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
permutations
'''INSERT INTO Shop_Product_Permutation_Temp (
id_permutation,
id_product,
description,
cost_local,
id_currency_cost,
profit_local_min,
latency_manufacture_days,
id_unit_measurement_quantity,
count_unit_measurement_quantity,
quantity_min,
quantity_max,
quantity_stock,
is_subscription,
id_unit_measurement_interval_recurrence,
count_interval_recurrence,
id_stripe_product,
does_expire_faster_once_unsealed,
id_unit_measurement_interval_expiration_unsealed,
count_interval_expiration_unsealed,
active,
guid
)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)''',
rows
)
self.db.commit()
print('cursor executed')
db.commit()
print('cursor committed')
cursor.close()
print('cursor closed')
"""
DataStore_Store_Base.upload_bulk(Product_Permutation_Temp.__tablename__, rows, 1000)
print('bulk uploaded')
argument_dict_list = {
'a_id_user': user.id_user,
'a_comment': comment,
'a_guid': guid
}
self.db_procedure_execute('p_shop_save_permutation', argument_dict_list)
cursor.close()
cls.db_procedure_execute('p_shop_save_product_permutation', argument_dict_list)
print('saved product permutations')

View File

@@ -25,7 +25,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
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!
@@ -80,7 +80,7 @@ class DataStore_Store_Product_Variation(DataStore_Store_Base):
result_set = cursor.fetchall()
# Product_Variations
variations = Product_Variation_List()
variations = Product_Variation_Container()
for row in result_set:
new_variation = Product_Variation.from_DB_variation(row)
variations.add_product_variation(new_variation)

View File

@@ -25,7 +25,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
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!

View File

@@ -25,7 +25,7 @@ from business_objects.store.product import Product, Product_Permutation, 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 business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_Container
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!

View File

@@ -13,19 +13,9 @@ Datastore for Users
# internal
# from routes import bp_home
import lib.argument_validation as av
from business_objects.store.basket import Basket, Basket_Item
from business_objects.store.product_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 DataStore_Base
from helpers.helper_db_mysql import Helper_DB_MySQL
# from models.model_view_store_checkout import Model_View_Store_Checkout # circular!