Example #1
0
 def setUp(self):
     self.inv = Inventory()
     self.inv.products["orange"] = Product("orange", 2, "food", None, 6)
     self.inv.products["Banana"] = Product("Banana", 2, "food", None, 2)
     self.inv.products["Tako"] = Product("Tako", 2, "food", None, 2)
     self.inv.products["Bamba"] = Product("Bamba", 2, "food", None, 2)
     self.inv.products["Potato"] = Product("Potato", 2, "food", None, 2)
     self.products_list = ["orange", "Banana", "Tako", "Bamba", "Potato"]
Example #2
0
class TestInventory(TestCase):
    def setUp(self):
        self.inv = Inventory()
        self.inv.products["orange"] = Product("orange", 2, "food", None, 6)
        self.inv.products["Banana"] = Product("Banana", 2, "food", None, 2)
        self.inv.products["Tako"] = Product("Tako", 2, "food", None, 2)
        self.inv.products["Bamba"] = Product("Bamba", 2, "food", None, 2)
        self.inv.products["Potato"] = Product("Potato", 2, "food", None, 2)
        self.products_list = ["orange", "Banana", "Tako", "Bamba", "Potato"]

    def test_add_product(self):
        apple = Product("apple", 1, "food", None, 2)
        self.inv.add_product(apple.name, Product("apple", 1, "food", None, 2))
        inv_apple = self.inv.products.get(apple.name)
        self.assertTrue(apple == inv_apple)

    def test_buy_product(self):
        self.assertFalse(self.inv.buy_product("not real product", 1000))
        self.assertTrue(self.inv.buy_product("orange", 5))
        self.assertFalse(self.inv.buy_product("orange", 2))

    def test_get_products(self):
        for product in self.products_list:
            self.assertIn(product, self.inv.get_products())
        self.assertEqual(len(self.inv.get_products()), 5)

    def test_remove_product(self):
        self.assertIn("orange", self.inv.products.keys())
        self.inv.remove_product("orange")
        self.assertNotIn("orange", self.inv.products.keys())
Example #3
0
 def __init__(self, store_id, name, store_owner):
     self.store_id = store_id
     self.name = name
     self.inventory = Inventory()
     self.sale_policy = None
     self.discount_policy = None
     self.store_discounts = []
     self.store_owners = [store_owner]
     self.store_managers = {}  # {manager_name:functions}
     self.sales = []
     self.rate = 0
     self.appointed_by = {store_owner: []}
Example #4
0
 def __init__(self, store_id, name, store_owner, orm=None):
     self.store_id = store_id
     self.name = name
     self.inventory = Inventory()
     self.discounts = {}  # {discount_id: Discount}
     self.discount_idx = 0
     self.purchase_policies = {}  # {purchase_policy_id: PurchasePolicy}
     self.purchases_idx = 0
     self.store_owners = [store_owner]
     self.store_managers = {}  # {manager_name:functions}
     self.sales = []
     self.rate = 0
     self.appointed_by = {store_owner: []}
     if orm is None:
         self.orm = StoreORM()
         self.orm.id = store_id
         self.orm.name = name
         self.orm.discount_index = 0
         self.orm.appoint_owner(store_owner, "")
         self.orm.purchase_index = 0
         self.orm.add()
     else:
         self.orm = orm
     self.publisher = None
Example #5
0
class Store:
    def __init__(self, store_id, name, store_owner, orm=None):
        self.store_id = store_id
        self.name = name
        self.inventory = Inventory()
        self.discounts = {}  # {discount_id: Discount}
        self.discount_idx = 0
        self.purchase_policies = {}  # {purchase_policy_id: PurchasePolicy}
        self.purchases_idx = 0
        self.store_owners = [store_owner]
        self.store_managers = {}  # {manager_name:functions}
        self.sales = []
        self.rate = 0
        self.appointed_by = {store_owner: []}
        if orm is None:
            self.orm = StoreORM()
            self.orm.id = store_id
            self.orm.name = name
            self.orm.discount_index = 0
            self.orm.appoint_owner(store_owner, "")
            self.orm.purchase_index = 0
            self.orm.add()
        else:
            self.orm = orm
        self.publisher = None

    def appoint_owner(self, owner, to_appoint):
        """

        Args:
            owner:
            to_appoint:

        Returns:

        """
        if owner in self.store_owners and \
                to_appoint not in self.store_owners:
            return {
                'error': False,
                'data': self.appoint_owner_helper(owner, to_appoint)
            }
        else:
            logger.error("%s is not a store owner or %s is already owner",
                         owner, to_appoint)
            return {
                'error':
                True,
                'error_msg':
                owner + "is not a store owner or " + to_appoint +
                " is already owner"
            }

    def appoint_owner_helper(self, owner, to_appoint):
        self.store_owners.append(to_appoint)
        self.orm.appoint_owner(owner, to_appoint)
        self.appointed_by[to_appoint] = []
        if to_appoint in self.store_managers:
            self.store_managers.pop(to_appoint)
        self.appointed_by[owner].append(to_appoint)
        return True

    def remove_owner(self, owner, to_remove, publisher: Publisher):
        """

        Args:
            owner:
            to_remove:
            :param owner:
            :param to_remove:
            :param publisher:

        Returns:


        """
        if owner in self.store_owners:
            if to_remove in self.store_owners:
                if owner in self.appointed_by.keys(
                ) and to_remove in self.appointed_by.get(owner):
                    if to_remove in self.appointed_by.keys():
                        self.appointed_by[owner].remove(to_remove)

                        self.__remove_owner_all_appointed(to_remove, publisher)
                        self.orm.remove_owner(to_remove)
                    return {'ans': True, 'desc': 'product has been removed'}
                else:
                    logger.error("%s is not a store owner", owner)
                    return {
                        'ans': False,
                        'desc': to_remove + ' is not a appointed by ' + owner
                    }
            else:
                return {
                    'ans': False,
                    'desc': to_remove + ' is not owner of this store'
                }
        else:
            return {
                'ans': False,
                'desc': to_remove + ' is not owner of this store'
            }

    def remove_manager(self, owner, to_remove):
        """

        Args:
            owner:
            to_remove:

        Returns:

        """
        if owner in self.store_owners:
            if to_remove in self.store_managers.keys():

                if to_remove in self.appointed_by.get(owner):

                    self.appointed_by[owner].remove(to_remove)
                    self.store_managers.pop(to_remove)

                    return {
                        'ans': True,
                        'desc': to_remove + ' is not a manager by ' + owner
                    }

                else:
                    return {
                        'ans': False,
                        'desc': to_remove + ' is not a appointed by ' + owner
                    }
            else:
                return {
                    'ans': False,
                    'desc': to_remove + ' is not a manager of this store'
                }
        else:
            logger.error("%s is not a store owner", owner)
            return {
                'ans': False,
                'desc': owner + ' is not an owner of this store'
            }

    def __remove_owner_all_appointed(self, to_remove, publisher):

        if to_remove in self.store_owners:
            self.store_owners.remove(to_remove)
            # send notification to user to_remove.
            publisher.store_ownership_update(self.store_id, self.name,
                                             [to_remove])
        if to_remove in self.store_managers.keys():
            self.store_managers.pop(to_remove)
        if to_remove in self.appointed_by.keys():
            for own_or_man in self.appointed_by[to_remove]:
                self.__remove_owner_all_appointed(own_or_man, publisher)
                self.appointed_by.pop(to_remove)

    def add_permission_to_manager(self, owner, manager, permission):
        """

        Args:
            owner:
            manager:
            permission:

        Returns:

        """
        if owner in self.store_owners:
            if manager in self.appointed_by.get(owner):
                if manager in self.store_managers.keys():
                    # permission_function = getattr(Store, permission)
                    if permission not in self.store_managers.get(manager):
                        self.store_managers[manager].append(permission)
                        self.orm.add_permission(manager, permission)
                        return {
                            'error': False,
                            'data':
                            permission + ' has been added to ' + manager
                        }
                    else:
                        return {
                            'error': True,
                            'error_msg':
                            manager + ' has already this permission'
                        }

                else:
                    return {
                        'error': True,
                        'error_msg': manager + ' is not a manager'
                    }

            else:
                return {
                    'error': True,
                    'error_msg': manager + ' not appointed by ' + owner
                }

        else:
            logger.error("%s is not a store owner", owner)
            return {
                'error': True,
                'error_msg': owner + ' is not an owner of this store'
            }

    def remove_permission_from_manager(self, owner, manager, permission):
        """

        Args:
            owner:
            manager:
            permission:

        Returns:

        """

        if owner in self.store_owners:
            if manager in self.store_managers.keys():
                if manager in self.appointed_by[owner]:
                    # permission_function = getattr(Store, permission)
                    if permission in self.store_managers.get(manager):
                        self.store_managers[manager].remove(permission)
                        self.orm.remove_permission(manager, permission)
                        return {
                            'error':
                            False,
                            'data':
                            permission + ' has been removed from ' + manager
                        }

                    else:
                        return {
                            'error': True,
                            'error_msg': manager + ' dont has this permission'
                        }

                else:
                    return {
                        'error': True,
                        'error_msg': manager + ' not appointed by ' + owner
                    }
            else:
                return {
                    'error': False,
                    'error_msg': manager + ' is not a manager'
                }

        else:
            logger.error("%s is not a store owner", owner)
            return {
                'error': True,
                'error_msg': owner + 'is not an owner of this store'
            }

    def appoint_manager(self, owner, to_appoint):
        """

        Args:
            owner: user that in the owners list
            to_appoint: user that should be appoint to manager

        Returns:

        """
        if owner in self.store_owners:
            if to_appoint not in self.store_managers.keys():
                self.store_managers[to_appoint] = [
                    getattr(Store, "get_sales_history")
                ]
                self.appointed_by[owner].append(to_appoint)
                self.orm.appoint_manager(owner, to_appoint)
                return {
                    'error': False,
                    'data': to_appoint + ' has become a manager'
                }
            else:
                return {
                    'error': True,
                    'error_msg': to_appoint + ' is already a manager'
                }
        else:
            logger.error("%s is not a store owner", owner)
            return {
                'error': True,
                'error_msg': to_appoint + ' is not an owner'
            }

    def add_product(self, user_name: str, product_name: str,
                    product_price: int, product_categories, key_words: [str],
                    amount):
        """

        Args:
            user_name:the user who wants to add product, should be a owner
                or a manager with permission
            product_name:product name
            product_price:product price
            product_categories:
            key_words:

        Returns:

        """
        if self.is_owner(user_name) or self.check_permission(
                user_name, 'update_products'):
            self.inventory.add_product(
                product_name,
                Product(product_name, product_price, product_categories,
                        key_words, amount, self.store_id))
            return {'error': False, 'data': "Product has been added"}
        else:
            logger.error("%s Don't have this permission", user_name)
            return {'error': True, 'error_msg': "User don't have permission"}

    def search(self,
               search_term: str = "",
               categories=[],
               key_words=[]) -> [Product]:
        """

        Args:
            search_term: part of the wanted product name
            categories: categories to search in
            key_words:
        Returns:
                list of products
        """
        result = []
        for product_name in self.inventory.get_products().keys():
            if search_term in product_name:
                result.append(self.inventory.get_products().get(product_name))

        if len(categories) > 0:
            result = [
                product for product in result if any(
                    category in product.categories for category in categories)
            ]

        if len(key_words) > 0:
            result = [
                product for product in result
                if any(key_word in product.key_words for key_word in key_words)
            ]

        result = deepcopy(result)
        self.products_after_discount(result)
        return result

    def products_after_discount(self, result):
        for product in result:
            for discount in self.discounts.values():
                product.original_price = discount.get_updated_price(product)

    def buy_product(self, product_name, amount):
        res = self.inventory.buy_product(product_name, amount)
        return res

    def get_sales_history(self, user, is_admin) -> [Purchase]:
        if self.check_permission(user, 'view_purchase_history') or is_admin:
            self.sales = self.orm.getPurchases()
            return {'error': False, 'data': self.sales}
        return {'error': True, 'error_msg': 'User dont have the permission'}

    def update_product(self, user, product_name, attribute, updated):
        if self.check_permission(user, "update_products"):
            return {
                'error':
                not self.inventory.update_product(product_name, attribute,
                                                  updated),
                'data':
                'updated'
            }
        logger.error("%s don't have this permission", user)
        return {
            'error': True,
            'error_msg': user + " don't have this permission"
        }

    def add_new_sale(self, purchase: Purchase, publisher: Publisher):
        """

         Args:

             purchase: Holds the store products bought by the user
         Returns:
                 True if @new_sale was added to @self.sales list, else false
                 :param purchase:
                 :param publisher:
         """
        if purchase is not None:
            self.sales.append(purchase)
            # send notification to owners.
            publisher.purchase_update(self.store_id, self.name,
                                      self.store_owners)
            return {'error': False, 'data': 'sale has been added'}
        return {'error': True, 'error_msg': 'sale has not been added'}

    def check_permission(self, user, function):
        return user in self.store_owners or \
               (user in self.store_managers and function in self.store_managers.get(user))

    def get_store_products(self):
        return {'ans': True, 'desc': self.inventory.get_products()}

    def remove_product(self, product_name, username):
        if self.is_owner(username) or self.check_permission(
                username, "update_products"):
            return {
                'error': not self.inventory.remove_product(product_name),
                'data': 'product removed'
            }
        return {
            'error': True,
            'error_msg': username + ' do not have permission'
        }

    def add_visible_product_discount(self, permitted_username,
                                     discount: Discount):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            self.discount_idx += 1
            discount.id = self.discount_idx
            self.discounts[self.discount_idx] = discount
            discount.set_id(self.discount_idx)
            return {'error': False, 'data': {'discount_id': self.discount_idx}}
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def add_conditional_discount_to_product(self, permitted_username,
                                            discount):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            self.discount_idx += 1
            discount.id = self.discount_idx
            self.discounts[self.discount_idx] = discount
            discount.set_id(self.discount_idx)
            return {'error': False, 'data': {'discount_id': self.discount_idx}}
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def add_conditional_discount_to_store(self, permitted_username, discount):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            self.discount_idx += 1
            discount.id = self.discount_idx
            self.discounts[self.discount_idx] = discount
            discount.set_id(self.discount_idx)
            return {'error': False, 'data': {'discount_id': self.discount_idx}}
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def add_composite_discount(self, permitted_username: str,
                               discount: Discount):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            self.discount_idx += 1
            discount.id = self.discount_idx
            self.discounts[self.discount_idx] = discount
            discount.set_id(self.discount_idx)
            return {'error': False, 'data': {'discount_id': self.discount_idx}}
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def edit_visible_discount(self, permitted_username, discount_id,
                              start_date, end_date, percent):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            discount = self.discounts[discount_id]
            return {
                'error':
                not discount.edit_discount(start_date, end_date, percent),
                'data': 'done'
            }
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def edit_conditional_discount_to_product(self, permitted_username: str,
                                             discount_id: int, start_date,
                                             end_date, percent,
                                             min_amount: int,
                                             nums_to_apply: int):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            discount = self.discounts[discount_id]
            return {
                'error':
                not discount.edit_discount(discount_id, start_date, end_date,
                                           percent, min_amount, nums_to_apply),
                'data':
                'done'
            }
        return {
            'error': True,
            'error_msg': permitted_username + ' do not have this permission'
        }

    def edit_conditional_discount_to_store(self, permitted_username: str,
                                           discount_id: int, start_date,
                                           end_date, percent: int,
                                           min_price: int):
        if self.is_owner(permitted_username) or self.check_permission(
                permitted_username, 'update_discounts'):
            discount: ConditionalStoreDiscount = self.discounts[discount_id]
            return discount.edit_discount(discount_id, start_date, end_date,
                                          percent, min_price)
        return False

    def is_owner(self, username):
        if username in self.store_owners:
            return True
        return False

    def get_updated_basket(self, basket):
        product_price_dict = {}
        for product in basket.values():
            product_price_dict[product[0].name] = (
                product[0], product[1], product[0].get_price_by_amount(
                    product[1]), product[0].original_price * product[1]
            )  # {product_name, (amount, updated_price)}

        for discount in self.discounts.values():
            discount.commit_discount(product_price_dict)

        return product_price_dict  # {product_name, (Product, amount, updated_price, original_price)}

    def add_product_to_discount(self, permitted_user: str, discount_id: int,
                                product_name: str):
        is_permitted = self.is_owner(permitted_user) or self.check_permission(
            permitted_user, 'update_discounts')
        is_in_inventory = product_name in self.inventory.products.keys()
        discount: Discount = self.discounts[discount_id]
        if is_permitted and is_in_inventory:
            discount.add_product(product_name)
            return {
                'error': False,
                'data': 'product has been added to discount'
            }
        return {
            'error': True,
            'error_msg': permitted_user + ' do not has this permission'
        }

    def remove_product_from_discount(self, permitted_user, discount_id,
                                     product_name):
        is_permitted = self.is_owner(permitted_user) or self.check_permission(
            permitted_user, 'update_discounts')
        is_in_inventory = product_name in self.inventory.products.keys()
        discount: Discount = self.discounts[discount_id]
        if is_permitted and is_in_inventory:
            discount.remove_product(product_name)
            return {'error': False, 'data': 'product has been removed'}

        return {
            'error': True,
            'error_msg': permitted_user + ' do not has this permission'
        }

    def add_purchase_store_policy(self, permitted_user, min_amount_products,
                                  max_amount_products):
        MAX_SIZE = 100000
        MIN_SIZE = 0

        if min_amount_products is None and max_amount_products is None:
            return {'ans': False, 'desc': "The parameters are not valid \n"}
        if not self.check_permission(permitted_user, 'update_policy'):
            return {'ans': False, 'desc': "User dont have permission\n"}

        min_amount = MIN_SIZE if min_amount_products is None else min_amount_products
        max_amount = MAX_SIZE if max_amount_products is None else max_amount_products
        self.purchases_idx += 1

        policy = PurchaseStorePolicy(min_amount, max_amount,
                                     self.purchases_idx)
        self.purchase_policies[self.purchases_idx] = policy
        policy.set_id(self.purchases_idx)

        return {'error': False, 'data': "Policy as been added"}

    def add_purchase_product_policy(self, permitted_user, min_amount_products,
                                    max_amount_products):
        MAX_SIZE = 100000
        MIN_SIZE = 0

        if min_amount_products is None and max_amount_products is None:
            return {
                'error': True,
                'error_msg': "The parameters are not valid \n"
            }
        if not self.check_permission(permitted_user, 'update_policy'):
            return {'error': True, 'error_msg': "User dont have permission\n"}

        min_amount = MIN_SIZE if min_amount_products is None else min_amount_products
        max_amount = MAX_SIZE if max_amount_products is None else max_amount_products
        self.purchases_idx += 1

        policy = PurchaseProductPolicy(min_amount, max_amount,
                                       self.purchases_idx)
        print("add_purchase_product_policy: policy")
        print(policy)
        self.purchase_policies[self.purchases_idx] = policy
        policy.set_id(self.purchases_idx)

        return {
            'error': False,
            'data': {
                'msg': "Policy as been added",
                'policy_id': policy.id
            }
        }

    def add_purchase_composite_policy(self, permitted_user: str,
                                      policies: list,
                                      logic_operator: LogicOperator):
        if not self.check_permission(permitted_user, 'update_policy'):
            return {'error': True, 'error_msg': "User dont have permission\n"}

        self.purchases_idx += 1

        for policy in policies:
            del self.purchase_policies[policy.id]

        policy = PurchaseCompositePolicy(policies, logic_operator,
                                         self.purchases_idx)
        self.purchase_policies[self.purchases_idx] = policy
        policy.set_id(self.purchases_idx)

        return {'error': False, 'data': "Policy as been added"}

    def add_policy_to_purchase_composite_policy(self, permitted_user: str,
                                                composite_id, policy_id: int):
        if composite_id not in self.purchase_policies.keys(
        ) or policy_id not in self.purchase_policies.keys():
            return {
                'error': True,
                'error_msg': "One of the policies is not exist for this store"
            }

        if not self.check_permission(permitted_user, 'update_policy'):
            return {
                'error': True,
                'error_msg': "policy is not exist for this store\n"
            }

        self.purchase_policies[composite_id].add_policy(
            self.purchase_policies[policy_id])
        return {'error': False, 'data': "Policy as been added"}

    def add_product_to_purchase_product_policy(self, policy_id,
                                               permitted_user: str,
                                               product_name: str):
        if policy_id not in self.purchase_policies.keys():
            return {
                'error': True,
                'error_msg': "policy is not exist for this store\n"
            }

        if not self.check_permission(permitted_user, 'update_policy'):
            return {
                'error': True,
                'error_msg': "policy is not exist for this store\n"
            }

        self.purchase_policies[policy_id].add_product(product_name)
        return {'error': False, 'data': "Product has been added to policy"}

    def remove_product_from_purchase_product_policy(self, policy_id,
                                                    permitted_user,
                                                    product_name):
        if policy_id is None:
            return {'error': True, 'error_msg': "No such policy"}
        if policy_id not in self.purchase_policies.keys():
            return {
                'error': True,
                'error_msg': "policy is not exist for this store\n"
            }
        if not self.check_permission(permitted_user, 'update_policy'):
            return {'error': True, 'error_msg': "User dont have permission\n"}
        self.purchase_policies[policy_id].remove_product(product_name)
        return {
            'error': False,
            'data': product_name + " has been removed from policy \n"
        }

    def get_discounts(self):
        return {'ans': True, 'desc': self.discounts}

    def get_discount_by_id(self, discount_id):
        if discount_id in self.discounts.keys():
            return {'ans': False, 'discount': self.discounts[discount_id]}

    def get_purchase_policies(self):
        return {'ans': True, 'desc': self.purchase_policies}

    def get_purchase_policy_by_id(self, purchase_policy_id: int):
        if purchase_policy_id is None:
            return {'ans': False, 'desc': "No such policy"}

        if purchase_policy_id not in self.purchase_policies.keys():
            return {'ans': False, 'desc': "No such policy"}

        if purchase_policy_id in self.purchase_policies.keys():
            return {
                'ans': True,
                'desc': self.purchase_policies[purchase_policy_id]
            }
            # return self.purchase_policies[purchase_policy_id]

    def check_basket_validity(self, basket):
        is_approved = True
        description = ""
        for policy in self.purchase_policies.values():

            p_approved, outcome = policy.is_approved(basket)
            if not p_approved:
                description += outcome
                is_approved = False

        for product_name in basket.keys():
            valid = self.is_valid_amount(product_name, basket[product_name])
            if valid['error'] is True:
                description += valid['error_msg']
                is_approved = False

        return is_approved, description

    def remove_purchase_policy(self, policy_id, permitted_user):
        if policy_id is None or permitted_user is None:
            return {'ans': False, 'desc': "The parameters are not valid \n"}

        if policy_id not in self.purchase_policies.keys():
            return {'ans': False, 'desc': "No such policy in this store \n"}

        del self.purchase_policies[policy_id]
        return {'ans': True, 'desc': "Policy has been removed \n"}

    def get_description(self):
        id = self.store_id
        inventory_description = self.get_inventory_description()
        discount_description = self.get_discounts()
        purchase_policies_description = self.get_purchase_policies()
        store_owners = self.store_owners
        store_managers = self.store_managers.keys()

        description = [
            id, inventory_description, discount_description,
            purchase_policies_description, store_owners, store_managers
        ]

        return description

    def get_inventory_description(self):
        return self.inventory

    def get_product(self, product_name):
        return self.inventory.get_product(product_name)

    def get_store_managers(self):
        # store_managers_dict = {}
        # for manager in self.store_managers.keys():
        #     store_managers_dict[manager] = []
        #     for perm in self.store_managers[manager]:
        #         store_managers_dict[manager].append(perm)
        return {'error': False, 'data': list(self.store_managers.keys())}

    def get_user_permissions(self, username):
        permissions = {'username': username}
        return_val = {}
        if username in self.store_owners:
            permissions['permissions'] = self.get_all_permissions()
            return_val['error'] = False
            return_val['data'] = permissions
        else:
            if username in self.store_managers.keys():
                permissions['permissions'] = self.store_managers[username]
                return_val['error'] = False
                return_val['data'] = permissions
            else:
                return_val['error'] = True
                return_val[
                    'error_msg'] = 'The user' + username + 'does not have any permissions.'
        return return_val

    def get_all_permissions(self):
        return [
            "update_products", "update_policy", "update_discounts",
            "edit_owners", "appoint_owner", "edit_managers",
            "apporint_managers", "view_purchase_history"
        ]

    def is_valid_amount(self, product_name, quantity):
        return self.inventory.is_valid_amount(product_name, quantity)
Example #6
0
class Store:
    def __init__(self, store_id, name, store_owner):
        self.store_id = store_id
        self.name = name
        self.inventory = Inventory()
        self.sale_policy = None
        self.discount_policy = None
        self.store_discounts = []
        self.store_owners = [store_owner]
        self.store_managers = {}  # {manager_name:functions}
        self.sales = []
        self.rate = 0
        self.appointed_by = {store_owner: []}

    def appoint_owner(self, owner, to_appoint):
        """

        Args:
            owner:
            to_appoint:

        Returns:

        """
        if owner in self.store_owners and \
                to_appoint not in self.store_owners:
            return self.appoint_owner_helper(owner, to_appoint)
        else:
            logger.error("%s is not a store owner or %s is already owner", owner, to_appoint)
            return False

    def appoint_owner_helper(self, owner, to_appoint):
        self.store_owners.append(to_appoint)
        self.appointed_by[to_appoint] = []
        if to_appoint in self.store_managers:
            self.store_managers.pop(to_appoint)
        self.appointed_by[owner].append(to_appoint)
        return True

    def remove_owner(self, owner, to_remove):

        """

        Args:
            owner:
            to_remove:

        Returns:

        """
        if owner in self.store_owners:
            if to_remove in self.store_owners:
                if owner in self.appointed_by.keys() and to_remove in self.appointed_by.get(owner):
                    if to_remove in self.appointed_by.keys():
                        self.appointed_by[owner].remove(to_remove)
                        self.__remove_owner_all_appointed(to_remove)
                    return True
                else:
                    logger.error("%s is not a store owner", owner)
                    return False
            else:
                return False

        else:
            return False

    def remove_manager(self, owner, to_remove):

        """

        Args:
            owner:
            to_remove:

        Returns:

        """
        if owner in self.store_owners:
            if to_remove in self.store_managers.keys():

                if to_remove in self.appointed_by.get(owner):

                    self.appointed_by[owner].remove(to_remove)
                    self.store_managers.pop(to_remove)

                    return True
                else:
                    return False
            else:
                return False

        else:
            logger.error("%s is not a store owner", owner)
            return False

    def __remove_owner_all_appointed(self, to_remove):

        if to_remove in self.store_owners:
            self.store_owners.remove(to_remove)
        if to_remove in self.store_managers.keys():
            self.store_managers.pop(to_remove)
        if to_remove in self.appointed_by.keys():
            for own_or_man in self.appointed_by[to_remove]:
                self.__remove_owner_all_appointed(own_or_man)
                self.appointed_by.pop(to_remove)

    def add_permission_to_manager(self, owner, manager, permission):
        """

        Args:
            owner:
            manager:
            permission:

        Returns:

        """
        if owner in self.store_owners:
            if manager in self.appointed_by.get(owner):
                if manager in self.store_managers.keys():
                    permission_function = getattr(Store, permission)
                    if permission_function not in self.store_managers.get(manager):
                        self.store_managers[manager].append(permission_function)
                        return True
                    else:
                        return False
                else:
                    return False
            else:
                return False
        else:
            logger.error("%s is not a store owner", owner)
            return False

    def remove_permission_from_manager(self, owner, manager, permission):
        """

        Args:
            owner:
            manager:
            permission:

        Returns:

        """

        if owner in self.store_owners:
                if manager in self.store_managers.keys():
                    if manager in self.appointed_by[owner]:
                        permission_function = getattr(Store, permission)
                        if permission_function in self.store_managers.get(manager):
                            self.store_managers[manager].remove(permission_function)
                            return True
                        else:
                            return False
                    else:
                        return False
                else:
                    return False
        else:
            logger.error("%s is not a store owner", owner)
            return False

    def appoint_manager(self, owner, to_appoint):
        """

        Args:
            owner: user that in the owners list
            to_appoint: user that should be appoint to manager

        Returns:

        """
        if owner in self.store_owners:
            if to_appoint not in self.store_managers.keys():
                self.store_managers[to_appoint] = [getattr(Store, "get_sales_history")]
                self.appointed_by[owner].append(to_appoint)
                return True
            else:
                return False
        else:
            logger.error("%s is not a store owner", owner)
            return False

    def add_product(self, user_name: str, product_name: str, product_price: int, product_categories,
                    key_words: [str], amount) -> bool:
        """

        Args:
            user_name:the user who wants to add product, should be a owner
                or a manager with permission
            product_name:product name
            product_price:product price
            product_categories:
            key_words:

        Returns:

        """
        if self.check_permission(user_name, getattr(Store, "add_product")):
            self.inventory.add_product(product_name,
                                       Product(product_name, product_price, product_categories, key_words, amount))
            return True
        else:
            logger.error("%s Don't have this permission", user_name)
            return False

    def search(self, search_term: str = "", categories: [str] = [], key_words: [str] = []) -> [Product]:
        """

        Args:
            search_term: part of the wanted product name
            categories: categories to search in
            key_words:
        Returns:
                list of products
        """
        result = []
        for product_name in self.inventory.get_products().keys():
            if search_term in product_name:
                result.append(self.inventory.get_products().get(product_name))

        if len(categories)>0:
            result = [product for product in result if any(category in product.categories for category in categories)]

        if len(key_words)>0:
            result = [product for product in result if any(key_word in product.key_words for key_word in key_words)]

        return result

    def buy_product(self, product_name, amount):
        return self.inventory.buy_product(product_name, amount)

    def get_sales_history(self, user, is_admin) -> [Purchase]:
        if self.check_permission(user, getattr(Store, "get_sales_history")) or is_admin:
            return self.sales

    def update_product(self, user, product_name, attribute, updated):
        if self.check_permission(user, getattr(Store, "update_product")):
            return self.inventory.update_product(product_name, attribute, updated)
        logger.error("%s don't have this permission", user)
        return False

    def add_new_sale(self, purchase: Purchase) -> bool:
        """

         Args:

             purchase: Holds the store products bought by the user
         Returns:
                 True if @new_sale was added to @self.sales list, else false
         """
        if purchase is not None:
            self.sales.append(purchase)
            return True
        return False

    def check_permission(self, user, function):
        return user in self.store_owners or \
               (user in self.store_managers and function in self.store_managers.get(user))

    def get_store_products(self):
        return self.inventory.get_products()

    def remove_product(self, product_name, username):
        if self.is_owner(username) or self.check_permission(username, getattr(Store, "remove_product")):
            return self.inventory.remove_product(product_name)
        return False

    def add_discount_to_product(self, product_name, permitted_username,  discount):
        if self.is_owner(permitted_username) or self.check_permission(permitted_username, getattr(Store, "add_discount_to_product")):
            return self.inventory.add_discount_to_product(product_name, discount)
        return False

    def edit_discount(self, product_name, permitted_username, discount_id):
        if self.is_owner(permitted_username) or self.check_permission(permitted_username, getattr(Store, "edit_product_discount")):
            return self.inventory.edit_product_discount(product_name, discount_id)

    def add_store_discount(self, permitted_username, discount):
        if self.is_owner(permitted_username) or self.check_permission(permitted_username, getattr(Store, "add_store_discount")):
            self.store_discounts.append(discount)

    def is_owner(self, username):
        if username in self.store_owners:
            return True
        return False
Example #7
0
 def setUp(self):
     self.inv = Inventory()
     self.inv.products = {"orange": Product("orange", 2, "food", None, 2)}
Example #8
0
class TestInventory(unittest.TestCase):
    def setUp(self):
        self.inv = Inventory()
        self.inv.products = {"orange": Product("orange", 2, "food", None, 2)}

    def test_add_product(self):
        apple = Product("apple", 1, "food", None, 2)
        self.inv.add_product(apple.name, Product("apple", 1, "food", None, 2))
        inv_apple = self.inv.products.get(apple.name)
        self.assertTrue(apple == inv_apple)

    def test_update_product(self):
        self.inv.update_product("orange", "price", 5)
        self.assertEqual(5, self.inv.products.get("orange").price)
        self.inv.update_product("not real product", "price", 5)

    def test_remove_product(self):
        self.assertIn("orange", self.inv.products.keys())
        self.inv.remove_product("orange")
        self.assertNotIn("orange", self.inv.products.keys())

    def test_buy_product(self):
        self.assertFalse(self.inv.buy_product("not real product", 1000))
        self.assertFalse(self.inv.buy_product("orange", 5))
        self.assertTrue(self.inv.buy_product("orange", 2))