class SalesOrderLogic(object):
    def __init__(self, sales_order):
        self.sales_order = sales_order
        self.stock = ProductStockManagement(self.sales_order).stock

    def update_purchased_order_stock(self):
        from purchasing.models import PurchasedOrder

        for purchased_order_id, stock in self.stock.items():
            # here is another example where the we need to do a field update in a non-elegant fashion to bypass the
            # save() method when using sqlite
            if self._get_purchased_order(purchased_order_id):
                PurchasedOrder.objects.filter(id=purchased_order_id).update(
                    in_stock=stock)

    # this methods check if we have enough products in stock before we make the final sale
    def validate_if_in_stock(self):
        if self.sales_order.quantity > sum(self.stock.values()):
            raise Exception(
                'There is not enough in stock for product with id {}'.format(
                    self.sales_order.product.id))

    @staticmethod
    def _get_purchased_order(purchased_order_id):
        from purchasing.models import PurchasedOrder

        try:
            PurchasedOrder.objects.get(id=purchased_order_id)
        except PurchasedOrder.DoesNotExist:
            return False
        else:
            return True
    def _validate_if_product_is_being_sold(purchased_order, original_quantity):
        """
          Check if the purchased order is on the process of being sold
        """
        stock = ProductStockManagement(purchased_order).stock

        if original_quantity != stock.get(str(purchased_order.id)):
            raise Exception(
                "You can't perform the following action because this order with id: {} is in the process of being "
                "sold".format(purchased_order.id))
Exemple #3
0
    def set_sold_out_purchased_orders(instance, **kwargs):
        from purchasing.models import PurchasedOrder

        stock = ProductStockManagement(instance).stock

        for purchased_product_id, quantity in stock.items():
            # if the quantity has been reduced to 0, it means it has been sold out. Therefore, we must update the
            # sold_out field to True
            if quantity == 0:
                PurchasedOrder.objects.filter(id=purchased_product_id).update(
                    sold_out=True)
Exemple #4
0
def generate_inventory_products():
    for product in Product.objects.all():
        purchased_order = PurchasedOrder.objects.filter(product=product)
        total_qty_purchased = purchased_order.aggregate(Sum('quantity')).get('quantity__sum')
        total_qty_sold = SalesOrder.objects.filter(product=product).aggregate(Sum('quantity')).get('quantity__sum')
        total_qty_expired = purchased_order.filter(expired=True).aggregate(Sum('quantity')).get('quantity__sum')
        total_qty_in_stock = sum(ProductStockManagement(purchased_order.first()).stock.values())
        profit = (total_qty_sold * product.unit_price) - (total_qty_purchased * product.unit_cost)

        InventoryProduct.objects.create(
            product=product,
            total_qty_purchased=total_qty_purchased,
            total_qty_sold=total_qty_sold,
            total_qty_expired=total_qty_expired,
            total_qty_in_stock=total_qty_in_stock,
            profit=profit
        )
    def find_and_update_expired_purchased_orders():
        from purchasing.models import PurchasedOrder

        # This one line SQL query could find all the expired products and set their expired field to True, but it can't
        # be used with sqlite3. One additional benefit of this approach is that we can run the update method on the
        # query set causing the method .save() to never be called.
        # PurchasedOrder.objects.filter(
        #     sold_out=False,
        #     expired=False,
        #     purchased_date__lt=timezone.now() - timedelta(days=1) * F("product__shelf_life").update(expired=True)
        # )

        # Thus, we will be using this less efficient/elegant approach to do the same thing
        for purchased_order in PurchasedOrder.objects.filter(sold_out=False,
                                                             expired=False):
            if purchased_order.purchased_date < timezone.now() - timedelta(
                    minutes=1):
                PurchasedOrder.objects.filter(id=purchased_order.id).update(
                    expired=True)
                # sets the stock for this purchased order to 0
                ProductStockManagement(purchased_order).deletes_order_stock()
Exemple #6
0
 def update_purchased_order_stock(instance, **kwargs):
     # this method will keep in check the stock in redis for all purchased products
     ProductStockManagement(instance).update_redis_stock()
     # this method will update the stock field in the DB
     SalesOrderLogic(instance).update_purchased_order_stock()
 def __init__(self, sales_order):
     self.sales_order = sales_order
     self.stock = ProductStockManagement(self.sales_order).stock
Exemple #8
0
 def deletes_order_stock(instance, **kwargs):
     # if the purchased order is deleted, we want to set the stock to 0
     ProductStockManagement(instance).deletes_order_stock()
Exemple #9
0
 def create_or_update_order_stock(instance, **kwargs):
     # We only want to create or update the stock for this purchased order if the following conditions are met
     if not instance.sold_out and not instance.expired:
         ProductStockManagement(instance).create_or_update_order_stock()