feat(UI): Stock Items page added with getting, filtering, and saving data.

This commit is contained in:
2024-10-13 19:40:25 +01:00
parent 818d049702
commit f6a6966ce4
183 changed files with 5747 additions and 8607 deletions

View File

@@ -14,3 +14,27 @@ python -m flask run
host for local network:
python -m flask run --host=0.0.0.0
files dedicated to each page:
CSS
page
HTML
page
row
JavaScript
page
api
router
MySQL
get
save
table
staging table
audit table
Python
business object
controller
datastore
form
model

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,97 @@
"""
Project: PARTS Website
Author: Edward Middleton-Smith
Precision And Research Technology Systems Limited
Technology: Business Objects
Feature: Address Business Object
Description:
Business object for address
"""
# internal
import lib.argument_validation as av
from business_objects.base import Base
from business_objects.region import Region
from extensions import db
# external
from typing import ClassVar
class Address(db.Model, Base):
FLAG_ADDRESS_LINE_1: ClassVar[str] = 'address_line_1'
FLAG_ADDRESS_LINE_2: ClassVar[str] = 'address_line_2'
FLAG_CITY: ClassVar[str] = 'city'
FLAG_COUNTY: ClassVar[str] = 'county'
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Base.ATTR_ID_ADDRESS
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_POSTCODE
__tablename__ = 'Shop_Address'
id_address = db.Column(db.Integer, primary_key=True)
id_region = db.Column(db.Integer)
postcode = db.Column(db.String(20))
address_line_1 = db.Column(db.String(256))
address_line_2 = db.Column(db.String(256))
city = db.Column(db.String(256))
county = db.Column(db.String(256))
active = db.Column(db.Boolean)
# region = None
def __init__(self):
super().__init__()
Base.__init__(self)
self.region = None
@classmethod
def from_DB_storage_location(cls, query_row):
address = cls()
address.id_address = query_row[2]
address.id_region = query_row[3]
return address
@classmethod
def from_DB_plant(cls, query_row):
address = cls()
address.id_address = query_row[1]
address.id_region = query_row[2]
@classmethod
def from_DB_stock_item(cls, query_row):
address = cls()
address.id_address = query_row[6]
address.id_region = query_row[7]
return address
def __repr__(self):
return f'''
{self.ATTR_ID_ADDRESS}: {self.id_address}
{self.FLAG_REGION}: {self.region}
{self.FLAG_POSTCODE}: {self.postcode}
{self.FLAG_ADDRESS_LINE_1}: {self.address_line_1}
{self.FLAG_ADDRESS_LINE_2}: {self.address_line_2}
{self.FLAG_CITY}: {self.city}
{self.FLAG_COUNTY}: {self.county}
{self.FLAG_ACTIVE}: {self.active}
'''
def to_json(self):
return {
**self.get_shared_json_attributes(self),
self.ATTR_ID_ADDRESS: self.id_address,
self.FLAG_REGION: self.region.to_json(),
self.FLAG_POSTCODE: self.postcode,
self.FLAG_ADDRESS_LINE_1: self.address_line_1,
self.FLAG_ADDRESS_LINE_2: self.address_line_2,
self.FLAG_CITY: self.city,
self.FLAG_COUNTY: self.county,
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
}
@classmethod
def from_json(cls, json):
print(f'{cls.__name__}.from_json: {json}')
address = cls()
address.id_address = json[cls.ATTR_ID_ADDRESS],
address.region = Region.from_json(json[cls.FLAG_REGION]),
address.postcode = json[cls.FLAG_POSTCODE],
address.address_line_1 = json[cls.FLAG_ADDRESS_LINE_1],
address.address_line_2 = json.get(cls.FLAG_ADDRESS_LINE_2, ''),
address.city = json[cls.FLAG_CITY],
address.county = json[cls.FLAG_COUNTY],
address.active = json[cls.FLAG_ACTIVE]
return address

View File

@@ -19,15 +19,20 @@ from typing import ClassVar
class Base():
ATTR_ID_ACCESS_LEVEL: ClassVar[str] = 'id_access_level'
ATTR_ID_ADDRESS: ClassVar[str] = 'id_address'
ATTR_ID_CURRENCY: ClassVar[str] = 'id_currency'
ATTR_ID_DELIVERY_REGION: ClassVar[str] = 'id_delivery_region'
ATTR_ID_REGION: ClassVar[str] = 'id_region'
ATTR_ID_USER: ClassVar[str] = 'id_user'
ATTR_ID_USER_MANAGER: ClassVar[str] = 'id_user_manager'
FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required'
FLAG_ACTIVE: ClassVar[str] = 'active'
FLAG_ADDRESS: ClassVar[str] = 'address'
FLAG_CAN_ADMIN: ClassVar[str] = 'can_admin'
FLAG_CAN_EDIT: ClassVar[str] = 'can_edit'
FLAG_CAN_VIEW: ClassVar[str] = 'can_view'
FLAG_CODE: ClassVar[str] = 'code'
FLAG_CURRENCY: ClassVar[str] = 'currency'
FLAG_CURRENCY_COST: ClassVar[str] = 'currency_cost'
FLAG_DESCRIPTION: ClassVar[str] = 'description'
FLAG_DISPLAY_ORDER: ClassVar[str] = 'display_order'
FLAG_GUID: ClassVar[str] = 'guid'
@@ -38,10 +43,14 @@ class Base():
FLAG_NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'NAME_ATTR_OPTION_VALUE'
FLAG_NAME_SINGULAR: ClassVar[str] = 'name_singular'
FLAG_NAME_PLURAL: ClassVar[str] = 'name_plural'
FLAG_POSTCODE: ClassVar[str] = 'postcode'
FLAG_PRIORITY: ClassVar[str] = 'priority'
FLAG_REGION: ClassVar[str] = 'region'
FLAG_ROWS: ClassVar[str] = 'rows'
FLAG_SYMBOL: ClassVar[str] = 'symbol'
FLAG_URL: ClassVar[str] = 'url'
FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value_local_vat_excl'
FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value_local_vat_incl'
NAME_ATTR_OPTION_TEXT: ClassVar[str] = 'name-attribute-option-text'
NAME_ATTR_OPTION_VALUE: ClassVar[str] = 'name-attribute-option-value'

View File

@@ -81,6 +81,15 @@ class Currency(db.Model, Store_Base):
v_arg_type = 'class attribute'
currency = cls()
return currency
@classmethod
def from_DB_stock_item(cls, query_row):
_m = 'Currency.from_DB_get_many_stock_item'
v_arg_type = 'class attribute'
currency = cls()
currency.id_currency = query_row[12]
currency.code = query_row[13]
currency.symbol = query_row[14]
return currency
def __repr__(self):
return f'''
id: {self.id_currency}

View File

@@ -30,11 +30,8 @@ class Get_Many_Parameters_Base(BaseModel, metaclass=ABCMeta):
@abstractmethod
def get_default(cls): # , id_user
pass
"""
@abstractmethod
def to_json(self):
pass
"""
return self.dict()
"""
@classmethod
@abstractmethod

View File

@@ -0,0 +1,82 @@
"""
Project: PARTS Website
Author: Edward Middleton-Smith
Precision And Research Technology Systems Limited
Technology: Business Objects
Feature: Address Region Business Object
Description:
Business object for address region
"""
# internal
import lib.argument_validation as av
from business_objects.base import Base
from extensions import db
# external
from typing import ClassVar
class Region(db.Model, Base):
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Base.ATTR_ID_REGION
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Base.FLAG_NAME
__tablename__ = 'Shop_Region'
id_region = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(50))
name = db.Column(db.String(200))
active = db.Column(db.Boolean)
# region = None
def __init__(self):
super().__init__()
Base.__init__(self)
self.region = None
@classmethod
def from_DB_stock_item(cls, query_row):
plant = cls()
plant.id_region = query_row[7]
return plant
def __repr__(self):
return f'''
{self.ATTR_ID_REGION}: {self.id_region}
{self.FLAG_CODE}: {self.code}
{self.FLAG_NAME}: {self.name}
{self.FLAG_ACTIVE}: {self.active}
'''
def to_json(self):
return {
**self.get_shared_json_attributes(self),
self.ATTR_ID_REGION: self.id_region,
self.FLAG_CODE: self.code,
self.FLAG_NAME: self.name,
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
}
@classmethod
def from_json(cls, json):
print(f'{cls.__name__}.from_json: {json}')
plant = cls()
plant.id_region = json[cls.ATTR_ID_REGION]
plant.code = json[cls.FLAG_CODE]
plant.name = json[cls.FLAG_NAME]
plant.active = json[cls.FLAG_ACTIVE]
return plant
@classmethod
def from_DB_get_many_product_catalogue(cls, query_row):
region = cls()
region.id_region = query_row[0]
region.name = query_row[1]
region.code = query_row[2]
# self.display_order = query_row[3]
return region
@classmethod
def from_DB_region(cls, query_row):
region = cls()
region.id_region = query_row[0]
region.code = query_row[1]
region.name = query_row[2]
region.active = av.input_bool(query_row[3], cls.FLAG_ACTIVE, f'{cls.__name__}.from_DB_region')
region.display_order = query_row[4]
return region

View File

@@ -22,7 +22,7 @@ class Delivery_Option():
delay_max: int
quantity_min: float
quantity_max: float
regions: list # [Enum_Delivery_Region]
regions: list # [Enum_Region]
cost: float
def __new__(cls, name, delay_min, delay_max, quantity_min, quantity_max, regions, cost):
@@ -33,7 +33,7 @@ class Delivery_Option():
av.val_int(delay_max, 'delay_max', _m, 0, v_arg_type = v_arg_type)
av.val_float(quantity_min, 'quantity_min', _m, 0, v_arg_type = v_arg_type)
av.val_float(quantity_max, 'quantity_max', _m, 0, v_arg_type = v_arg_type)
av.val_list_instances(regions, 'regions', _m, Enum_Delivery_Region, v_arg_type = v_arg_type)
av.val_list_instances(regions, 'regions', _m, Enum_Region, v_arg_type = v_arg_type)
av.val_float(cost, 'cost', _m, 0, v_arg_type = v_arg_type)
return super(Delivery_Option, cls).__new__(cls)

View File

@@ -1,103 +0,0 @@
"""
Project: PARTS Website
Author: Edward Middleton-Smith
Precision And Research Technology Systems Limited
Technology: Business Objects
Feature: Delivery Region Business Object
Description:
Business object for delivery region
"""
# internal
from business_objects.store.store_base import Store_Base
from extensions import db
from lib import argument_validation as av
# external
from enum import Enum
from typing import ClassVar
class Enum_Delivery_Region(Enum):
UK = 0
class Delivery_Region(db.Model, Store_Base):
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_DELIVERY_REGION
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Store_Base.FLAG_NAME
id_region = db.Column(db.Integer, primary_key=True)
"""
id_category = db.Column(db.Integer)
id_product = db.Column(db.Integer)
id_discount = db.Column(db.Integer)
"""
code = db.Column(db.String(50))
name = db.Column(db.String(200))
active = db.Column(db.Boolean)
display_order = db.Column(db.Integer)
"""
def __new__(cls, id, id_category, id_product, id_discount, code, name, display_order):
_m = 'Delivery_Region.__new__'
v_arg_type = 'class attribute'
av.val_int(id, 'id', _m, 0, v_arg_type = v_arg_type)
av.val_int(id_category, 'id_category', _m, 0, v_arg_type=v_arg_type)
av.val_int(id_product, 'id_product', _m, 0, v_arg_type = v_arg_type)
av.val_int(id_discount, 'id_discount', _m, v_arg_type = v_arg_type)
av.val_str(code, 'code', _m, max_len = 50, v_arg_type = v_arg_type)
av.val_str(name, 'name', _m, max_len = 100, v_arg_type = v_arg_type)
av.val_int(display_order, 'display_order', _m, v_arg_type = v_arg_type)
return super(Delivery_Region, cls).__new__(cls)
def __init__(self, id, id_category, id_product, id_discount, code, name, display_order):
self.id_region = id
self.id_category = id_category
self.id_product = id_product
self.id_discount = id_discount
self.name = name
self.code = code
self.display_order = display_order
"""
@classmethod
def from_DB_get_many_product_catalogue(cls, query_row):
region = cls()
region.id_region = query_row[0]
region.name = query_row[1]
region.code = query_row[2]
# self.display_order = query_row[3]
return region
@classmethod
def from_DB_region(cls, query_row):
region = cls()
region.id_region = query_row[0]
region.code = query_row[1]
region.name = query_row[2]
region.active = av.input_bool(query_row[3], cls.FLAG_ACTIVE, f'{cls.__name__}.from_DB_region')
region.display_order = query_row[4]
return region
def __repr__(self):
return f'''
id: {self.id_region}
name: {self.name}
code: {self.code}
active: {self.active}
display_order: {self.display_order}
'''
def to_json(self):
return {
**self.get_shared_json_attributes(self),
self.ATTR_ID_REGION: self.id_region,
self.FLAG_CODE: self.code,
self.FLAG_NAME: self.name,
self.FLAG_ACTIVE: self.active,
self.FLAG_DISPLAY_ORDER: self.display_order
}
@staticmethod
def from_json(json_region):
region = Delivery_Region()
region.id_region = json_region[Delivery_Region.ATTR_ID_REGION]
region.code = json_region[Delivery_Region.FLAG_CODE]
region.name = json_region[Delivery_Region.FLAG_NAME]
region.active = json_region[Delivery_Region.FLAG_ACTIVE]
region.display_order = json_region[Delivery_Region.FLAG_DISPLAY_ORDER]
return region

View File

@@ -0,0 +1,92 @@
"""
Project: PARTS Website
Author: Edward Middleton-Smith
Precision And Research Technology Systems Limited
Technology: Business Objects
Feature: Plant Business Object
Description:
Business object for plant
"""
# internal
import lib.argument_validation as av
from business_objects.address import Address
from business_objects.store.store_base import Store_Base
from extensions import db
# external
from typing import ClassVar
class Plant(db.Model, Store_Base):
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PLANT
NAME_ATTR_OPTION_TEXT: ClassVar[str] = Store_Base.FLAG_NAME
__tablename__ = 'Shop_Plant'
id_plant = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(50))
name = db.Column(db.String(255))
id_address = db.Column(db.Integer)
id_user_manager = db.Column(db.Integer)
active = db.Column(db.Boolean)
# address = None
def __init__(self):
super().__init__()
Store_Base.__init__(self)
self.address = None
@classmethod
def from_DB_storage_location(cls, query_row):
plant = cls()
plant.id_plant = query_row[1]
plant.id_address = query_row[2]
plant.address = Address.from_DB_storage_location(query_row)
return plant
@classmethod
def from_DB_plant(cls, query_row):
plant = cls()
plant.id_plant = query_row[0]
plant.id_address = query_row[1]
plant.address = Address.from_DB_plant(query_row)
plant.code = query_row[4]
plant.name = query_row[5]
plant.active = query_row[6]
return plant
@classmethod
def from_DB_stock_item(cls, query_row):
plant = cls()
plant.id_plant = query_row[5]
plant.code = query_row[10]
plant.name = query_row[11]
return plant
def __repr__(self):
return f'''
{self.ATTR_ID_PLANT}: {self.id_plant}
{self.FLAG_CODE}: {self.code}
{self.FLAG_NAME}: {self.name}
{self.FLAG_ADDRESS}: {self.address}
{self.ATTR_ID_USER_MANAGER}: {self.id_user_manager}
{self.FLAG_ACTIVE}: {self.active}
'''
def to_json(self):
return {
**self.get_shared_json_attributes(self),
self.ATTR_ID_PLANT: self.id_plant,
self.FLAG_CODE: self.code,
self.FLAG_NAME: self.name,
self.FLAG_ADDRESS: self.address.to_json(),
self.ATTR_ID_USER_MANAGER: self.id_user_manager,
self.FLAG_ACTIVE: 1 if av.input_bool(self.active, self.FLAG_ACTIVE, f'{self.__class__.__name__}.to_json') else 0
}
@classmethod
def from_json(cls, json):
print(f'{cls.__name__}.from_json: {json}')
plant = cls()
plant.id_plant = json[cls.ATTR_ID_PLANT],
plant.code = json[cls.FLAG_CODE],
plant.name = json[cls.FLAG_NAME],
plant.address = Address.from_json(json[cls.FLAG_ADDRESS]),
plant.id_user_manager = json[cls.ATTR_ID_USER_MANAGER],
plant.active = json[cls.FLAG_ACTIVE]
return plant

View File

@@ -175,7 +175,7 @@ class Product(SQLAlchemy_ABC, Store_Base):
if self.variation_trees[index_tree].is_equal(variation_tree):
found_variation_tree_match = True
break
if not found_variation_tree_match:
if not found_variation_tree_match and variation_tree is not None:
self.variation_trees.append(variation_tree)
def from_DB_Stripe_product(query_row):
permutation = Product_Permutation.from_DB_Stripe_product(query_row)
@@ -374,6 +374,13 @@ class Product(SQLAlchemy_ABC, Store_Base):
text_input += tree.get_text_input_types()
return text_input
"""
def get_csv_ids_permutation(self):
csv = ''
for permutation in self.permutations:
if csv != '':
csv += ','
csv += str(permutation.id_permutation)
return csv
class Parameters_Product(Get_Many_Parameters_Base):
@@ -482,7 +489,7 @@ class Parameters_Product(Get_Many_Parameters_Base):
@staticmethod
def from_form_filters_product_permutation(form):
# if not (form is Filters_Product_Permutation): raise ValueError(f'Invalid form type: {type(form)}')
av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product_Permutation)
# av.val_instance(form, 'form', 'Parameters_Product.from_form', Filters_Product_Permutation)
has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '')
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", "Parameters_Product.from_form")
@@ -491,11 +498,11 @@ class Parameters_Product(Get_Many_Parameters_Base):
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,
ids_product_category = form.id_category.data if form.id_category.data is not None else '',
get_all_product = not has_product_filter,
get_inactive_product = False,
# get_first_product_only = False,
ids_product = form.id_product.data,
ids_product = form.id_product.data if form.id_product.data is not None else '',
get_all_permutation = not get_permutations_stock_below_min,
get_inactive_permutation = False,
# get_first_permutation_only = False,
@@ -601,6 +608,9 @@ class Parameters_Product(Get_Many_Parameters_Base):
ids_image = '',
get_products_quantity_stock_below_min = False
)
@classmethod
def from_filters_stock_item(cls, filters_stock_item):
return cls.from_form_filters_product_permutation(filters_stock_item)
"""
class Parameters_Product(Get_Many_Parameters_Base):

View File

@@ -242,6 +242,11 @@ class Product_Category(SQLAlchemy_ABC, Store_Base):
'value': self.id_category,
'text': self.name
}
def get_csv_ids_permutation(self):
list_ids = []
for product in self.products:
list_ids += product.get_csv_ids_permutation()
return list_ids
"""
class Filters_Product_Category(BaseModel, Store_Base):
ids_product_category: str
@@ -433,6 +438,11 @@ class Product_Category_Container(Store_Base):
if column.name not in ['created_on', 'created_by']
}
return self.to_object_with_missing_attributes(excluded_attributes)
def get_csv_ids_permutation(self):
list_ids = []
for category in self.categories:
list_ids += category.get_csv_ids_permutation()
return ','.join(list_ids)
"""

View File

@@ -14,7 +14,7 @@ Business object for product permutation
import lib.argument_validation as av
from lib import data_types
from forms.forms import Form_Basket_Add, Form_Basket_Edit
from business_objects.store.currency import Currency
from business_objects.currency import Currency
from business_objects.store.delivery_option import Delivery_Option
from business_objects.store.discount import Discount
from business_objects.store.image import Image
@@ -309,6 +309,7 @@ class Product_Permutation(db.Model, Store_Base):
'value': self.id_permutation,
'text': self.get_name_variations()
}
def get_name(self):
return
def get_name_variations(self):
@@ -317,19 +318,14 @@ class Product_Permutation(db.Model, Store_Base):
return len(self.prices) > 0
def get_price(self):
return self.prices[0]
def get_price_local_VAT_incl(self):
price = self.get_price()
return price.value_local_VAT_incl
def get_price_local_VAT_excl(self):
price = self.get_price()
return price.value_local_VAT_excl
def output_lead_time(self):
return '1 day' if self.latency_manufacture_days == 1 else f'{self.latency_manufacture_days} days'
def output_delivery_date(self):
return (datetime.now() + timedelta(days=self.latency_manufacture_days)).strftime('%A, %d %B %Y')
"""
def output_lead_time(self):
return '1 day' if self.latency_manufacture_days == 1 else f'{self.latency_manufacture_days} days'
def output_price(self, is_included_VAT):
if self.is_unavailable_in_currency_or_region:
return 'Not available in currency and region'
@@ -341,33 +337,14 @@ class Product_Permutation(db.Model, Store_Base):
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_incl, grouping=True)}'
else:
return f'{price.symbol_currency} {locale.format_string("%d", price.value_local_VAT_excl, grouping=True)}'
def output_currency(self):
if not self.is_available:
return ''
"""
price = self.get_price()
return price.code_currency
"""
return self.code_currency_cost if self.symbol_currency_cost == '' else self.symbol_currency_cost
def output_variations(self):
if not self.has_variations: return ''
return '\n'.join([f'{variation.name_variation_type}: {variation.name_variation}' for variation in self.variations])
def output_variations_jsonify(self):
if not self.has_variations: return ''
return ','.join([f'{variation.id_type}: {variation.id_variation}' for variation in self.variations])
"""
def output_price_VAT_incl(self):
locale.setlocale(locale.LC_ALL, '')
return locale.format_string("%d", self.price_GBP_VAT_incl, grouping=True)
def output_price_VAT_excl(self):
locale.setlocale(locale.LC_ALL, '')
return locale.format_string("%d", self.price_GBP_VAT_excl, grouping=True)
def add_form_basket_add(self):
self.form_basket_add = None
def add_form_basket_edit(self):
self.form_basket_edit = None
"""
def __repr__(self):
return f'''Product_Permutation
id_permutation: {self.id_permutation}

View File

@@ -11,8 +11,8 @@ Business object for product price
"""
# internal
from business_objects.store.currency import Currency
from business_objects.store.delivery_region import Delivery_Region
from business_objects.currency import Currency
from business_objects.region import Region
from business_objects.store.store_base import Store_Base
from extensions import db
# external
@@ -22,8 +22,6 @@ from typing import ClassVar
class Product_Price(db.Model, Store_Base):
NAME_ATTR_OPTION_VALUE: ClassVar[str] = Store_Base.ATTR_ID_PRODUCT_PRICE
NAME_ATTR_OPTION_TEXT = Store_Base.FLAG_TEXT
FLAG_VALUE_LOCAL_VAT_INCL: ClassVar[str] = 'value-local-vat-incl'
FLAG_VALUE_LOCAL_VAT_EXCL: ClassVar[str] = 'value-local-vat-excl'
id_price = db.Column(db.Integer, primary_key=True)
id_permutation = db.Column(db.Integer)
@@ -87,7 +85,7 @@ class Product_Price(db.Model, Store_Base):
self.ATTR_ID_PRODUCT: self.id_product,
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category,
self.FLAG_CURRENCY: self.currency.to_json(),
# Delivery_Region.ATTR_ID_DELIVERY_REGION: self.id_region,
# Region.ATTR_ID_REGION_DELIVERY: self.id_region,
self.FLAG_VALUE_LOCAL_VAT_INCL: self.value_local_VAT_incl,
self.FLAG_VALUE_LOCAL_VAT_EXCL: self.value_local_VAT_excl,
self.FLAG_DISPLAY_ORDER: self.display_order
@@ -101,7 +99,7 @@ class Product_Price(db.Model, Store_Base):
price.id_product = json[cls.ATTR_ID_PRODUCT]
price.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
price.currency = Currency.from_json(json)
# price.id_region = json[Delivery_Region.ATTR_ID_DELIVERY_REGION]
# price.id_region = json[Region.ATTR_ID_REGION_DELIVERY]
price.value_local_VAT_incl = json[cls.FLAG_VALUE_LOCAL_VAT_INCL]
price.value_local_VAT_excl = json[cls.FLAG_VALUE_LOCAL_VAT_EXCL]
price.display_order = json[cls.FLAG_DISPLAY_ORDER]

View File

@@ -82,6 +82,7 @@ class Product_Variation_Tree():
@classmethod
def from_json_str(cls, json_str):
variations = []
if json_str is None or json_str == '': return None
for json_variation in json_str.split(','):
parts = json_variation.split(':')
if len(parts) != 2: continue

View File

@@ -13,13 +13,15 @@ import lib.argument_validation as av
from lib import data_types
from forms.store.stock_item import Filters_Stock_Item
from business_objects.db_base import Get_Many_Parameters_Base
from business_objects.store.product_price import Product_Price
from business_objects.currency import Currency
# from business_objects.discount import Discount
from business_objects.store.product_variation_tree import Product_Variation_Tree
from business_objects.store.storage_location import Storage_Location
from business_objects.store.store_base import Store_Base
from extensions import db
# external
from dataclasses import dataclass
from typing import ClassVar
from typing import ClassVar, Optional
from datetime import datetime
@@ -34,21 +36,19 @@ class Stock_Item(db.Model, Store_Base):
FLAG_DATE_UNSEALED: ClassVar[str] = 'date_unsealed'
FLAG_IS_CONSUMED: ClassVar[str] = 'is_consumed'
FLAG_IS_SEALED: ClassVar[str] = 'is_sealed'
FLAG_VALUE_LOCAL_VAT_EXCL_COST: ClassVar[str] = f'{Product_Price.FLAG_VALUE_LOCAL_VAT_EXCL}_cost'
FLAG_VALUE_LOCAL_VAT_INCL_COST: ClassVar[str] = f'{Product_Price.FLAG_VALUE_LOCAL_VAT_INCL}_cost'
id_stock = db.Column(db.Integer, primary_key=True)
id_permutation = db.Column(db.Integer)
id_product = db.Column(db.Integer)
id_category = db.Column(db.Integer)
# name_category = db.Column(db.String(255))
# name_product = db.Column(db.String(255))
id_location_storage = db.Column(db.Integer)
id_plant = db.Column(db.Integer)
id_region = db.Column(db.Integer)
id_currency_cost = db.Column(db.Integer)
cost_local_VAT_excl = db.Column(db.Float)
cost_local_VAT_incl = db.Column(db.Float)
date_purchased = db.Column(db.DateTime)
date_received = db.Column(db.DateTime)
id_location_storage = db.Column(db.Integer)
id_currency_cost = db.Column(db.Integer)
cost_local_VAT_incl = db.Column(db.Float)
cost_local_VAT_excl = db.Column(db.Float)
is_sealed = db.Column(db.Boolean)
date_unsealed = db.Column(db.DateTime)
date_expiration = db.Column(db.DateTime)
@@ -60,10 +60,15 @@ class Stock_Item(db.Model, Store_Base):
can_edit = db.Column(db.Boolean)
can_admin = db.Column(db.Boolean)
"""
# variation_tree: Product_Variation_Tree = None
def __init__(self):
super().__init__()
Store_Base.__init__(self)
self.currency_cost = None
self.storage_location = None
self.variation_tree = None
self.has_variations = False
def from_DB_stock_item(query_row):
_m = 'Product.from_DB_stock_item'
@@ -73,21 +78,20 @@ class Stock_Item(db.Model, Store_Base):
stock_item.id_permutation = query_row[1]
stock_item.id_product = query_row[2]
stock_item.id_category = query_row[3]
# stock_item.name_category = query_row[4]
# stock_item.name_product = query_row[5]
stock_item.date_purchased = query_row[4]
stock_item.date_received = query_row[5]
stock_item.id_location_storage = query_row[6]
# stock_item.name_location_storage = query_row[9]
stock_item.id_currency_cost = query_row[7]
stock_item.cost_local_VAT_incl = query_row[8]
stock_item.cost_local_VAT_excl = query_row[9]
stock_item.is_sealed = av.input_bool(query_row[10], "is_sealed", _m, v_arg_type=v_arg_type)
stock_item.date_unsealed = query_row[11]
stock_item.date_expiration = query_row[12]
stock_item.is_consumed = av.input_bool(query_row[13], "is_consumed", _m, v_arg_type=v_arg_type)
stock_item.date_consumed = query_row[14]
stock_item.active = av.input_bool(query_row[15], "active", _m, v_arg_type=v_arg_type)
stock_item.id_location_storage = query_row[4]
stock_item.storage_location = Storage_Location.from_DB_stock_item(query_row)
stock_item.id_currency_cost = query_row[12]
stock_item.currency_cost = Currency.from_DB_stock_item(query_row)
stock_item.cost_local_VAT_excl = query_row[15]
stock_item.cost_local_VAT_incl = query_row[16]
stock_item.date_purchased = query_row[17]
stock_item.date_received = query_row[18]
stock_item.is_sealed = av.input_bool(query_row[19], "is_sealed", _m, v_arg_type=v_arg_type)
stock_item.date_unsealed = query_row[20]
stock_item.date_expiration = query_row[21]
stock_item.is_consumed = av.input_bool(query_row[22], "is_consumed", _m, v_arg_type=v_arg_type)
stock_item.date_consumed = query_row[23]
stock_item.active = av.input_bool(query_row[24], "active", _m, v_arg_type=v_arg_type)
"""
stock_item.can_view = av.input_bool(query_row[24], "can_view", _m, v_arg_type=v_arg_type)
stock_item.can_edit = av.input_bool(query_row[25], "can_edit", _m, v_arg_type=v_arg_type)
@@ -99,96 +103,55 @@ class Stock_Item(db.Model, Store_Base):
def from_json(cls, json):
stock_item = cls()
stock_item.id_stock = json[cls.ATTR_ID_STOCK_ITEM]
stock_item.id_permutation = json[cls.ATTR_ID_PRODUCT_PERMUTATION]
stock_item.id_permutation = json.get(cls.ATTR_ID_PRODUCT_PERMUTATION, 0)
stock_item.id_product = json[cls.ATTR_ID_PRODUCT]
stock_item.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY]
print(f'json: {json}\nhalf stock item: {stock_item}')
stock_item.variation_tree = Product_Variation_Tree.from_json_str(json[cls.FLAG_PRODUCT_VARIATIONS])
stock_item.date_purchased = json[cls.FLAG_DATE_PURCHASED]
stock_item.date_received = json[cls.FLAG_DATE_RECEIVED]
stock_item.id_location_storage = json[cls.ATTR_ID_LOCATION_STORAGE]
stock_item.id_location_storage = json[cls.ATTR_ID_STORAGE_LOCATION]
stock_item.id_currency_cost = json[cls.ATTR_ID_CURRENCY_COST]
stock_item.cost_local_VAT_incl = json[cls.FLAG_VALUE_LOCAL_VAT_INCL_COST]
stock_item.cost_local_VAT_excl = json[cls.FLAG_VALUE_LOCAL_VAT_EXCL_COST]
stock_item.cost_local_VAT_excl = json[cls.FLAG_COST_LOCAL_VAT_EXCL]
stock_item.cost_local_VAT_incl = json[cls.FLAG_COST_LOCAL_VAT_INCL]
stock_item.is_sealed = json[cls.FLAG_IS_SEALED]
stock_item.date_unsealed = json[cls.FLAG_DATE_UNSEALED]
stock_item.date_expiration = json[cls.FLAG_DATE_EXPIRATION]
stock_item.is_consumed = json[cls.FLAG_IS_CONSUMED]
stock_item.date_consumed = json[cls.FLAG_DATE_CONSUMED]
stock_item.active = json[cls.FLAG_ACTIVE]
"""
stock_item.can_view = json[cls.FLAG_CAN_VIEW]
stock_item.can_edit = json[cls.FLAG_CAN_EDIT]
stock_item.can_admin = json[cls.FLAG_CAN_ADMIN]
"""
return stock_item
"""
def from_json(json_basket_item, key_id_product, key_id_permutation):
permutation = Product_Permutation.from_json(json_basket_item, key_id_product, key_id_permutation)
product = Product.from_permutation(permutation)
return product
def output_lead_time(self):
return self.get_permutation_selected().output_lead_time()
def output_delivery_date(self):
return self.get_permutation_selected().output_delivery_date()
def output_price(self, is_included_VAT):
return self.get_permutation_selected().output_price(is_included_VAT)
def output_price_VAT_incl(self):
return self.get_permutation_selected().output_price(True)
def output_price_VAT_excl(self):
return self.get_permutation_selected().output_price(False)
def get_price_local(self, is_included_VAT):
if is_included_VAT:
return self.get_price_local_VAT_incl()
else:
return self.get_price_local_VAT_excl()
def get_price_local_VAT_incl(self):
return self.get_permutation_selected().get_price_local_VAT_incl()
def get_price_local_VAT_excl(self):
return self.get_permutation_selected().get_price_local_VAT_excl()
def get_quantity_min(self):
return self.get_permutation_selected().quantity_min
def get_id_permutation(self):
return self.get_permutation_selected().id_permutation
def get_image_from_index(self, index_image):
return self.get_permutation_selected().images[index_image]
def get_name(self):
return self.get_permutation_selected().name
def get_description(self):
return self.get_permutation_selected().description
def output_currency(self):
return self.get_permutation_selected().get_price().symbol_currency
def add_form_basket_add(self):
self.form_basket_add = None
def add_form_basket_edit(self):
self.form_basket_edit = None
"""
def __repr__(self):
return f'''Product
return f'''Stock Item
id_stock: {self.id_stock}
id_permutation: {self.id_permutation}
id_product: {self.id_product}
id_category: {self.id_category}
name: {self.name}
display_order: {self.display_order}
can_view: {self.can_view}
can_edit: {self.can_edit}
can_admin: {self.can_admin}
has_variations: {self.has_variations}
permutations: {self.permutations}
variation trees: {self.variation_trees}
variations: {self.variation_tree.to_preview_str() if self.variation_tree is not None else 'None'}
storage_location: {self.storage_location}
currency: {self.currency_cost}
cost_local_VAT_excl: {self.cost_local_VAT_excl}
cost_local_VAT_incl: {self.cost_local_VAT_incl}
date_purchased: {self.date_purchased}
date_received: {self.date_received}
is_sealed: {self.is_sealed}
date_unsealed: {self.date_unsealed}
date_expiration: {self.date_expiration}
is_consumed: {self.is_consumed}
date_consumed: {self.date_consumed}
active: {self.active}
'''
def to_json(self):
return {
**self.get_shared_json_attributes(self),
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_PRODUCT_PERMUTATION: {self.permutations},
self.FLAG_PRODUCT_VARIATION_TREES: {self.variation_trees},
self.ATTR_ID_STOCK_ITEM: self.id_stock,
self.ATTR_ID_PRODUCT_PERMUTATION: self.id_permutation,
self.ATTR_ID_PRODUCT: self.id_product,
self.ATTR_ID_PRODUCT_CATEGORY: self.id_category,
self.FLAG_STORAGE_LOCATION: self.storage_location.to_json(),
self.FLAG_CURRENCY_COST: self.currency_cost.to_json(),
self.FLAG_COST_LOCAL_VAT_EXCL: self.cost_local_VAT_excl,
self.FLAG_COST_LOCAL_VAT_INCL: self.cost_local_VAT_incl,
}
def has_permutations(self):
return len(self.permutations) > 0
@@ -224,12 +187,11 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
a_ids_region_storage: str
a_get_all_plant_storage: bool
a_get_inactive_plant_storage: bool
a_get_first_plant_storage_only: bool
a_ids_plant_storage: str
a_get_all_location_storage: bool
a_get_inactive_location_storage: bool
a_ids_location_storage: str
a_date_received_to: datetime
a_date_received_to: Optional[datetime] = None
a_get_sealed_stock_item_only: bool
a_get_unsealed_stock_item_only: bool
a_get_expired_stock_item_only: bool
@@ -244,7 +206,7 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
def get_default(cls):
return cls(
# a_id_user = id_user,
a_get_all_product_permutation = True,
a_get_all_product_permutation = False,
a_get_inactive_product_permutation = False,
a_ids_product_permutation = '',
a_get_all_stock_item = True,
@@ -271,3 +233,70 @@ class Parameters_Stock_Item(Get_Many_Parameters_Base):
@classmethod
def from_form_stock_item(cls, form):
return cls.get_default()
class Stock_Item_Temp(db.Model, Store_Base):
__tablename__: ClassVar[str] = 'Shop_Stock_Item_Temp'
__table_args__ = { 'extend_existing': True }
id_stock: int = db.Column(db.Integer, primary_key=True)
# id_category: int = db.Column(db.Integer)
id_product: int = db.Column(db.Integer)
# has_variations: bool = db.Column(db.Boolean)
id_permutation: int = db.Column(db.Integer)
id_pairs_variations: str = db.Column(db.String(4000))
date_purchased: datetime = db.Column(db.DateTime)
date_received: datetime = db.Column(db.DateTime, nullable=True)
id_location_storage: int = db.Column(db.Integer)
id_currency_cost: int = db.Column(db.Integer)
cost_local_VAT_excl: float = db.Column(db.Float)
cost_local_VAT_incl: float = db.Column(db.Float)
is_sealed: bool = db.Column(db.Boolean)
date_unsealed: datetime = db.Column(db.DateTime, nullable=True)
date_expiration: datetime = db.Column(db.DateTime, nullable=True)
is_consumed: bool = db.Column(db.Boolean)
date_consumed: datetime = db.Column(db.DateTime, nullable=True)
active: bool = db.Column(db.Boolean)
guid: str = db.Column(db.String(36))
@classmethod
def from_stock_item(cls, stock_item):
row = cls()
row.id_stock = stock_item.id_stock
# row.id_category = stock_item.id_category
row.id_product = stock_item.id_product
row.id_permutation = stock_item.id_permutation
# row.has_variations = stock_item.has_variations
row.id_pairs_variations = stock_item.variation_tree.to_json_str() if stock_item.variation_tree is not None else ''
row.date_purchased = stock_item.date_purchased
row.date_received = stock_item.date_received if stock_item.date_received else None
row.id_location_storage = stock_item.id_location_storage
row.id_currency_cost = stock_item.id_currency_cost
row.cost_local_VAT_excl = stock_item.cost_local_VAT_excl
row.cost_local_VAT_incl = stock_item.cost_local_VAT_incl
row.is_sealed = 1 if stock_item.is_sealed else 0
row.date_unsealed = stock_item.date_unsealed if stock_item.date_unsealed else None
row.date_expiration = stock_item.date_expiration if stock_item.date_expiration else None
row.is_consumed = 1 if stock_item.is_consumed else 0
row.date_consumed = stock_item.date_consumed if stock_item.date_consumed else None
row.active = 1 if stock_item.active else 0
return row
def __repr__(self):
return f'''
id_stock: {self.id_stock}
id_product: {self.id_product}
id_permutation: {self.id_permutation}
id_pairs_variations: {self.id_pairs_variations}
date_purchased: {self.date_purchased}
date_received: {self.date_received}
id_location_storage: {self.id_location_storage}
id_currency_cost: {self.id_currency_cost}
cost_local_VAT_excl: {self.cost_local_VAT_excl}
cost_local_VAT_incl: {self.cost_local_VAT_incl}
is_sealed: {self.is_sealed}
date_unsealed: {self.date_unsealed}
date_expiration: {self.date_expiration}
is_consumed: {self.is_consumed}
date_consumed: {self.date_consumed}
active: {self.active}
guid: {self.guid}
'''

View File

@@ -12,6 +12,7 @@ Business object for product
# internal
import lib.argument_validation as av
from business_objects.store.plant import Plant
from business_objects.store.store_base import Store_Base
from extensions import db
# external
@@ -28,18 +29,32 @@ class Storage_Location(db.Model, Store_Base):
name = db.Column(db.String(255))
active = db.Column(db.Boolean)
# plant = None
def __init__(self):
super().__init__()
Store_Base.__init__(self)
self.plant = None
@classmethod
def from_DB_storage_location(cls, query_row):
location = cls()
location.id_location = query_row[0]
location.id_plant = query_row[1]
location.plant = Plant.from_DB_storage_location(query_row)
location.code = query_row[2]
location.name = query_row[3]
location.active = query_row[4]
return location
@classmethod
def from_DB_stock_item(cls, query_row):
location = cls()
location.id_location = query_row[4]
location.id_plant = query_row[5]
location.code = query_row[8]
location.name = query_row[9]
location.plant = Plant.from_DB_stock_item(query_row)
return location
def __repr__(self):
return f'''
{self.ATTR_ID_STORAGE_LOCATION}: {self.id_location}
@@ -67,3 +82,6 @@ class Storage_Location(db.Model, Store_Base):
location.name = json[cls.FLAG_NAME],
location.active = json[cls.FLAG_ACTIVE]
return location
def get_full_name(self):
return f'{self.plant.name} - {self.name}'

View File

@@ -58,9 +58,9 @@ class I_Store_Base():
class Store_Base(Base):
# ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost'
ATTR_ID_DELIVERY_OPTION: ClassVar[str] = 'id_delivery_option'
ATTR_ID_DISCOUNT: ClassVar[str] = 'id_discount'
ATTR_ID_IMAGE: ClassVar[str] = 'id_image'
ATTR_ID_LOCATION_STORAGE: ClassVar[str] = 'id_location_storage'
ATTR_ID_PLANT: ClassVar[str] = 'id_plant'
ATTR_ID_PRODUCT: ClassVar[str] = 'id_product'
ATTR_ID_PRODUCT_CATEGORY: ClassVar[str] = 'id_category'
@@ -70,10 +70,15 @@ class Store_Base(Base):
ATTR_ID_PRODUCT_VARIATION: ClassVar[str] = 'id_variation'
ATTR_ID_PRODUCT_VARIATION_TYPE: ClassVar[str] = 'id_type'
ATTR_ID_STOCK_ITEM: ClassVar[str] = 'id_stock_item'
FLAG_CURRENCY: ClassVar[str] = 'currency'
ATTR_ID_STORAGE_LOCATION: ClassVar[str] = 'id_location'
FLAG_COST_LOCAL: ClassVar[str] = 'cost_local'
FLAG_COST_LOCAL_VAT_EXCL: ClassVar[str] = FLAG_COST_LOCAL + '_vat_excl'
FLAG_COST_LOCAL_VAT_INCL: ClassVar[str] = FLAG_COST_LOCAL + '_vat_incl'
FLAG_DELIVERY_OPTION: ClassVar[str] = 'delivery_option'
FLAG_HAS_VARIATIONS: ClassVar[str] = 'has_variations'
FLAG_IS_OUT_OF_STOCK: ClassVar[str] = 'is_out_of_stock'
FLAG_DISCOUNT: ClassVar[str] = 'discount'
FLAG_PLANT: ClassVar[str] = 'plant'
FLAG_PRODUCT: ClassVar[str] = 'product'
FLAG_PRODUCT_CATEGORY: ClassVar[str] = 'product_category'
FLAG_PRODUCT_IMAGE: ClassVar[str] = 'product_image'
@@ -85,6 +90,7 @@ class Store_Base(Base):
FLAG_QUANTITY_MIN: ClassVar[str] = 'quantity_min'
FLAG_QUANTITY_MAX: ClassVar[str] = 'quantity_max'
FLAG_STOCK_ITEM: ClassVar[str] = 'stock_item'
FLAG_STORAGE_LOCATION: ClassVar[str] = 'storage_location'
FLAG_TEXT: ClassVar[str] = 'text'
FLAG_VALUE_TEXT: ClassVar[str] = 'value_text'

View File

@@ -38,7 +38,9 @@ class User(db.Model, Base):
# is_logged_in: bool
def __init__(self):
self.id_user = 0
self.is_logged_in = False
super().__init__()
def from_DB_user(query_row):
_m = 'User.from_DB_user'
@@ -62,7 +64,7 @@ class User(db.Model, Base):
_m = 'User.from_json'
user = User()
if json is None: return user
print(f'json: {json}')
print(f'{_m}\njson: {json}')
user.id_user = json['id_user']
user.id_user_auth0 = json['id_user_auth0']
user.firstname = json['firstname']
@@ -85,7 +87,7 @@ class User(db.Model, Base):
_m = 'User.from_json_auth0'
user = User()
if json is None: return user
print(f'json: {json}')
print(f'{_m}\njson: {json}')
user_info = json['userinfo']
user.id_user = None
user.id_user_auth0 = user_info['sub']
@@ -136,11 +138,6 @@ class User(db.Model, Base):
can_admin_user: {self.can_admin_user}
'''
@staticmethod
def get_default():
user = User()
user.id_user = None
return user
@dataclass

View File

@@ -88,6 +88,11 @@ def services():
def admin_home():
try:
model = Model_View_Admin_Home()
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', callback = Model_View_Admin_Home.HASH_PAGE_ADMIN_HOME))
return redirect(url_for('routes_core.home'))
if not (model.user.can_admin_store or model.user.can_admin_user):
return redirect(url_for('routes_core.home'))
html_body = render_template('pages/core/_admin_home.html', model = model)
except Exception as e:
return jsonify(error=str(e)), 403

View File

@@ -111,6 +111,9 @@ def products():
form_filters = Filters_Product()
print(f'form_filters={form_filters}')
model = Model_View_Store_Product(form_filters)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product.KEY_CALLBACK: Model_View_Store_Product.HASH_PAGE_STORE_PRODUCTS })))
return redirect(url_for('routes_core.home'))
return render_template('pages/store/_products.html', model = model)
@routes_store_product.route(Model_View_Store_Product.HASH_GET_STORE_PRODUCT, methods=['POST'])
@@ -124,6 +127,8 @@ def filter_product():
Model_View_Store_Product.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
})
model = Model_View_Store_Product(form_filters = form_filters)
if not model.is_user_logged_in:
raise Exception('User not logged in')
return jsonify({
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,
Model_View_Store_Product.KEY_DATA: model.category_list.to_json()
@@ -161,6 +166,8 @@ def save_product():
save_errors = Model_View_Store_Product.save_products(data.get('comment', 'No comment'), objsProduct)
model_return = Model_View_Store_Product(form_filters=form_filters)
if not model_return.is_user_logged_in:
raise Exception('User not logged in')
print('nips')
return jsonify({
Model_View_Store_Product.FLAG_STATUS: Model_View_Store_Product.FLAG_SUCCESS,

View File

@@ -54,6 +54,9 @@ def categories():
return redirect(url_for('routes_store_product_category.categories', **filters.to_json()))
"""
model = Model_View_Store_Product_Category(form_filters)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Category.KEY_CALLBACK: Model_View_Store_Product_Category.HASH_PAGE_STORE_PRODUCT_CATEGORIES })))
return redirect(url_for('routes_core.home'))
return render_template('pages/store/_product_categories.html', model = model)
@routes_store_product_category.route(Model_View_Store_Product_Category.HASH_GET_STORE_PRODUCT_CATEGORY, methods=['POST'])
@@ -70,6 +73,8 @@ def filter_category():
# ToDo: manually validate category, product
# filters_form = Filters_Product_Category.from_form(form_filters)
model = Model_View_Store_Product_Category(form_filters = form_filters)
if not model.is_user_logged_in:
raise Exception('User not logged in')
return jsonify({
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
Model_View_Store_Product_Category.KEY_DATA: model.category_list.to_json()
@@ -106,7 +111,8 @@ def save_category():
Model_View_Store_Product_Category.save_categories(data.get('comment', 'No comment'), objsCategory)
model_return = Model_View_Store_Product_Category(form_filters=form_filters)
print('nips')
if not model_return.is_user_logged_in:
raise Exception('User not logged in')
return jsonify({
Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS,
Model_View_Store_Product_Category.KEY_DATA: model_return.category_list.to_json()

View File

@@ -96,6 +96,9 @@ def permutations():
form_filters = Filters_Product_Permutation()
print(f'form_filters={form_filters}')
model = Model_View_Store_Product_Permutation(form_filters)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Product_Permutation.KEY_CALLBACK: Model_View_Store_Product_Permutation.HASH_PAGE_STORE_PRODUCT_PERMUTATIONS })))
return redirect(url_for('routes_core.home'))
return render_template('pages/store/_product_permutations.html', model = model)
@routes_store_product_permutation.route(Model_View_Store_Product_Permutation.HASH_GET_STORE_PRODUCT_PERMUTATION, methods=['POST'])
@@ -109,6 +112,8 @@ def filter_permutation():
Model_View_Store_Product_Permutation.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
})
model = Model_View_Store_Product_Permutation(form_filters = form_filters)
if not model.is_user_logged_in:
raise Exception('User not logged in')
return jsonify({
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,
Model_View_Store_Product_Permutation.KEY_DATA: model.category_list.to_json()
@@ -146,6 +151,8 @@ def save_permutation():
Model_View_Store_Product_Permutation.save_permutations(data.get('comment', 'No comment'), objsPermutation)
model_return = Model_View_Store_Product_Permutation(form_filters=form_filters)
if not model_return.is_user_logged_in:
raise Exception('User not logged in')
print('nips')
return jsonify({
Model_View_Store_Product_Permutation.FLAG_STATUS: Model_View_Store_Product_Permutation.FLAG_SUCCESS,

View File

@@ -11,91 +11,26 @@ Initializes the Flask application, sets the configuration based on the environme
"""
# internal
from business_objects.store.product import Product, Parameters_Product, Product_Permutation
from business_objects.store.stock_item import Stock_Item
from forms.store.stock_item import Filters_Stock_Item
from models.model_view_base import Model_View_Base
from models.model_view_store import Model_View_Store
from models.model_view_store_supplier import Model_View_Store_Supplier
from models.model_view_store_product_category import Model_View_Store_Product_Category
from models.model_view_store_product_permutation import Model_View_Store_Product_Permutation
from models.model_view_store_stock_item import Model_View_Store_Stock_Item
from helpers.helper_app import Helper_App
import lib.argument_validation as av
# external
from datetime import datetime
from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app
from extensions import db, oauth
from urllib.parse import quote_plus, urlencode
from authlib.integrations.flask_client import OAuth
from authlib.integrations.base_client import OAuthError
from urllib.parse import quote, urlparse, parse_qs
import requests
routes_store_stock_item = Blueprint('routes_store_stock_item', __name__)
"""
@routes_store_stock_item.route('/store/stock_items', methods=['GET'])
def stock():
filters = Filters_Stock_Item.get_default()
model = Model_View_Store_Stock_Item(filters_stock_item=filters)
return render_template('pages/store/_stock_items.html', model = model)
@routes_store_stock_item.route('/store/stock_item_filter', methods=['POST'])
def stock_filter():
data = Helper_App.get_request_data(request)
form_filters = None
try:
form_filters = get_Filters_Stock_Items(data)
if not form_filters.validate_on_submit():
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'})
# ToDo: manually validate category, product
filters_form = Filters_Stock_Item.from_form(form_filters)
model = Model_View_Store_Stock_Item(filters_stock_item=filters_form)
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model.category_list.to_permutation_row_list()})
except Exception as e:
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'})
def get_Filters_Stock_Items(data_request):
data_form = data_request[Model_View_Store_Stock_Item.KEY_FORM]
form_filters = Filters_Stock_Item(**data_form)
form_filters.is_out_of_stock.data = av.input_bool(data_form['is_out_of_stock'], 'is_out_of_stock', 'permutations_post')
return form_filters
@routes_store_stock_item.route('/store/stock_item_save', methods=['POST'])
def stock_save():
data = Helper_App.get_request_data(request)
""
form_filters = None
try:
form_filters = get_Filters_Stock_Items(data)
if not form_filters.validate_on_submit():
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'})
stock_items = data[Model_View_Store_Stock.KEY_PERMUTATIONS]
print(f'stock_items: {stock_items}')
if len(stock_items) == 0:
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'No stock items.'})
objsStockItem = []
for stock_item in stock_items:
objsStockItem.append(Product_Permutation.from_json(stock_item))
print(f'objsStockItem: {objsStockItem}')
# ToDo: manually validate category, product
filters_form = Stock_Filters.from_form(form_filters)
model_save = Model_View_Store_Stock(filters_product=filters_form)
model_save.save_stock_items(data.comment, objsPermutation)
model_return = Model_View_Store_Stock(filters_product=filters_form)
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model_return.category_list.to_permutation_row_list()})
except Exception as e:
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'})
""
"""
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS, methods=['GET'])
def permutations():
print('permutations')
def stock_items():
print('stock_items')
try:
form_filters = Filters_Stock_Item.from_json(request.args)
except Exception as e:
@@ -103,19 +38,39 @@ def permutations():
form_filters = Filters_Stock_Item()
print(f'form_filters={form_filters}')
model = Model_View_Store_Stock_Item(form_filters)
return render_template('pages/store/_stock_items.html', model = model)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Stock_Item.KEY_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })))
# return requests.post(f"{current_app.config['URL_HOST']}{url_for('routes_user.login')}", json={ Model_View_Store_Stock_Item.KEY_CALLBACK: Model_View_Store_Stock_Item.HASH_PAGE_STORE_STOCK_ITEMS })
return redirect(url_for('routes_core.home'))
return render_template('pages/store/_stock_items.html', model = model, datetime = datetime)
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_GET_STORE_STOCK_ITEM, methods=['POST'])
def filter_permutation():
def filter_stock_item():
data = Helper_App.get_request_data(request)
try:
form_filters = Filters_Stock_Item.from_json(data)
if not form_filters.validate_on_submit():
error_keys = list(form_filters.errors.keys())
try:
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT_CATEGORY)
"""
if not av.val_int(form_filters.id_product_category.data):
form_filters.errors[Stock_Item.ATTR_ID_PRODUCT_CATEGORY] = ['Invalid category.']
"""
except:
pass
try:
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT)
except:
pass
if error_keys:
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
})
model = Model_View_Store_Stock_Item(form_filters = form_filters)
model = Model_View_Store_Stock_Item(filters_stock_item = form_filters)
if not model.is_user_logged_in:
raise Exception('User not logged in.')
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
Model_View_Store_Stock_Item.KEY_DATA: model.category_list.to_json()
@@ -127,33 +82,55 @@ def filter_permutation():
})
@routes_store_stock_item.route(Model_View_Store_Stock_Item.HASH_SAVE_STORE_STOCK_ITEM, methods=['POST'])
def save_permutation():
def save_stock_item():
data = Helper_App.get_request_data(request)
try:
form_filters = Filters_Stock_Item.from_json(data[Model_View_Store_Stock_Item.FLAG_FORM_FILTERS])
"""
if not form_filters.validate_on_submit():
error_keys = list(form_filters.errors.keys())
try:
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT_CATEGORY)
""
if not av.val_int(form_filters.id_product_category.data):
form_filters.errors[Stock_Item.ATTR_ID_PRODUCT_CATEGORY] = ['Invalid category.']
""
except:
pass
try:
error_keys.remove(Stock_Item.ATTR_ID_PRODUCT)
except:
pass
if error_keys:
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'
})
"""
# filters_form = Filters_Stock_Item.from_form(form_filters)
print(f'form_filters: {form_filters}')
permutations = data[Model_View_Store_Stock_Item.FLAG_STOCK_ITEM]
if len(permutations) == 0:
stock_items = data[Model_View_Store_Stock_Item.FLAG_STOCK_ITEM]
if len(stock_items) == 0:
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'No permutations.'
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'No stock items.'
})
objsPermutation = []
for permutation in permutations:
objsPermutation.append(Stock_Item.from_json(permutation))
print(f'stock_items={stock_items}')
objs_stock_item = []
for stock_item in stock_items:
objs_stock_item.append(Stock_Item.from_json(stock_item))
# model_save = Model_View_Store_Stock_Item() # filters_product=filters_form)
print(f'objsPermutation={objsPermutation}')
Model_View_Store_Stock_Item.save_permutations(data.get('comment', 'No comment'), objsPermutation)
model_return = Model_View_Store_Stock_Item(form_filters=form_filters)
print('nips')
print(f'objs_stock_item={objs_stock_item}')
save_errors = Model_View_Store_Stock_Item.save_stock_items(data.get('comment', 'No comment'), objs_stock_item)
if len(save_errors) > 0:
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_FAILURE,
Model_View_Store_Stock_Item.FLAG_MESSAGE: f'Save errors: {save_errors}'
})
model_return = Model_View_Store_Stock_Item(filters_stock_item=form_filters)
if not model_return.is_user_logged_in:
raise Exception('User not logged in.')
return jsonify({
Model_View_Store_Stock_Item.FLAG_STATUS: Model_View_Store_Stock_Item.FLAG_SUCCESS,
Model_View_Store_Stock_Item.KEY_DATA: model_return.category_list.to_json()

View File

@@ -53,6 +53,9 @@ def supplier():
# if not logged in:
try:
model = Model_View_Store_Supplier(form)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_Store_Supplier.KEY_CALLBACK: Model_View_Store_Supplier.HASH_PAGE_STORE_SUPPLIERS })))
return redirect(url_for('routes_core.home'))
# print('importing basket')
# model.import_JSON_basket(data)
model.get_basket(data)

View File

@@ -170,6 +170,9 @@ def logout_callback():
def user():
try:
model = Model_View_User(current_app, db)
if not model.is_user_logged_in:
# return redirect(url_for('routes_user.login', data = jsonify({ Model_View_User.KEY_CALLBACK: Model_View_User.HASH_PAGE_USER_ACCOUNT })))
return redirect(url_for('routes_core.home'))
html_body = render_template('pages/user/_user.html', model = model)
except Exception as e:
return str(e)

View File

@@ -20,7 +20,7 @@ from business_objects.store.product_category import Product_Category_Container,
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.delivery_region import 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, Parameters_Product # Permutation_Variation_Link
@@ -145,7 +145,7 @@ class DataStore_Base(BaseModel):
result_set_1 = cursor.fetchall()
regions = []
for row in result_set_1:
region = Delivery_Region.make_from_DB_region(row)
region = Region.make_from_DB_region(row)
regions.append(region)
print(f'regions: {regions}')
DataStore_Base.db_cursor_clear(cursor)

View File

@@ -14,10 +14,10 @@ Datastore for Store
# from routes import bp_home
from business_objects.store.basket import Basket, Basket_Item
from business_objects.store.product_category import Product_Category_Container, Product_Category
from business_objects.store.currency import Currency
from business_objects.currency import Currency
from business_objects.store.image import Image
from business_objects.store.delivery_option import Delivery_Option
from business_objects.store.delivery_region import Delivery_Region
from business_objects.region import Region
from business_objects.store.discount import Discount
from business_objects.store.order import Order
from business_objects.store.product import Product, Product_Permutation, Parameters_Product
@@ -235,7 +235,7 @@ class DataStore_Store_Base(DataStore_Base):
result_set_1 = cursor.fetchall()
regions = []
for row in result_set_1:
region = Delivery_Region.from_DB_region(row)
region = Region.from_DB_region(row)
regions.append(region)
print(f'regions: {regions}')
DataStore_Store_Base.db_cursor_clear(cursor)

View File

@@ -15,10 +15,10 @@ Datastore for Store Baskets
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.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.region import 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, Parameters_Product

View File

@@ -14,10 +14,10 @@ Datastore for Store Product Categories
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, Product_Category_Temp
from business_objects.store.currency import Currency
from business_objects.currency import Currency
from business_objects.store.image import Image
from business_objects.store.delivery_option import Delivery_Option
from business_objects.store.delivery_region import Delivery_Region
from business_objects.region import 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, Parameters_Product

View File

@@ -15,10 +15,10 @@ Datastore for Store Product Variations
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.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.region import 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, Parameters_Product

View File

@@ -13,21 +13,10 @@ Datastore for Store Stock Items
# 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, Parameters_Product
from business_objects.sql_error import SQL_Error
from business_objects.store.stock_item import Stock_Item
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_Container
from business_objects.store.stock_item import Stock_Item, Parameters_Stock_Item, Stock_Item_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
@@ -52,11 +41,11 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
super().__init__()
# Stock Items
def get_many_stock_item(self, Parameters_Stock_Item, category_list):
def get_many_stock_item(self, parameters_stock_item, category_list):
# redundant argument validation?
_m = 'DataStore_Store_Stock_Item.get_many_stock_item'
av.val_instance(Parameters_Stock_Item, 'Parameters_Stock_Item', _m, Parameters_Stock_Item)
argument_dict = Parameters_Stock_Item.to_json()
av.val_instance(parameters_stock_item, 'parameters_stock_item', _m, Parameters_Stock_Item)
argument_dict = parameters_stock_item.to_json()
user = self.get_user_session()
"""
argument_dict['a_id_user'] = user.id_user # 'auth0|6582b95c895d09a70ba10fef' # id_user
@@ -67,6 +56,9 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
, **argument_dict
, 'a_debug': 0
}
ids_permutation = category_list.get_csv_ids_permutation()
print(f'ids_permutation: {ids_permutation}')
argument_dict['a_ids_product_permutation'] = ids_permutation
print(f'argument_dict: {argument_dict}')
print('executing p_shop_get_many_stock_item')
result = self.db_procedure_execute('p_shop_get_many_stock_item', argument_dict)
@@ -85,7 +77,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
print(f'raw categories: {result_set_1}')
for row in result_set_1:
new_stock_item = Stock_Item.from_DB_stock_item(row)
category_list.add_stock_item(new_stock_item, row)
category_list.add_stock_item(new_stock_item) # , row)
# Errors
cursor.nextset()
@@ -112,5 +104,47 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base):
if 'region' in error.msg or 'currency' in error.msg:
permutation.is_unavailable_in_currency_or_region = True
"""
DataStore_Store_Stock_Item.db_cursor_clear(cursor)
return category_list, errors # categories, category_index
@classmethod
def save_stock_items(cls, comment, stock_items):
_m = 'DataStore_Store_Stock_Item.save_stock_items'
av.val_str(comment, 'comment', _m)
guid = Helper_DB_MySQL.create_guid_str()
now = datetime.now()
user = cls.get_user_session()
rows = []
for stock_item in stock_items:
# row = permutation.to_temporary_record()
row = Stock_Item_Temp.from_stock_item(stock_item)
row.guid = guid
rows.append(row)
print(f'rows: {rows}')
DataStore_Store_Base.upload_bulk(Stock_Item_Temp.__tablename__, rows, 1000)
print('bulk uploaded')
argument_dict_list = {
'a_comment': comment,
'a_guid': guid,
'a_id_user': user.id_user,
'a_debug': 0
}
result = cls.db_procedure_execute('p_shop_save_stock_item', argument_dict_list)
print('saved product permutations')
# Errors
cursor = result.cursor
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_Store_Stock_Item.db_cursor_clear(cursor)
return errors

View File

@@ -15,10 +15,10 @@ Datastore for Store Stripe service
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.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.region import 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, Parameters_Product

View File

@@ -139,6 +139,76 @@ class DataStore_User(DataStore_Base):
'a_id_user': user.id_user
, 'a_id_user_auth0': user.id_user_auth0
, **user_filters.to_json()
, 'a_debug': 0
}
# argument_dict_list['a_guid'] = guid
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)
"""
query = text(f"SELECT * FROM Shop_Calc_User_Temp UE_T WHERE UE_T.guid = '{guid}'")
result = self.db.session.execute(query)
"""
cursor = result.cursor
result_set = cursor.fetchall()
print(f'raw users: {result_set}')
print(f'type result set: {str(type(result_set))}')
print(f'len result set: {len(result_set)}')
"""
user_permission_evals = []
for row in result_set:
user_permission_eval = User_Permission_Evaluation.from_DB_user_eval(row)
user_permission_evals.append(user_permission_eval)
print(f'user_permission_evals: {user_permission_evals}')
"""
users = []
if len(result_set) > 0:
for row in result_set:
print(f'row: {row}')
user = User.from_DB_user(row)
users.append(user)
print(f'user {str(type(user))}: {user}')
print(f'type users: {str(type(users))}\n type user 0: {str(type(None if len(users) == 0 else users[0]))}')
# error_list, cursor = self.get_error_list_from_cursor(cursor)
errors = []
cursor.nextset()
result_set_e = cursor.fetchall()
print(f'raw errors: {result_set_e}')
if len(result_set_e) > 0:
errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # [SQL_Error(row[0], row[1]) for row in result_set_e]
for error in errors:
print(f"Error [{error.code}]: {error.msg}")
DataStore_User.db_cursor_clear(cursor)
return users, errors
def get_many_user(self, user_filters, user=None):
_m = 'DataStore_User.get_many_user'
print(_m)
# av.val_str(user_filters, 'user_filters', _m)
# av.val_list(permutations, 'list_permutations', _m, Product_Permutation, 1)
av.val_instance(user_filters, 'user_filters', _m, User_Filters)
guid = Helper_DB_MySQL.create_guid()
# now = datetime.now()
# user = self.get_user_session()
"""
argument_dict_list = {
'a_id_user': id_user,
'a_comment': comment,
'a_guid': guid
}
"""
if user is None:
user = self.get_user_session()
argument_dict_list = {
# 'a_guid': guid
'a_id_user': user.id_user
, 'a_id_user_auth0': user.id_user_auth0
, **user_filters.to_json()
, 'a_debug': 0
}
# argument_dict_list['a_guid'] = guid
result = self.db_procedure_execute('p_get_many_user', argument_dict_list)

View File

@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
class Filters_Access_Level(Form_Base):
active = BooleanField("Active only?")
active = BooleanField("Active only?", default = True)
def __repr__(self):
return f'{self.__class__.__name__}(active={self.active.data})'
@classmethod

View File

@@ -122,7 +122,7 @@ class Form_Supplier(FlaskForm):
fax = StringField('Fax number')
website = StringField('Website')
id_currency = SelectField('Currency ID')
is_active = BooleanField('Active')
is_active = BooleanField('Active', default = True)
# class Form_Supplier_Purchase_Order(FlaskForm):
@@ -130,5 +130,5 @@ class Form_Supplier(FlaskForm):
# User
class Form_Filters_User(FlaskForm):
active = BooleanField('Active only?')
active = BooleanField('Active only?', default = True)
id_user = SelectField('User ID', validators=[Optional()], choices=[])

View File

@@ -24,7 +24,7 @@ from flask_wtf.recaptcha import RecaptchaField
class Filters_Product(FlaskForm):
id_category = SelectField('Category', validators=[Optional()], choices=[('', 'All')])
is_not_empty = BooleanField('Not empty only?')
active = BooleanField("Active only?")
active = BooleanField("Active only?", default = True)
@classmethod
def from_filters_product(cls, filters_product):
form = Filters_Product()

View File

@@ -27,7 +27,7 @@ from abc import ABCMeta, abstractmethod
class Filters_Product_Category(Form_Base):
is_not_empty = BooleanField('Not empty only?')
active = BooleanField("Active only?")
active = BooleanField("Active only?", default = True)
"""
@classmethod
def from_filters(cls, filters):

View File

@@ -25,8 +25,8 @@ from flask_wtf.recaptcha import RecaptchaField
from abc import ABCMeta, abstractmethod
class Filters_Stock_Item(Form_Base):
id_category = SelectField('Category', validators=[Optional()], choices=[])
id_product = SelectField('Product', validators=[Optional()], choices=[])
id_category = SelectField('Category', choices=[Form_Base.get_choice_all()], default='')
id_product = SelectField('Product', choices=[Form_Base.get_choice_all()], default='')
is_out_of_stock = BooleanField('Out of stock only?')
quantity_min = FloatField('Min stock')
quantity_max = FloatField('Max stock')
@@ -45,9 +45,9 @@ class Filters_Stock_Item(Form_Base):
@classmethod
def from_json(cls, json):
form = cls()
form.id_category.choices = [(json[Store_Base.ATTR_ID_PRODUCT_CATEGORY], json[Store_Base.ATTR_ID_PRODUCT_CATEGORY])]
# form.id_category.choices = [(json[Store_Base.ATTR_ID_PRODUCT_CATEGORY], json[Store_Base.ATTR_ID_PRODUCT_CATEGORY])]
form.id_category.data = json[Store_Base.ATTR_ID_PRODUCT_CATEGORY]
form.id_product.choices = [(json[Store_Base.ATTR_ID_PRODUCT], json[Store_Base.ATTR_ID_PRODUCT])]
# form.id_product.choices = [(json[Store_Base.ATTR_ID_PRODUCT], json[Store_Base.ATTR_ID_PRODUCT])]
form.id_product.data = json[Store_Base.ATTR_ID_PRODUCT]
form.is_out_of_stock.data = av.input_bool(json[Store_Base.FLAG_IS_OUT_OF_STOCK], Store_Base.FLAG_IS_OUT_OF_STOCK, f'{cls.__name__}.from_json')
form.quantity_min.data = json[Store_Base.FLAG_QUANTITY_MIN]
@@ -66,3 +66,11 @@ class Filters_Stock_Item(Form_Base):
filters = cls()
filters.id_category.choices = cls.get_choices_blank()
filters.id_product.choices = cls.get_choices_blank()
"""
def import_values(self, form_filters):
self.id_category.data = form_filters.id_category.data
self.id_product.data = form_filters.id_product.data
self.is_out_of_stock.data = form_filters.is_out_of_stock.data
self.quantity_min.data = form_filters.quantity_min.data
self.quantity_max.data = form_filters.quantity_max.data
"""

View File

@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
class Filters_Unit_Measurement(Form_Base):
active = BooleanField("Active only?")
active = BooleanField("Active only?", default = True)
@classmethod
def from_filters(cls, filters):
form = Filters_Unit_Measurement()

Some files were not shown because too many files have changed in this diff Show More