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))
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)
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()
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
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()
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()