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
Example #6
0
    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)
Example #7
0
    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)
Example #10
0
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()
Example #11
0
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')
Example #12
0
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:
Example #14
0
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)