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

View File

@@ -6,6 +6,7 @@ from apps.product.services.services import (
quota_attribute_value
)
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.product.exceptions import DistributionWeightException
from apps.pos_device.models import POSFreeProducts
@@ -171,52 +172,12 @@ class InventoryQuotaSaleTransactionSerializer(serializers.ModelSerializer):
# create pre sale for distribution
create_pre_sale(transaction=transaction, sale_item=item)
# 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()
}
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()
# calculate quota usage of rancher
usages = QuotaUsageService.allocate_usage(
rancher=rancher,
distribution=distribution,
item_data=item_data
)
transaction.transaction_price = total_price
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