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