fix - caculate my childs quota stat / add assigned orgs & assigned_to_me status

This commit is contained in:
2025-11-25 10:20:51 +03:30
parent 303124e1a1
commit 67904fd1a8
3 changed files with 98 additions and 61 deletions

View File

@@ -8,6 +8,7 @@ from django.db.models import Sum
from simple_history.models import HistoricalRecords from simple_history.models import HistoricalRecords
from apps.authentication.models import OrganizationType, Organization from apps.authentication.models import OrganizationType, Organization
from apps.authentication.services.service import get_all_org_child
from apps.authorization.models import UserRelations from apps.authorization.models import UserRelations
from apps.core.models import BaseModel from apps.core.models import BaseModel
from apps.herd.models import Rancher from apps.herd.models import Rancher
@@ -465,10 +466,40 @@ class Quota(BaseModel):
return persian_date.month in self.sale_license return persian_date.month in self.sale_license
def quota_amount_by_org(self, org: Organization): def quota_amount_by_org(self, org: Organization):
"""
get stats of quota from org quota stat model
"""
stat = OrganizationQuotaStats.objects.filter( stat = OrganizationQuotaStats.objects.filter(
quota=self, quota=self,
organization=org organization=org
) )
if not stat.exists():
# get childs of organization
org_childs = get_all_org_child(org) # noqa
# calculate total stats of child orgs
stat = OrganizationQuotaStats.objects.filter(
quota=self,
organization_id__in=[child.id for child in org_childs]
).aggregate(
total_quota_weight=models.Sum('total_amount'),
total_remaining_weight=models.Sum('remaining_amount'),
total_quota_distributed=models.Sum('total_distributed'),
total_been_sold=models.Sum('sold_amount'),
total_inventory_received=models.Sum('inventory_received'),
total_inventory_entry_balance=models.Sum('inventory_entry_balance')
)
return {
"id": 0,
"quota_weight": stat['total_quota_weight'],
"remaining_weight": stat['total_remaining_weight'],
"quota_distributed": stat['total_quota_distributed'],
"been_sold": stat['total_been_sold'],
"inventory_received": stat['total_inventory_received'],
"inventory_entry_balance": stat['total_inventory_entry_balance'],
}
return { return {
"id": stat.first().id if stat.exists() else 0, "id": stat.first().id if stat.exists() else 0,
"quota_weight": stat.first().total_amount if stat.exists() else 0, "quota_weight": stat.first().total_amount if stat.exists() else 0,

View File

@@ -24,6 +24,8 @@ class QuotaSerializer(serializers.ModelSerializer):
def to_representation(self, instance: product_models.Quota): def to_representation(self, instance: product_models.Quota):
representation = super().to_representation(instance) representation = super().to_representation(instance)
assigned_orgs = instance.assigned_organizations.all()
# change quota weight by organization received weight # change quota weight by organization received weight
if 'org' in self.context.keys(): if 'org' in self.context.keys():
org = self.context['org'] org = self.context['org']
@@ -51,71 +53,77 @@ class QuotaSerializer(serializers.ModelSerializer):
"weight": dist.weight, "weight": dist.weight,
} for dist in instance.distributions_assigned.filter(assigned_organization=org)] } for dist in instance.distributions_assigned.filter(assigned_organization=org)]
if isinstance(instance, product_models.Quota): representation['assigned_to_me'] = True if org in assigned_orgs else False
if instance.sale_unit:
representation['sale_unit'] = product_serializers.SaleUnitSerializer(
instance.sale_unit
).data
representation['product'] = {"product": instance.product.name, "product_id": instance.product.id}
# quota incentive plan data # list of assigned organizations that received this quota
incentive_plan_map = {} representation['assigned_organizations'] = [{
for assign in instance.incentive_assignments.all(): "name": org.name, "id": org.id
plan_id = assign.incentive_plan.id } for org in assigned_orgs]
if plan_id not in incentive_plan_map:
incentive_plan_map[plan_id] = {
"id": assign.id,
"name": assign.incentive_plan.name,
"incentive_plan": plan_id,
"live_stocks": []
}
if assign.livestock_type: if instance.sale_unit:
incentive_plan_map[plan_id]['live_stocks'].append({ representation['sale_unit'] = product_serializers.SaleUnitSerializer(
"id": assign.livestock_type.id, instance.sale_unit
"name": assign.livestock_type.name,
"quantity": assign.quantity_kg
})
representation['incentive_plan'] = list(incentive_plan_map.values())
representation['attribute_values'] = product_serializers.AttributeValueSerializer(
instance.attribute_values.all(),
many=True
).data ).data
representation['product'] = {"product": instance.product.name, "product_id": instance.product.id}
representation['brokers'] = QuotaBrokerValueSerializer( # quota incentive plan data
instance.broker_values.all(), incentive_plan_map = {}
many=True for assign in instance.incentive_assignments.all():
).data plan_id = assign.incentive_plan.id
if plan_id not in incentive_plan_map:
representation['livestock_allocations'] = QuotaLiveStockAllocationSerializer( incentive_plan_map[plan_id] = {
instance.livestock_allocations.all(), "id": assign.id,
many=True "name": assign.incentive_plan.name,
).data "incentive_plan": plan_id,
"live_stocks": []
representation['livestock_limitations'] = QuotaLiveStockAgeLimitationSerializer(
instance.livestock_age_limitations.all(),
many=True
).data
representation['limit_by_organizations'] = [
{"name": limit.name, "id": limit.id} for limit in instance.limit_by_organizations.all()
]
# Build a simplified list of pricing items for API output:
# map `pricing_type_id` to `pricing_type` and keep `name` and `value`
items = [
{
"pricing_type": it["pricing_type_id"],
"pricing_type_name": it["pricing_type__name"],
"name": it["name"],
"value": it["value"],
} }
for it in instance.pricing_items.values("pricing_type_id", "pricing_type__name", "name", "value")
]
representation["price_calculation_items"] = items if assign.livestock_type:
incentive_plan_map[plan_id]['live_stocks'].append({
"id": assign.livestock_type.id,
"name": assign.livestock_type.name,
"quantity": assign.quantity_kg
})
representation['incentive_plan'] = list(incentive_plan_map.values())
representation['attribute_values'] = product_serializers.AttributeValueSerializer(
instance.attribute_values.all(),
many=True
).data
representation['brokers'] = QuotaBrokerValueSerializer(
instance.broker_values.all(),
many=True
).data
representation['livestock_allocations'] = QuotaLiveStockAllocationSerializer(
instance.livestock_allocations.all(),
many=True
).data
representation['livestock_limitations'] = QuotaLiveStockAgeLimitationSerializer(
instance.livestock_age_limitations.all(),
many=True
).data
representation['limit_by_organizations'] = [
{"name": limit.name, "id": limit.id} for limit in instance.limit_by_organizations.all()
]
# Build a simplified list of pricing items for API output:
# map `pricing_type_id` to `pricing_type` and keep `name` and `value`
items = [
{
"pricing_type": it["pricing_type_id"],
"pricing_type_name": it["pricing_type__name"],
"name": it["name"],
"value": it["value"],
}
for it in instance.pricing_items.values("pricing_type_id", "pricing_type__name", "name", "value")
]
representation["price_calculation_items"] = items
return representation return representation

View File

@@ -359,8 +359,6 @@ class QuotaViewSet(BaseViewSet, SoftDeleteMixin, viewsets.ModelViewSet, DynamicS
self.get_queryset(visibility_by_org_scope=True).filter( self.get_queryset(visibility_by_org_scope=True).filter(
is_closed=False)) # return by search param or all objects is_closed=False)) # return by search param or all objects
print(queryset)
# paginate queryset # paginate queryset
page = self.paginate_queryset( page = self.paginate_queryset(
queryset.filter( queryset.filter(