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('id', filter=Q(type__name='گوسفند')), # noqa goat=Count('id', filter=Q(type__name='بز')), cow=Count('id', filter=Q(type__name='گاو')), camel=Count('id', filter=Q(type__name='شتر')), horse=Count('id', filter=Q(type__name='بز')), ) return [{'name': key, 'value': value} for key, value in stats.items()], 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", # noqa "بز": "goat", "گاو": "cow", "شتر": "camel", "اسب": "horse" } 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_list, livestock_counts_dict = get_rancher_statistics(rancher) total_weight = 0 merged = {} for item in allocations + incentive_plans: # noqa if item.livestock_type: animal_type_fa = item.livestock_type.name animal_type_en = item.livestock_type.en_name per_head = item.quantity_kg count = livestock_counts_dict.get(live_stock_meta.get(animal_type_fa), 0) weight = per_head * count total_weight += weight if animal_type_en not in merged: merged[animal_type_en] = { "name_fa": animal_type_fa, "weight": weight, "type": item.livestock_type.weight_type } else: merged[animal_type_en]['weight'] += weight return { "total_weight": total_weight, "remaining_weight": 20, "by_type": [{ "name": key, "name_fa": value['name_fa'], "weight": value['weight'], "type": value['type'] } for key, value in merged.items()] }