""" Project: PARTS Website Author: Edward Middleton-Smith Precision And Research Technology Systems Limited Technology: Business Objects Feature: Product Category Business Object Description: Business object for product """ # IMPORTS # VARIABLE INSTANTIATION # CLASSES # METHODS # IMPORTS # internal import lib.argument_validation as av from lib import data_types from forms import Form_Basket_Add, Form_Basket_Edit # Form_Product from business_objects.product import Product, Product_Permutation, Price from business_objects.variation import Variation from business_objects.image import Image from business_objects.delivery_option import Delivery_Option from business_objects.discount import Discount # external from enum import Enum from datetime import datetime, timedelta import locale from flask_sqlalchemy import SQLAlchemy # VARIABLE INSTANTIATION db = SQLAlchemy() # CLASSES class Enum_Product_Category(Enum): ASSISTIVE_DEVICES = 0 HOME_DECOR = 1 MISCELLANEOUS = 99 def text(self): return Enum_Product_Category.Enum_Product_Category_Text(self) def Enum_Product_Category_Text(category): av.val_instance(category, 'category', 'Product_Category_Enum_Text', Enum_Product_Category) if category == Enum_Product_Category.ASSISTIVE_DEVICES: return 'Assistive devices' elif category == Enum_Product_Category.HOME_DECOR: return 'Home decor' else: return 'Other' def get_member_by_text(text): av.val_str(text, 'text', 'Enum_Product_Category.get_member_by_text') return data_types.get_enum_member_by_text(Enum_Product_Category, text.upper()) class Category(db.Model): id_category = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255)) description = db.Column(db.String(4000)) display_order = db.Column(db.Integer) """ def __new__(cls, id, name, description, display_order): _m = 'Category.__new__' v_arg_type = 'class attribute' av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type) av.val_str(name, 'name', _m, max_len=256, v_arg_type=v_arg_type) av.val_str(description, 'description', _m, max_len=4001, v_arg_type=v_arg_type) av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) return super(Category, cls).__new__(cls) """ def __init__(self): # , id, name, description, display_order): """ self.id_category = id self.name = name self.description = description self.display_order = display_order """ self.products = [] self.product_index = {} super().__init__() def make_from_DB_product(query_row): category = Category() category.id_category = query_row[0] category.name = query_row[1] category.description = query_row[2] category.display_order = query_row[3] return category """ def key_product_index_from_ids_product_permutation(id_product, id_permutation): return f'{id_product},{"" if id_permutation is None else id_permutation}' def key_product_index_from_product(product): av.val_instance(product, 'product', 'Category.key_product_index_from_product', Product) return f'{product.id_product},{"" if product.id_permutation is None else product.id_permutation}' """ def get_index_product(self, product): return self.get_index_product_from_id(product.id_product) def get_index_product_from_id(self, id_product): try: return self.product_index[id_product] except: raise KeyError(f'product id: {id_product} not in product index keys: {self.product_index.keys()} with category id: {self.id_category}') def get_index_product_from_id_permutation(self, id_permutation): for product in self.products: try: index_permutation = product.get_index_permutation_from_id(id_permutation) return self.get_index_product(product) except: pass raise KeyError(f'permutation id: {id_permutation} not in category id: {self.id_category}') def add_product(self, product): _m = 'Category.add_product' av.val_instance(product, 'product', _m, Product) # self.product_index.append(len(self.products)) # self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products) try: self.get_index_product(product) raise ValueError(f"{av.error_msg_str(product, 'product', _m, Product)}\nProduct already in category.") except KeyError: self.product_index[product.id_product] = len(self.products) self.products.append(product) def add_permutation(self, permutation): _m = 'Category.add_permutation' av.val_instance(permutation, 'permutation', _m, Product_Permutation) # self.product_index.append(len(self.products)) # self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products) index_product = self.get_index_product_from_id(permutation.id_product) # index_product = self.product_index[permutation.id_product] self.products[index_product].add_permutation(permutation) def add_variation(self, variation): av.val_instance(variation, 'variation', 'Category.add_variation', Variation) index_product = self.get_index_product_from_id(variation.id_product) self.products[index_product].add_variation(variation) def add_price(self, price): av.val_instance(price, 'price', 'Category.add_price', Price) index_product = self.get_index_product_from_id(price.id_product) self.products[index_product].add_price(price) def add_image(self, image): av.val_instance(image, 'image', 'Category.add_image', Image) index_product = self.get_index_product_from_id(image.id_product) self.products[index_product].add_image(image) def add_delivery_option(self, delivery_option): av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option) index_product = self.get_index_product_from_id(delivery_option.id_product) self.products[index_product].add_delivery_option(delivery_option) def add_discount(self, discount): av.val_instance(discount, 'discount', 'Category.add_discount', Discount) index_product = self.get_index_product_from_id(discount.id_product) self.products[index_product].add_discount(discount) def get_all_variation_trees(self): for product in self.products: if product.has_variations: print(f'product with id:{product.id_product} has variations') product.get_variation_trees() """ def index_product_from_ids_product_permutation(self, id_product, id_permutation): key = Category.key_product_index_from_ids_product_permutation(id_product, id_permutation) print(f'product_index: {self.product_index}') print(f'Key Error: {key}') try: return self.product_index[key] except KeyError: pass """ def __repr__(self): return f''' id: {self.id_category} name: {self.name} description: {self.description} display_order: {self.display_order} products: {self.products} ''' def get_permutation_first(self): if not (len(self.products) == 0): print(f'getting first permutation from product') return None if len(self.products) == 0 else self.products[0].get_permutation_selected() def is_available(self): if len(self.products) == 0: return False for product in self.products: if product.is_available(): return True return False class Product_Category_Filters(): category_ids: str # csv product_ids: str # csv def __new__(cls, product_ids, product_categories): # Initialiser - validation _m = 'Product_Filters.__new__' v_arg_type = 'class attribute' # av.val_list_instances(product_ids, 'product_ids', _m, str, v_arg_type=v_arg_type) # av.val_list_instances(product_categories, 'product_categories', _m, Product_Category_Enum, v_arg_type=v_arg_type) av.val_str(product_ids, 'product_ids', _m, v_arg_type=v_arg_type) av.val_str(product_categories, 'product_categories', _m, v_arg_type=v_arg_type) return super(Product_Category_Filters, cls).__new__(cls) def __init__(self, product_ids, product_categories): # Constructor self.ids = product_ids self.categories = product_categories class Category_List(): categories: list def __init__(self): self.categories = [] def add_category(self, category): av.val_instance(category, 'category', 'Category_List.add_category', Category) self.categories.append(category) def get_index_category_from_id(self, id_category): for index_category in range(len(self.categories)): category = self.categories[index_category] if category.id_category == id_category: return index_category raise ValueError(f"{av.error_msg_str(id_category, 'id_category', 'Category_List.get_index_category_from_id', int)}\nID not in list") def get_index_category_from_id_permutation(self, id_permutation): for index_category in range(len(self.categories)): category = self.categories[index_category] try: index_product = category.get_index_product_from_id_permutation(id_permutation) return index_category except: pass raise ValueError(f"{av.error_msg_str(id_permutation, 'id_permutation', 'Category_List.get_index_category_from_id_permutation', int)}. Permutation ID not in list") def add_product(self, product): av.val_instance(product, 'product', 'Category_List.add_product', Product) index_category = self.get_index_category_from_id(product.id_category) self.categories[index_category].add_product(product) def add_permutation(self, permutation): av.val_instance(permutation, 'permutation', 'Category_List.add_permutation', Product_Permutation) index_category = self.get_index_category_from_id(permutation.id_category) self.categories[index_category].add_permutation(permutation) def add_variation(self, variation): av.val_instance(variation, 'variation', 'Category.add_variation', Variation) index_category = self.get_index_category_from_id(variation.id_category) self.categories[index_category].add_variation(variation) def add_price(self, price): av.val_instance(price, 'price', 'Category.add_price', Price) index_category = self.get_index_category_from_id(price.id_category) self.categories[index_category].add_price(price) def add_image(self, image): av.val_instance(image, 'image', 'Category.add_image', Image) index_category = self.get_index_category_from_id(image.id_category) self.categories[index_category].add_image(image) def add_delivery_option(self, delivery_option): av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option) index_category = self.get_index_category_from_id(delivery_option.id_category) self.categories[index_category].add_delivery_option(delivery_option) def add_discount(self, discount): av.val_instance(discount, 'discount', 'Category.add_discount', Discount) index_category = self.get_index_category_from_id(discount.id_category) self.categories[index_category].add_discount(discount) def get_all_variation_trees(self): for category in self.categories: category.get_all_variation_trees() def __repr__(self): return f'categories: {self.categories}' def get_permutation_first(self): print(f'getting first permutation from category list') if not (len(self.categories) == 0): print(f'getting first permutation from category') return None if len(self.categories) == 0 else self.categories[0].get_permutation_first() def get_count_categories(self): return len(self.categories)