def remove_product(self): if not PrintLists().print_products( ProductManager().get_product_list()): return False id = PrintInputs.enter_product_id( ProductManager().get_product_list()[-1].id) product_remove = ProductManager().remove_product(id) if product_remove: PrinterStatemants.print_product_removed() return True else: PrinterStatemants.print_not_found(id, 'product') return False
def __init__(self, database): """ DatabaseUpdater constructor. Creates instances of table manager classes. Runs _run() method. """ self.product_manager = ProductManager(database) self.category_manager = CategoryManager(database) self.product_category_manager = ProductCategoryManager(database) self.store_manager = StoreManager(database) self.product_store_manager = ProductStoreManager(database) self._run(database)
def add_product(self): product = PrintInputs.enter_product() product_add = ProductManager().add_product(product) if product_add: PrinterStatemants.print_product_added() return True else: return False
def setUp(self): """ Setup test data """ engine = create_engine('sqlite:///test_products.sqlite') #Creates all the tables Base.metadata.create_all(engine) Base.metadata.bind = engine self.logPoint() self._product_manager = ProductManager("test_products.sqlite") computer1 = Computer("Huawei Matebook X Pro", 1600, 1200, "07/18/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") self._product_manager.add_product(computer1) cellphone5 = Cellphone("Pixel 4", 1000, 500, "03/21/2018", "04/21/2019", True, "G Camera", "Google Lock", 88) self._product_manager.add_product(cellphone5)
def edit_product(self): if not PrintLists().print_products( ProductManager().get_product_list()): return False id = PrintInputs.enter_product_id( ProductManager().get_product_list()[-1].id) product = PrintInputs.enter_product() product = { 'id': id, 'name': product['name'], 'price': product['price'], 'quantity': product['quantity'] } product_edit = ProductManager().edit_product(product) if product_edit: PrinterStatemants.print_product_updated() return True else: PrinterStatemants.print_not_found(id, 'product') return False
def __init__(self, database): """ DatabaseFiller constructor. For each category and for each nutrition grade, retrieves corresponding products from Open Food Facts API and adds them to local database. """ # self.database = database # Creates instances of table manager classes self.product_manager = ProductManager(database) self.category_manager = CategoryManager(database) self.product_category_manager = ProductCategoryManager(database) self.store_manager = StoreManager(database) self.product_store_manager = ProductStoreManager(database) for nutrition_grade in nutrition_grades: for category in tag_categories: products = self._get_products(category, nutrition_grade) self._fill_db(products)
def sending_products(self): # Product objects created in the previous method are saved; save() method from ProductManager class is called. ten_products_result = self.ten_products(self.popular_categories()) product_manager = ProductManager() product_manager.save(ten_products_result) product_manager.saving_categories(ten_products_result)
class TestProductManager(TestCase): _product_manager = None def setUp(self): """ Setup test data """ engine = create_engine('sqlite:///test_products.sqlite') #Creates all the tables Base.metadata.create_all(engine) Base.metadata.bind = engine self.logPoint() self._product_manager = ProductManager("test_products.sqlite") computer1 = Computer("Huawei Matebook X Pro", 1600, 1200, "07/18/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") self._product_manager.add_product(computer1) cellphone5 = Cellphone("Pixel 4", 1000, 500, "03/21/2018", "04/21/2019", True, "G Camera", "Google Lock", 88) self._product_manager.add_product(cellphone5) def logPoint(self): currentTest = self.id().split('.')[-1] callingFunction = inspect.stack()[1][3] print('in %s - %s()' % (currentTest, callingFunction)) def tearDown(self): """ Destroys test data """ os.remove("test_products.sqlite") self.logPoint() def test_add(self): """ 010A - Valid add """ all_products = self._product_manager.get_all() self.assertTrue(len(all_products) == 2) """Add to products""" computer3 = Computer("Macbook Pro", 2000, 1500, "05/19/2019", "09/22/2019", True, "A13 Bionic", "Dbrand", "DDR4") self._product_manager.add_product(computer3) all_products = self._product_manager.get_all() self.assertTrue(len(all_products) == 3) def test_add_invalid(self): """ 010B - Invalid add """ undefined_computer = None self.assertRaisesRegex(ValueError, "Product cannot be none.", self._product_manager.add_product, undefined_computer) def test_get_product_by_id(self): """ 020A - Valid get """ computer1 = self._product_manager.get_product_by_id(1) self.assertEqual("Huawei Matebook X Pro", computer1.get_name()) cellphone5 = self._product_manager.get_product_by_id(2) self.assertEqual("Pixel 4", cellphone5.get_name()) def test_get_product_by_id_invalid(self): """ 020B - Invalid get """ not_number_id = "not number" self.assertRaisesRegex(ValueError, "ID is not a number!", self._product_manager.get_product_by_id, not_number_id) def test_get_all(self): """ 030A - Valid get_all """ products = self._product_manager.get_all() self.assertEqual(2, len(products)) for product in products: product_name = product.get_name() if product.get_id() == 1: self.assertEqual("Huawei Matebook X Pro", product_name) if product.get_id() == 2: self.assertEqual("Pixel 4", product_name) def test_get_all_by_type(self): """ 040A - Valid get_all_by_type """ computers = self._product_manager.get_all_by_type( AbstractProduct.COMPUTER_TYPE) cellphones = self._product_manager.get_all_by_type( AbstractProduct.CELLPHONE_TYPE) self.assertEqual(1, len(computers)) self.assertEqual(1, len(cellphones)) self.assertEqual("Huawei Matebook X Pro", computers[0].get_name()) self.assertEqual("Pixel 4", cellphones[0].get_name()) def test_get_all_by_type_invalid(self): """ 040B - Invalid get_all_by_type """ undefined_type = None self.assertRaisesRegex(ValueError, "Type cannot be undefined.", self._product_manager.get_all_by_type, undefined_type) def test_update(self): """ 050A - Valid update """ computer1 = Computer("Huawei Matebook X Pro", 1600, 1200, "07/18/2019", None, False, "Nvidia Geforce", "Dbrand", "DDR4") id = self._product_manager.add_product(computer1) old_computer_price = computer1.get_price() new_computer_price = old_computer_price + 100 computer1.set_price(new_computer_price) self._product_manager.update_product(computer1) updated_computer = self._product_manager.get_product_by_id(id) self.assertEqual(computer1.get_name(), updated_computer.get_name()) self.assertEqual(new_computer_price, updated_computer.get_price()) def test_update_invalid(self): """ 050B - Invalid update """ undefined_computer = None self.assertRaisesRegex(ValueError, "Product cannot be none.", self._product_manager.update_product, undefined_computer) def test_delete(self): """ 060A - Valid delete """ products = self._product_manager.get_all() computer1 = products[0] self.assertEqual(AbstractProduct.COMPUTER_TYPE, computer1.get_type()) self.assertEqual(1, computer1.get_id()) self.assertEqual("Huawei Matebook X Pro", computer1.get_name()) id = computer1.get_id() self._product_manager.remove_product_by_id(id) deleted = True products = self._product_manager.get_all() for product in products: if product.get_id() == id: deleted = False break self.assertTrue(deleted) def test_delete_invalid(self): """ 060B - Invalid delete """ not_number_id = "not number" self.assertRaisesRegex(ValueError, "ID is not a number!", self._product_manager.remove_product_by_id, not_number_id) def test_get_product_stats(self): """ 070A - Valid get_product_stats """ computer2 = Computer("IBM Thinkpad", 1400, 1000, "07/18/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") computer3 = Computer("Macbook Pro", 2000, 1000, "04/11/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") cellphone2 = Cellphone("iPhone 11 Pro Max", 2000, 500, "07/18/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") cellphone3 = Cellphone("Samsung Galaxy Note 10", 1400, 400, "07/18/2019", "08/21/2019", True, "Nvidia Geforce", "Dbrand", "DDR4") self._product_manager.add_product(computer2) self._product_manager.add_product(computer3) self._product_manager.add_product(cellphone2) self._product_manager.add_product(cellphone3) product_stats = self._product_manager.get_product_stats() num_products = product_stats.get_total_num_products() num_computers = product_stats.get_num_computers() num_cellphones = product_stats.get_num_cellphones() avg_computer_profit = product_stats.get_avg_computer_profit() avg_cellphone_profit = product_stats.get_avg_cellphone_profit() avg_computer_shelf_time = product_stats.get_avg_computer_shelf_time() avg_cellphone_shelf_time = product_stats.get_avg_cellphone_shelf_time() self.assertEqual(6, num_products) self.assertEqual(3, num_computers) self.assertEqual(3, num_cellphones) self.assertEqual(600, avg_computer_profit) self.assertEqual(1000, avg_cellphone_profit) self.assertEqual(66, avg_computer_shelf_time) self.assertEqual(154, avg_cellphone_shelf_time)
class DatabaseUpdater: """ Sets DatabaseUpdater class. Consists of 14 private methods : - __init__() - _run() - _get_products_codes() - _get_OFF_product() - _update_new_information() - _update_categories_information() - _get_local_product_categories_information() - _remove_obsolete_categories() - _add_new_categories() - _update_stores_information() - _get_local_product_stores_information() - _remove_obsolete_stores() - _add_new_stores() - _save_update_date() """ def __init__(self, database): """ DatabaseUpdater constructor. Creates instances of table manager classes. Runs _run() method. """ self.product_manager = ProductManager(database) self.category_manager = CategoryManager(database) self.product_category_manager = ProductCategoryManager(database) self.store_manager = StoreManager(database) self.product_store_manager = ProductStoreManager(database) self._run(database) def _run(self, database): """ Manages database update. For each product of local database, checks information & updates if necessary. Saves update date. """ codes = self._get_products_codes(database) for i in range(len(codes.all())): try: self._get_OFF_product(codes, i) local_product = self.product_manager.\ select_product_information(self.OFF_code) self._update_new_information(local_product) self._update_categories_information(local_product) self._update_stores_information(local_product) except KeyError as e: print('Aïe, KeyError : ', e, file=open('print_log.txt', 'a')) self._save_update_date() def _get_products_codes(self, database): """ Manages product codes retrieving. Returns 'codes' object containing product id for all products of the local database. """ codes = database.query('''SELECT Product.product_id FROM Product''') return codes def _get_OFF_product(self, codes, i): """ Manages product information retrieving. For a given product code, collects product information from Open Food Facts API using get() method from request library. """ response = get(f'''https://fr.openfoodfacts.org/api/v0/product/\ {codes[i]['product_id']}.json''') data = response.json() OFF_product = data['product'] self.OFF_code = OFF_product['code'] self.OFF_name = OFF_product['product_name'].strip().capitalize() self.OFF_description = OFF_product['generic_name'].capitalize() OFF_brands = (OFF_product['brands']).split(',') self.OFF_brand = OFF_brands[0].capitalize() OFF_categories_to_strip = (OFF_product['categories']).split(',') self.OFF_categories = [] for category in OFF_categories_to_strip: self.OFF_categories.append(category.strip().capitalize()) OFF_stores_to_strip = (OFF_product['stores']).split(',') self.OFF_stores = [] for store in OFF_stores_to_strip: self.OFF_stores.append(store.strip().capitalize()) self.OFF_nutrition_grade = OFF_product['nutrition_grades'].lower() def _update_new_information(self, local_product): """ Manages information updating, except categories and stores. Compares product information from local database vs. from Open Food Facts API. Updates information when needed. """ if local_product[0]['name'] != self.OFF_name: self.product_manager.update_name(self.OFF_name, self.OFF_code) print('"name" updated !', file=open('print_log.txt', 'a')) if local_product[0]['description'] != self.OFF_description: self.product_manager.update_description(self.OFF_description, self.OFF_code) print('"description" updated !', file=open('print_log.txt', 'a')) if local_product[0]['brand'] != self.OFF_brand: self.product_manager.update_brand(self.OFF_brand, self.OFF_code) print('"brand" updated !', file=open('print_log.txt', 'a')) if local_product[0]['nutrition_grade'] != self.OFF_nutrition_grade: self.product_manager.update_nutrition_grade( self.OFF_nutrition_grade, self.OFF_code) print('"nutrition_grade" updated !', file=open('print_log.txt', 'a')) def _update_categories_information(self, local_product): """ Manages categories information updating. - Retrieves categories information for local product. - Removes obsolete categories from local database. - Adds new categories from Open Food Facts into local database. """ local_product_categories_id, local_product_categories_list = \ self._get_local_product_categories_information() self._remove_obsolete_categories(local_product, local_product_categories_id, local_product_categories_list) self._add_new_categories(local_product_categories_list) def _get_local_product_categories_information(self): """ Manages retrieving of categories information. Returns categories id object & list of categories name for local product. """ local_product_categories_id = self.product_category_manager.\ select_based_on_product_id(self.OFF_code) local_product_categories_list = [] for i in range(len(local_product_categories_id.all())): category_name = self.category_manager.select_based_on_id( local_product_categories_id[i]['category_id']) local_product_categories_list.append(category_name) return local_product_categories_id, local_product_categories_list def _remove_obsolete_categories(self, local_product, local_product_categories_id, local_product_categories_list): """ Manages obsolete categories removing. Removes categories from local database which don't appear anymore in Open Food Facts platform. """ for i in range(len(local_product_categories_list)): if local_product_categories_list[i] not in self.OFF_categories: self.product_category_manager.delete( self.OFF_code, local_product_categories_id[i]['category_id']) product_category = self.product_category_manager.\ select_based_on_category_id( local_product_categories_id[i]['category_id']) try: category_id = product_category[0]['category_id'] # with open('print_log.txt', 'a') as f: print(f'La catégorie {category_id} est associée à \ d\'autre(s) produit(s). On la conserve.', file=open('print_log.txt', 'a')) except IndexError: # with open('print_log.txt', 'a') as f: print('La catégorie n\'est associée à aucun autre \ produit. On la supprime', file=open('print_log.txt', 'a')) self.category_manager.delete( local_product_categories_list[i]) def _add_new_categories(self, local_product_categories_list): """ Manages new categories addition. Adds new categories from Open Food Facts platform into local database. """ for category in self.OFF_categories: if category not in local_product_categories_list: local_category = self.category_manager.\ select_based_on_name(category) try: local_category_name = local_category[0]['name'] self.product_category_manager.insert( local_category_name, self.OFF_name) except IndexError: print('La catégorie n\'existe pas', file=open('print_log.txt', 'a')) self.category_manager.insert(category) self.product_category_manager.insert( category, self.OFF_name) def _update_stores_information(self, local_product): """ Manages stores information updating. - Retrieves stores information for local product. - Removes obsolete stores from local database. - Adds new stores from Open Food Facts into local database. """ local_product_stores_id, local_product_stores_list = \ self._get_local_product_stores_information() self._remove_obsolete_stores(local_product, local_product_stores_id, local_product_stores_list) self._add_new_stores(local_product_stores_list) def _get_local_product_stores_information(self): """ Manages retrieving of stores information. Returns stores id object & list of stores name for local product. """ local_product_stores_id = self.product_store_manager.\ select_based_on_product_id(self.OFF_code) local_product_stores_list = [] for i in range(len(local_product_stores_id.all())): store_name = self.store_manager.select_based_on_id( local_product_stores_id[i]['store_id']) local_product_stores_list.append(store_name) return local_product_stores_id, local_product_stores_list def _remove_obsolete_stores(self, local_product, local_product_stores_id, local_product_stores_list): """ Manages obsolete stores removing. Removes stores from local database which don't appear anymore in Open Food Facts platform. """ for i in range(len(local_product_stores_list)): if local_product_stores_list[i] not in self.OFF_stores: self.product_store_manager.delete( self.OFF_code, local_product_stores_id[i]['store_id']) product_store = self.product_store_manager.\ select_based_on_store_id( local_product_stores_id[i]['store_id']) try: store_id = product_store[0]['store_id'] print(f'Le magasin {store_id} est associé à \ d\'autre(s) produit(s). On le conserve.', file=open('print_log.txt', 'a')) except IndexError: print('Le magasin n\'est associé à aucun autre \ produit. On le supprime', file=open('print_log.txt', 'a')) self.store_manager.delete(local_product_stores_list[i]) def _add_new_stores(self, local_product_stores_list): """ Manages new stores addition. Adds new stores from Open Food Facts platform into local database. """ for store in self.OFF_stores: if store not in local_product_stores_list: local_store = self.store_manager.select_based_on_name(store) try: local_store_name = local_store[0]['name'] self.product_store_manager.insert(local_store_name, self.OFF_name) except IndexError: print('Le magasin n\'existe pas', file=open('print_log.txt', 'a')) self.store_manager.insert(store) self.product_store_manager.insert(store, self.OFF_name) def _save_update_date(self): """ Manages saving of database update date. Saves the date into an external 'last_update.txt' file. """ update_date = str(time()) with open('last_update.txt', "w") as f: f.write(update_date)
from product_manager import ProductManager from utils import is_not_valid_input, clrscr, to_valid_price if __name__ == "__main__": clrscr() product_manager = ProductManager() while True: command = input(">>> ").strip() if command == "/exit": break if command == "/clrscr": clrscr() elif command == "/help": print("/help: Display this help menu") print("/exit: Quit program") print("/clrscr: Clear screen") print("/all: Show all products") print("/del: Delete a product") print("/save: Save all products down to hardrive") print("[index]: Display information about product at index") print("[query_name]: Search products with similar name") print("[product_name]=[product_price]: Add product") elif command == "/all": product_manager.show()
from response import Response import login_config CONFIG = login_config.get_config() database_connector = DatabaseConnector(database=CONFIG.DB, host=CONFIG.HOST, user=CONFIG.USER, password=CONFIG.PASSWORD) database_connector.create_database(CONFIG.DB) database_connector.create_tables() connection = database_connector.get_connection() item_manager = ItemManager(database_connector) tag_manager = TagManager(database_connector) s3_resource = AwsConnector(CONFIG.BOTO3_PROFILE).get_s3_resource() image_manager = ImageManager(s3_resource, CONFIG.BUCKET) product_manager = ProductManager(item_manager, tag_manager, image_manager) application = Flask(__name__) application.secret_key = CONFIG.SECRET_KEY login_manager = LoginManager() login_manager.init_app(application) js = Bundle('js/helper.js', 'js/add-products.js', 'js/lettering.js', 'js/front-page.js', 'js/search.js', 'js/ajax.js', 'js/setup.js', output='gen/main.js')
from product_manager import ProductManager from print_inputs import PrintInputs from print_lists import PrintLists from accountancy import Accountancy from print_statements import PrinterStatemants product_manager = ProductManager() class Buyer: def choose_product(self, page): products_paginate = product_manager.get_product_list(page) products = products_paginate['products'] last_page = products_paginate['last_page'] index = PrintLists.print_products_paginate(products, page, last_page) if len(products) == 0: return False if (page - 1) >= 1: if index == 8: if not self.choose_product(page - 1): return False if index == 9: return False if not page == last_page: if index == 10: if not self.choose_product(page + 1): return False if len(products) < index: PrinterStatemants().print_not_found(index, 'product') return self.choose_product(page) quantity = PrintInputs.ask_quantity() product_price = product_manager.get_product_list(page)['products'][
from flask import Flask, request from product_manager import ProductManager from product_stats import ProductStats from abstract_product import AbstractProduct from cellphone import Cellphone from computer import Computer import json app = Flask(__name__) prod_manager = ProductManager("products.sqlite") @app.route('/product_manager/products', methods=['POST']) def add_product(): """ Adds a product to products """ content = request.json try: id = None type = None product = None if content["type"] == AbstractProduct.CELLPHONE_TYPE: cellphone = Cellphone(content['name'], content['price'], content['cost'], content["date_stocked"], content["date_sold"], content["is_sold"], content["camera"], content["security"], content["screen_body_ratio"]) prod_manager.add_product(cellphone) id = cellphone.get_id() type = cellphone.get_type() product = cellphone elif content["type"] == AbstractProduct.COMPUTER_TYPE:
class DatabaseFiller: """ Sets DatabaseFiller class. Consists of 3 private methods : - __init__() - _get_products() - _fill_db() """ def __init__(self, database): """ DatabaseFiller constructor. For each category and for each nutrition grade, retrieves corresponding products from Open Food Facts API and adds them to local database. """ # self.database = database # Creates instances of table manager classes self.product_manager = ProductManager(database) self.category_manager = CategoryManager(database) self.product_category_manager = ProductCategoryManager(database) self.store_manager = StoreManager(database) self.product_store_manager = ProductStoreManager(database) for nutrition_grade in nutrition_grades: for category in tag_categories: products = self._get_products(category, nutrition_grade) self._fill_db(products) def _get_products(self, category, nutrition_grade): """ Return a list of dictionnaries of products information. Connects to Open Food Facts API via get() method from requests library and sends requests using given criteria for categories and nutrition grades. json content from response object contains products information. """ criteria = { 'action': 'process', 'json': 1, 'countries': 'France', 'page_size': 100, 'page': 1, 'tagtype_0': 'categories', 'tag_contains_0': 'contains', 'tag_0': category, 'tagtype_1': 'nutrition_grades', 'tag_contains_1': 'contains', 'tag_1': nutrition_grade } response = get('https://fr.openfoodfacts.org/cgi/search.pl', params=criteria) data = response.json() # 'products' is a list of dictionnaries products = data['products'] return products def _fill_db(self, products): """ Manages database filling. Checks for each product whether required data is available or not. If so, product is added to local database. """ for product in products: try: self.code = product['code'] self.name = product['product_name'].strip().capitalize() self.description = product['generic_name'].capitalize() brands = (product['brands']).split(',') self.brand = brands[0].capitalize() self.url = product['url'] categories_to_strip = (product['categories']).split(',') self.categories = [] for category in categories_to_strip: self.categories.append(category.strip().capitalize()) stores_to_strip = (product['stores']).split(',') self.stores = [] for store in stores_to_strip: self.stores.append(store.strip().capitalize()) self.nutrition_grade = product['nutrition_grades'].lower() except KeyError: print('Missing data', file=open('print_log.txt', 'a')) if all([ self.code, self.name, self.description, self.brand, self.url, self.nutrition_grade, self.categories[0], self.stores[0] ]): self.product_manager.insert(self.code, self.name, self.description, self.brand, self.url, self.nutrition_grade) for category in self.categories: self.category_manager.insert(category) self.product_category_manager.insert(category, self.name) for store in self.stores: self.store_manager.insert(store) self.product_store_manager.insert(store, self.name)