Files
RasadDam_Backend/apps/herd/services/services.py
2025-09-20 12:52:49 +03:30

87 lines
2.9 KiB
Python

from decimal import Decimal
from apps.herd.models import Rancher
from apps.livestock.models import LiveStock
from apps.warehouse.models import InventoryEntry
from apps.product.models import Quota, QuotaDistribution
from django.db.models import Count, Q
import typing
def get_rancher_statistics(rancher: Rancher = None) -> typing.Any:
""" get statistics of a rancher """ # noqa
livestocks = LiveStock.objects.filter(herd__rancher=rancher) # noqa
stats = livestocks.aggregate(
herd_count=Count("herd", distinct=True),
light_count=Count('id', filter=Q(weight_type='L')),
heavy_count=Count('id', filter=Q(weight_type='H')),
sheep_count=Count('id', filter=Q(type__name='گوسفند')), # noqa
goat_count=Count('id', filter=Q(type__name='بز')),
cow_count=Count('id', filter=Q(type__name='گاو')),
camel_count=Count('id', filter=Q(type__name='شتر')),
horse_count=Count('id', filter=Q(type__name='بز')),
)
stats.update({'dhi_stat': rancher.dhi_state}) # add rancher dhi stat to dict result
return stats
def rancher_quota_weight(rancher, inventory_entry: InventoryEntry = None, distribution: QuotaDistribution = None):
"""
:param rancher: Rancher instance
:param inventory_entry: InventoryEntry instance
:param distribution: QuotaDistribution instance
:return: dict {total, by_type}
"""
live_stock_meta = {
"گوسفند": "sheep_count", # noqa
"بز": "goat_count",
"گاو": "cow_count",
"شتر": "camel_count",
"اسب": "horse_count"
}
if inventory_entry:
quota: Quota = inventory_entry.distribution.quota
elif distribution:
quota: Quota = distribution.quota
else:
quota: Quota = Quota()
# list of quota live stock allocations
allocations = list(quota.livestock_allocations.all().select_related('livestock_type'))
# list of quota incentive plans
incentive_plans = list(quota.incentive_assignments.all().select_related('livestock_type'))
livestock_counts = get_rancher_statistics(rancher)
total_weight = 0
merged = {}
for item in allocations + incentive_plans: # noqa
if item.livestock_type:
animal_type = item.livestock_type.name
per_head = item.quantity_kg
count = livestock_counts.get(live_stock_meta.get(animal_type), 0)
weight = per_head * count
total_weight += weight
if animal_type not in merged:
merged[animal_type] = {
"weight": weight,
"type": item.livestock_type.weight_type
}
else:
merged[animal_type]['weight'] += weight
return {
"total_weight": total_weight,
"by_type": [{
"name": key,
"weight": value['weight'],
"type": value['type']
}for key, value in merged.items()]
}