fix - improve response time of org_linked_ranchers

This commit is contained in:
2026-01-04 10:16:38 +03:30
parent 43b0d0b4ea
commit abf1c12e39

View File

@@ -5,54 +5,146 @@ from apps.authentication.services.service import get_all_org_child
from apps.herd.models import RancherOrganizationLink
# class RancherOrganizationService:
# """
# different services of ranchers linked to organization
# """
#
# def orgs_linked_rancher(self, org: Organization = None, org_type_key: str = None):
# """
# list of organizations with their information of rancher, herd, ....
# """
# if org.type.key != 'ADM':
# organizations = get_all_org_child(org)
# organizations = Organization.objects.filter(id__in=[item.id for item in organizations])
# else:
# organizations = Organization.objects.filter(type__key=org_type_key)
#
# linked_qs = RancherOrganizationLink.objects.select_related(
# 'rancher',
# 'organization'
# ).filter(organization__in=organizations, organization__type__key=org_type_key)
#
# organizations = organizations.annotate(
# rancher_count=Count(
# 'rancher_links__rancher_id',
# distinct=True
# ),
# herd_count=Count(
# 'rancher_links__rancher__herd',
# distinct=True
# ),
# livestock_count=Count(
# 'rancher_links__rancher__herd__live_stock_herd',
# distinct=True
# ),
# )
#
# return [
# {
# "id": org.id,
# "name": org.name,
# "org_service_area": [{'name': city.name, 'id': city.id} for city in org.service_area.all()],
# "org_purchase_policy": org.purchase_policy,
# "province": org.province.name,
# "province_id": org.province.id,
# "city": org.city.name,
# "city_id": org.city.id,
# "rancher_count": org.rancher_count,
# "herd_count": org.herd_count,
# "livestock_count": org.livestock_count,
# }
# for org in organizations
# ]
class RancherOrganizationService:
"""
different services of ranchers linked to organization
"""
def orgs_linked_rancher(self, org: Organization = None, org_type_key: str = None):
"""
list of organizations with their information of rancher, herd, ....
"""
def orgs_linked_rancher(self, org: Organization, org_type_key: str):
# --------------------------------------------------
# 1. Base organizations queryset
# --------------------------------------------------
if org.type.key != 'ADM':
organizations = get_all_org_child(org)
organizations = Organization.objects.filter(id__in=[item.id for item in organizations])
child_orgs = get_all_org_child(org)
org_ids = [o.id for o in child_orgs]
else:
organizations = Organization.objects.filter(type__key=org_type_key)
org_ids = Organization.objects.filter(
type__key=org_type_key
).values_list('id', flat=True)
linked_qs = RancherOrganizationLink.objects.select_related(
'rancher',
'organization'
).filter(organization__in=organizations, organization__type__key=org_type_key)
organizations = organizations.annotate(
rancher_count=Count(
'rancher_links__rancher',
distinct=True
),
herd_count=Count(
'rancher_links__rancher__herd',
distinct=True
),
livestock_count=Count(
'rancher_links__rancher__herd__live_stock_herd',
distinct=True
),
organizations = (
Organization.objects
.filter(id__in=org_ids, type__key=org_type_key)
.select_related('province', 'city')
.prefetch_related('service_area')
)
return [
{
# --------------------------------------------------
# 2. Rancher count per organization
# --------------------------------------------------
rancher_counts = {
row['organization_id']: row['cnt']
for row in (
RancherOrganizationLink.objects
.filter(organization_id__in=org_ids)
.values('organization_id')
.annotate(cnt=Count('rancher_id', distinct=True))
)
}
# --------------------------------------------------
# 3. Herd count per organization
# --------------------------------------------------
herd_counts = {
row['organization_id']: row['cnt']
for row in (
RancherOrganizationLink.objects
.filter(organization_id__in=org_ids)
.values('organization_id')
.annotate(cnt=Count('rancher__herd', distinct=True))
)
}
# --------------------------------------------------
# 4. Livestock count per organization
# --------------------------------------------------
livestock_counts = {
row['organization_id']: row['cnt']
for row in (
RancherOrganizationLink.objects
.filter(organization_id__in=org_ids)
.values('organization_id')
.annotate(
cnt=Count(
'rancher__herd__live_stock_herd',
distinct=True
)
)
)
}
# --------------------------------------------------
# 5. Final response (merge in memory)
# --------------------------------------------------
response = []
for org in organizations:
response.append({
"id": org.id,
"name": org.name,
"org_service_area": [{'name': city.name, 'id': city.id} for city in org.service_area.all()],
"org_service_area": [
{"id": city.id, "name": city.name}
for city in org.service_area.all()
],
"org_purchase_policy": org.purchase_policy,
"province": org.province.name,
"province_id": org.province.id,
"city": org.city.name,
"city_id": org.city.id,
"rancher_count": org.rancher_count,
"herd_count": org.herd_count,
"livestock_count": org.livestock_count,
}
for org in organizations
]
"rancher_count": rancher_counts.get(org.id, 0),
"herd_count": herd_counts.get(org.id, 0),
"livestock_count": livestock_counts.get(org.id, 0),
})
return response