rancher service & quota usage service

This commit is contained in:
2025-09-28 10:36:58 +03:30
parent 973d1319da
commit e9caad0dbf
4 changed files with 91 additions and 49 deletions

View File

@@ -0,0 +1,13 @@
from django.db.models import Sum, functions, Value
class RancherService:
@staticmethod
def get_total_used_weight(rancher, sale_item):
return sale_item.objects.filter(
transaction__rancher=rancher,
transaction__transaction_status='success'
).aggregate(
total_weight=functions.Coalesce(Sum('weight'), Value(0))
)['total_weight']

View File

@@ -1,8 +1,13 @@
from decimal import Decimal from decimal import Decimal
from apps.herd.models import Rancher from apps.herd.models import Rancher
from apps.livestock.models import LiveStock from apps.livestock.models import LiveStock
from apps.warehouse.models import InventoryEntry from apps.warehouse.models import (
InventoryEntry,
InventoryQuotaSaleItem
)
from django.db.models import Sum
from apps.product.models import Quota, QuotaDistribution from apps.product.models import Quota, QuotaDistribution
from apps.herd.services.rancher_service import RancherService
from django.db.models import Count, Q from django.db.models import Count, Q
import typing import typing
@@ -89,11 +94,13 @@ def rancher_quota_weight(rancher, inventory_entry: InventoryEntry = None, distri
# incentive plan quantity by this livestock type # incentive plan quantity by this livestock type
rancher_plan_weight = rancher_plans.first().allowed_quantity * item.quantity_kg rancher_plan_weight = rancher_plans.first().allowed_quantity * item.quantity_kg
total_weight += rancher_plan_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)
return { return {
"total_weight": total_weight, "total_weight": total_weight,
"remaining_weight": 20, "remaining_weight": total_weight - rancher_remaining_usage,
"by_type": [{ "by_type": [{
"name": key, "name": key,
"name_fa": value['name_fa'], "name_fa": value['name_fa'],

View File

@@ -6,6 +6,7 @@ from apps.product.services.services import (
quota_attribute_value quota_attribute_value
) )
from apps.pos_device.services.services import pos_organizations_sharing_information from apps.pos_device.services.services import pos_organizations_sharing_information
from apps.warehouse.services.quota_usage_services import QuotaUsageService
from apps.pos_device.pos.api.v1.serializers.device import DeviceSerializer from apps.pos_device.pos.api.v1.serializers.device import DeviceSerializer
from apps.product.exceptions import DistributionWeightException from apps.product.exceptions import DistributionWeightException
from apps.pos_device.models import POSFreeProducts from apps.pos_device.models import POSFreeProducts
@@ -171,52 +172,12 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer):
# create pre sale for distribution # create pre sale for distribution
create_pre_sale(transaction=transaction, sale_item=item) create_pre_sale(transaction=transaction, sale_item=item)
# purchase quota usage of rancher # calculate quota usage of rancher
if 'livestock_statistic' in item_data.keys(): usages = QuotaUsageService.allocate_usage(
rancher=rancher,
# get list of livestock types object for transaction item distribution=distribution,
livestock_types = { item_data=item_data
lt.en_name: lt )
for lt in LiveStockType.objects.filter(
en_name__in=[i['name'] for i in item_data.get('livestock_statistic', [])]
)
}
# get list of incentive plans object for transaction item
incentive_plans = {
iplan.id: iplan
for iplan in IncentivePlan.objects.all()
}
for item in item_data['livestock_statistic']:
# get livestock by en name
livestock_type = livestock_types.get(item['name'])
if not livestock_types:
continue
# true or false
is_incentive = item['id'] != 0
# get usage & calculate
usage, created = QuotaUsage.objects.get_or_create(
rancher=rancher,
livestock_type=livestock_type,
distribution=distribution,
incentive_plan=incentive_plans.get(item['id']) if is_incentive else None,
defaults={
"count": item['count'],
'usage_type': 'incentive' if is_incentive else 'base',
'incentive_quota_used': item['total_weight'] if is_incentive else 0,
'base_quota_used': item['total_weight'] if is_incentive else 0
}
)
if not created:
if usage.usage_type == 'incentive':
usage.incentive_quota_used += item['total_weight']
else:
usage.base_quota_used += item['total_weight']
usage.save()
transaction.transaction_price = total_price transaction.transaction_price = total_price
transaction.save() transaction.save()

View File

@@ -0,0 +1,61 @@
from apps.product.models import QuotaUsage, IncentivePlan
from apps.livestock.models import LiveStockType
class QuotaUsageService:
@staticmethod
def allocate_usage(rancher, distribution, item_data):
""" save & calculate quota usage of rancher """
# purchase quota usage of rancher
if 'livestock_statistic' in item_data.keys():
# get list of livestock types object for transaction item
livestock_types = {
lt.en_name: lt
for lt in LiveStockType.objects.filter(
en_name__in=[i['name'] for i in item_data.get('livestock_statistic', [])]
)
}
# get list of incentive plans object for transaction item
incentive_plans = {
iplan.id: iplan
for iplan in IncentivePlan.objects.all()
}
usages = [] # list of usages objects
for item in item_data['livestock_statistic']:
# get livestock by en name
livestock_type = livestock_types.get(item['name'])
if not livestock_types:
continue
# true or false
is_incentive = item['id'] != 0
# get usage & calculate
usage, created = QuotaUsage.objects.get_or_create(
rancher=rancher,
livestock_type=livestock_type,
distribution=distribution,
incentive_plan=incentive_plans.get(item['id']) if is_incentive else None,
defaults={
"count": item['count'],
'usage_type': 'incentive' if is_incentive else 'base',
'incentive_quota_used': item['total_weight'] if is_incentive else 0,
'base_quota_used': item['total_weight'] if is_incentive else 0
}
)
if not created:
if usage.usage_type == 'incentive':
usage.incentive_quota_used += item['total_weight']
else:
usage.base_quota_used += item['total_weight']
usage.save()
usages.append(usage)
return usages