diff --git a/apps/herd/services/rancher_service.py b/apps/herd/services/rancher_service.py index 1f4a57a..df32a1b 100644 --- a/apps/herd/services/rancher_service.py +++ b/apps/herd/services/rancher_service.py @@ -4,11 +4,11 @@ from django.db.models import Sum, functions, Value class RancherService: @staticmethod - def get_total_used_weight(rancher, sale_item, distribution): + def get_total_used_weight(rancher, sale_item, quota_stat): return sale_item.objects.filter( transaction__rancher=rancher, transaction__transaction_status='success', - quota_distribution=distribution, + quota_stat=quota_stat, ).aggregate( total_weight=functions.Coalesce(Sum('weight'), Value(0)) )['total_weight'] diff --git a/apps/herd/services/services.py b/apps/herd/services/services.py index 4a25653..f0b6caf 100644 --- a/apps/herd/services/services.py +++ b/apps/herd/services/services.py @@ -7,7 +7,7 @@ from django.db.models.functions import Coalesce from apps.herd.models import Rancher from apps.herd.services.rancher_service import RancherService from apps.livestock.models import LiveStock, TemporaryLiveStock -from apps.product.models import Quota, QuotaDistribution +from apps.product.models import Quota, QuotaDistribution, OrganizationQuotaStats from apps.warehouse.models import ( InventoryEntry, InventoryQuotaSaleItem @@ -82,7 +82,8 @@ def rancher_quota_weight( rancher: Rancher, inventory_entry: InventoryEntry = None, distribution: QuotaDistribution = None, - quota: Quota = None + quota: Quota = None, + quota_stat: OrganizationQuotaStats = None ): """ :param rancher: Rancher instance @@ -154,20 +155,26 @@ def rancher_quota_weight( total_weight += rancher_plan_weight print(total_weight) # get rancher remaining usage of quota for purchase - rancher_remaining_usage = RancherService.get_total_used_weight(rancher, InventoryQuotaSaleItem, distribution) + rancher_remaining_usage = RancherService.get_total_used_weight( + rancher, + InventoryQuotaSaleItem, + quota_stat=quota_stat + ) if total_weight - rancher_remaining_usage < 0: remaining_weight = 0 free_sale = rancher_remaining_usage - total_weight + total_purchase = free_sale + total_weight else: remaining_weight = total_weight - rancher_remaining_usage free_sale = 0 + total_purchase = total_weight - remaining_weight return { "total_weight": total_weight, "remaining_weight": remaining_weight, 'free_sale': free_sale, - 'total_purchase': 0, + 'total_purchase': total_purchase, "rancher_temporary_livestock": rancher.without_herd, "by_type": [{ "name": key, diff --git a/apps/product/models.py b/apps/product/models.py index 2eeff3d..8fd86cd 100644 --- a/apps/product/models.py +++ b/apps/product/models.py @@ -863,6 +863,8 @@ class OrganizationQuotaStats(BaseModel): ('distribution', 'DISTRIBUTION'), ('quota', 'QUOTA'), ), default='distribution') + free_sale_balance = models.PositiveBigIntegerField(default=0) + pre_sale_balance = models.PositiveBigIntegerField(default=0) def update_amount(self, main_quota=None): """ calculate total/sold/remaining """ diff --git a/apps/product/pos/api/v1/serializers/quota_serializers.py b/apps/product/pos/api/v1/serializers/quota_serializers.py index dad6918..ef62abd 100644 --- a/apps/product/pos/api/v1/serializers/quota_serializers.py +++ b/apps/product/pos/api/v1/serializers/quota_serializers.py @@ -321,7 +321,7 @@ class OrganizationQuotaStatsSerializer(serializers.ModelSerializer): # rancher live stock statistics by quota distributions representation['rancher_quota_weight_statistics'] = rancher_quota_weight( - rancher, quota=instance.quota + rancher, quota=instance.quota, quota_stat=instance ) return representation diff --git a/apps/warehouse/models.py b/apps/warehouse/models.py index b1f2860..60e0203 100644 --- a/apps/warehouse/models.py +++ b/apps/warehouse/models.py @@ -247,6 +247,12 @@ class ExtraSale(BaseModel): related_name='extra_sales', null=True ) + quota_stat = models.ForeignKey( + product_models.OrganizationQuotaStats, + on_delete=models.CASCADE, + related_name='extra_sales', + null=True + ) transaction = models.ForeignKey( InventoryQuotaSaleTransaction, on_delete=models.CASCADE, @@ -281,6 +287,12 @@ class QuotaPreSaleItem(BaseModel): related_name='pre_sales', null=True ) + quota_stat = models.ForeignKey( + product_models.OrganizationQuotaStats, + on_delete=models.CASCADE, + related_name='pre_sales', + null=True + ) transaction = models.ForeignKey( InventoryQuotaSaleTransaction, on_delete=models.CASCADE, diff --git a/apps/warehouse/pos/api/v2/serializers.py b/apps/warehouse/pos/api/v2/serializers.py index 892aa39..dd8e1ab 100644 --- a/apps/warehouse/pos/api/v2/serializers.py +++ b/apps/warehouse/pos/api/v2/serializers.py @@ -22,6 +22,7 @@ from apps.product.services.services import ( from apps.warehouse import models as warehouse_models from apps.warehouse.exceptions import WareHouseException from apps.warehouse.services.quota_usage_services import QuotaUsageService +from apps.warehouse.services.services import create_extra_sale, create_pre_sale class InventoryEntrySerializer(serializers.ModelSerializer): @@ -223,11 +224,11 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer): # IF WE DO NOT HAVE DISTRIBUTION, THEN IT IS A FREE PRODUCT TRANSACTION if 'quota_distribution' and 'quota_stat' in item_data.keys(): - # # create extra sale for distribution - # create_extra_sale(transaction=transaction, sale_item=item) - # - # # create pre sale for distribution - # create_pre_sale(transaction=transaction, sale_item=item) + # create extra sale for distribution + create_extra_sale(transaction=transaction, sale_item=item) + + # create pre sale for distribution + create_pre_sale(transaction=transaction, sale_item=item) # calculate quota usage of rancher QuotaUsageService.allocate_usage( diff --git a/apps/warehouse/services/services.py b/apps/warehouse/services/services.py index 3d18ab4..b6a3c3f 100644 --- a/apps/warehouse/services/services.py +++ b/apps/warehouse/services/services.py @@ -1,5 +1,11 @@ -from apps.herd.services.services import rancher_quota_weight, get_rancher_statistics +import typing + +from django.db.models import Sum from rest_framework.exceptions import APIException + +from apps.core.models import SystemConfig +from apps.herd.services.services import rancher_quota_weight +from apps.product.models import QuotaDistribution from apps.warehouse.models import ( InventoryEntry, InventoryQuotaSaleTransaction, @@ -7,10 +13,6 @@ from apps.warehouse.models import ( ExtraSale, QuotaPreSaleItem ) -from apps.product.models import QuotaDistribution -from apps.core.models import SystemConfig -from django.db.models import Sum -import typing def get_total_sold(rancher, inventory_entry: InventoryEntry = None, distribution: QuotaDistribution = None): @@ -74,21 +76,22 @@ def create_extra_sale( more than distribution warehouse balance """ - if sale_item.quota_distribution.free_sale: - if sale_item.weight > sale_item.quota_distribution.warehouse_balance: + if sale_item.quota_stat.quota.free_sale: + if sale_item.weight > sale_item.quota_stat.inventory_entry_balance: # calculate extra weight between item weight and warehouse balance - extra_weight = sale_item.weight - sale_item.quota_distribution.warehouse_balance + extra_weight = sale_item.weight - sale_item.quota_stat.inventory_entry_balance extra_sale = ExtraSale.objects.create( # create extra sale transaction=transaction, sale_item=sale_item, distribution=sale_item.quota_distribution, + quota_stat=sale_item.quota_stat, weight=extra_weight ) # set distribution warehouse balance to 0 because we have extra sale - sale_item.quota_distribution.warehouse_balance = 0 - sale_item.quota_distribution.free_sale_balance += extra_weight - sale_item.quota_distribution.save() + sale_item.quota_stat.inventory_entry_balance = 0 + sale_item.quota_stat.free_sale_balance += extra_weight + sale_item.quota_stat.save() # set transaction as free sale transaction.free_sale_state = True @@ -113,13 +116,14 @@ def create_pre_sale( Create pre_sale for distributions """ - if sale_item.quota_distribution.pre_sale: + if sale_item.quota_stat.quota.pre_sale: try: # create pre sale pre_sale = QuotaPreSaleItem.objects.create( transaction=transaction, sale_item=sale_item, distribution=sale_item.quota_distribution, + quota_stat=sale_item.quota_stat, weight=sale_item.weight ) @@ -129,11 +133,10 @@ def create_pre_sale( # set sale item as pre sale sale_item.is_pre_sale = True - sale_item.quota_distribution.pre_sale_balance += sale_item.weight + sale_item.quota_stat.pre_sale_balance += sale_item.weight sale_item.save() return pre_sale except APIException as e: pass pass -