diff --git a/.idea/RSI.iml b/.idea/RSI.iml
index cfcee21..a9f91e1 100644
--- a/.idea/RSI.iml
+++ b/.idea/RSI.iml
@@ -19,7 +19,7 @@
-
+
diff --git a/RSI/__pycache__/__init__.cpython-312.pyc b/RSI/__pycache__/__init__.cpython-312.pyc
index de388e4..611df2b 100644
Binary files a/RSI/__pycache__/__init__.cpython-312.pyc and b/RSI/__pycache__/__init__.cpython-312.pyc differ
diff --git a/RSI/__pycache__/settings.cpython-312.pyc b/RSI/__pycache__/settings.cpython-312.pyc
index 4e720b2..739753f 100644
Binary files a/RSI/__pycache__/settings.cpython-312.pyc and b/RSI/__pycache__/settings.cpython-312.pyc differ
diff --git a/RSI/__pycache__/urls.cpython-312.pyc b/RSI/__pycache__/urls.cpython-312.pyc
index a8bddf0..9559074 100644
Binary files a/RSI/__pycache__/urls.cpython-312.pyc and b/RSI/__pycache__/urls.cpython-312.pyc differ
diff --git a/RSI/__pycache__/wsgi.cpython-312.pyc b/RSI/__pycache__/wsgi.cpython-312.pyc
index e72caa2..852a173 100644
Binary files a/RSI/__pycache__/wsgi.cpython-312.pyc and b/RSI/__pycache__/wsgi.cpython-312.pyc differ
diff --git a/__pycache__/helpers.cpython-312.pyc b/__pycache__/helpers.cpython-312.pyc
index 4fbe9c7..65fbef3 100644
Binary files a/__pycache__/helpers.cpython-312.pyc and b/__pycache__/helpers.cpython-312.pyc differ
diff --git a/app/__pycache__/__init__.cpython-312.pyc b/app/__pycache__/__init__.cpython-312.pyc
index e585a3f..b478ea6 100644
Binary files a/app/__pycache__/__init__.cpython-312.pyc and b/app/__pycache__/__init__.cpython-312.pyc differ
diff --git a/app/__pycache__/admin.cpython-312.pyc b/app/__pycache__/admin.cpython-312.pyc
index 6ba60a1..0aa4f86 100644
Binary files a/app/__pycache__/admin.cpython-312.pyc and b/app/__pycache__/admin.cpython-312.pyc differ
diff --git a/app/__pycache__/apps.cpython-312.pyc b/app/__pycache__/apps.cpython-312.pyc
index 71dcad5..d544cfb 100644
Binary files a/app/__pycache__/apps.cpython-312.pyc and b/app/__pycache__/apps.cpython-312.pyc differ
diff --git a/app/__pycache__/cityandprovince.cpython-312.pyc b/app/__pycache__/cityandprovince.cpython-312.pyc
index 34938e6..c4c8b2a 100644
Binary files a/app/__pycache__/cityandprovince.cpython-312.pyc and b/app/__pycache__/cityandprovince.cpython-312.pyc differ
diff --git a/app/__pycache__/excel_processing.cpython-312.pyc b/app/__pycache__/excel_processing.cpython-312.pyc
index b8db971..b2bb301 100644
Binary files a/app/__pycache__/excel_processing.cpython-312.pyc and b/app/__pycache__/excel_processing.cpython-312.pyc differ
diff --git a/app/__pycache__/filtersets.cpython-312.pyc b/app/__pycache__/filtersets.cpython-312.pyc
index dfe4609..d3362a4 100644
Binary files a/app/__pycache__/filtersets.cpython-312.pyc and b/app/__pycache__/filtersets.cpython-312.pyc differ
diff --git a/app/__pycache__/helper.cpython-312.pyc b/app/__pycache__/helper.cpython-312.pyc
index c93382b..f224d6b 100644
Binary files a/app/__pycache__/helper.cpython-312.pyc and b/app/__pycache__/helper.cpython-312.pyc differ
diff --git a/app/__pycache__/helper_excel.cpython-312.pyc b/app/__pycache__/helper_excel.cpython-312.pyc
index b83ed7b..0242cd0 100644
Binary files a/app/__pycache__/helper_excel.cpython-312.pyc and b/app/__pycache__/helper_excel.cpython-312.pyc differ
diff --git a/app/__pycache__/models.cpython-312.pyc b/app/__pycache__/models.cpython-312.pyc
index b996c78..ff9e92f 100644
Binary files a/app/__pycache__/models.cpython-312.pyc and b/app/__pycache__/models.cpython-312.pyc differ
diff --git a/app/__pycache__/scripts.cpython-312.pyc b/app/__pycache__/scripts.cpython-312.pyc
index 8ddf365..3e18e90 100644
Binary files a/app/__pycache__/scripts.cpython-312.pyc and b/app/__pycache__/scripts.cpython-312.pyc differ
diff --git a/app/__pycache__/serializers.cpython-312.pyc b/app/__pycache__/serializers.cpython-312.pyc
index dcd9487..99fd1f8 100644
Binary files a/app/__pycache__/serializers.cpython-312.pyc and b/app/__pycache__/serializers.cpython-312.pyc differ
diff --git a/app/__pycache__/urls.cpython-312.pyc b/app/__pycache__/urls.cpython-312.pyc
index 928ccf6..48d8983 100644
Binary files a/app/__pycache__/urls.cpython-312.pyc and b/app/__pycache__/urls.cpython-312.pyc differ
diff --git a/app/__pycache__/views.cpython-312.pyc b/app/__pycache__/views.cpython-312.pyc
index 95968d5..40eceb7 100644
Binary files a/app/__pycache__/views.cpython-312.pyc and b/app/__pycache__/views.cpython-312.pyc differ
diff --git a/app/helper.py b/app/helper.py
index fd76876..f5b93b5 100644
--- a/app/helper.py
+++ b/app/helper.py
@@ -177,3 +177,77 @@ class SSLAdapter(HTTPAdapter):
self.context = create_urllib3_context()
self.context.options |= 0x4 # OP_LEGACY_SERVER_CONNECT
super().__init__(*args, **kwargs)
+
+
+
+
+
+from datetime import datetime, timedelta
+from django.utils import timezone
+
+
+def apply_date_filter(queryset, date_filter):
+ if not date_filter:
+ return queryset
+
+ field = date_filter.get("field", "Date")
+ filter_type = date_filter.get("type")
+ value = date_filter.get("value")
+
+ now = timezone.now()
+
+ if filter_type == "today":
+ start = now.replace(hour=0, minute=0, second=0, microsecond=0)
+ end = start + timedelta(days=1)
+ return queryset.filter(
+ **{f"{field}__gte": start, f"{field}__lt": end}
+ )
+
+ if filter_type == "yesterday":
+ start = (now - timedelta(days=1)).replace(
+ hour=0, minute=0, second=0, microsecond=0
+ )
+ end = start + timedelta(days=1)
+ return queryset.filter(
+ **{f"{field}__gte": start, f"{field}__lt": end}
+ )
+
+ if filter_type == "last_n_days" and value:
+ start = now - timedelta(days=int(value))
+ return queryset.filter(**{f"{field}__gte": start})
+
+ if filter_type == "this_week":
+ start = now - timedelta(days=now.weekday())
+ start = start.replace(hour=0, minute=0, second=0, microsecond=0)
+ return queryset.filter(**{f"{field}__gte": start})
+
+ if filter_type == "this_month":
+ start = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
+ return queryset.filter(**{f"{field}__gte": start})
+
+ if filter_type == "last_n_month" and value:
+ start = now
+ for _ in range(int(value)):
+ start = (start.replace(day=1) - timedelta(days=1)).replace(day=1)
+ start = start.replace(hour=0, minute=0, second=0, microsecond=0)
+ return queryset.filter(**{f"{field}__gte": start})
+
+ if filter_type == "this_year":
+ start = now.replace(
+ month=1, day=1, hour=0, minute=0, second=0, microsecond=0
+ )
+ return queryset.filter(**{f"{field}__gte": start})
+
+ if filter_type == "last_n_year" and value:
+ start = now.replace(
+ year=now.year - int(value),
+ month=1,
+ day=1,
+ hour=0,
+ minute=0,
+ second=0,
+ microsecond=0
+ )
+ return queryset.filter(**{f"{field}__gte": start})
+
+ return queryset
\ No newline at end of file
diff --git a/app/migrations/__pycache__/0001_initial.cpython-312.pyc b/app/migrations/__pycache__/0001_initial.cpython-312.pyc
index a5ddbdd..cc0a6f8 100644
Binary files a/app/migrations/__pycache__/0001_initial.cpython-312.pyc and b/app/migrations/__pycache__/0001_initial.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-312.pyc b/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-312.pyc
index 5c823a8..3b3176b 100644
Binary files a/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-312.pyc b/app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-312.pyc
index 05a9590..21c61a7 100644
Binary files a/app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-312.pyc b/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-312.pyc
index cada48f..72a6df4 100644
Binary files a/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-312.pyc and b/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-312.pyc b/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-312.pyc
index 007b94d..95a40f5 100644
Binary files a/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-312.pyc b/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-312.pyc
index 8ddd843..48ded36 100644
Binary files a/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0007_transportingchickendetail.cpython-312.pyc b/app/migrations/__pycache__/0007_transportingchickendetail.cpython-312.pyc
index aa50d21..53fdaf4 100644
Binary files a/app/migrations/__pycache__/0007_transportingchickendetail.cpython-312.pyc and b/app/migrations/__pycache__/0007_transportingchickendetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-312.pyc b/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-312.pyc
index 94f1302..b7b3509 100644
Binary files a/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-312.pyc b/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-312.pyc
index bb9feee..5a671f7 100644
Binary files a/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-312.pyc b/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-312.pyc
index f2d5bce..48525e3 100644
Binary files a/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc
index 2595756..bab4021 100644
Binary files a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc and b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc b/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc
index 1e4e0ac..48bdaa1 100644
Binary files a/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc and b/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-312.pyc b/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-312.pyc
index 2cb2c8a..dbc8cf8 100644
Binary files a/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-312.pyc and b/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-312.pyc b/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-312.pyc
index ede32fd..f7be85f 100644
Binary files a/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc b/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc
index a182fbd..8832884 100644
Binary files a/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc and b/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-312.pyc b/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-312.pyc
index 9c0435b..15ff979 100644
Binary files a/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0017_hatching_archivedate.cpython-312.pyc b/app/migrations/__pycache__/0017_hatching_archivedate.cpython-312.pyc
index 41413e3..342ae79 100644
Binary files a/app/migrations/__pycache__/0017_hatching_archivedate.cpython-312.pyc and b/app/migrations/__pycache__/0017_hatching_archivedate.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-312.pyc b/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-312.pyc
index be72a4f..b8ca5ac 100644
Binary files a/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-312.pyc and b/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc b/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc
index a832a59..a55f788 100644
Binary files a/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc and b/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0020_killhouse.cpython-312.pyc b/app/migrations/__pycache__/0020_killhouse.cpython-312.pyc
index 806a0f7..0caf569 100644
Binary files a/app/migrations/__pycache__/0020_killhouse.cpython-312.pyc and b/app/migrations/__pycache__/0020_killhouse.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-312.pyc b/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-312.pyc
index 358084b..60e9905 100644
Binary files a/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-312.pyc b/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-312.pyc
index 4dce39a..93e93fe 100644
Binary files a/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-312.pyc and b/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-312.pyc b/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-312.pyc
index 9899198..eaa4f08 100644
Binary files a/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-312.pyc and b/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-312.pyc b/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-312.pyc
index 4426600..bdc3cb8 100644
Binary files a/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-312.pyc and b/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-312.pyc b/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-312.pyc
index c88e24b..6a3faba 100644
Binary files a/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-312.pyc and b/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc b/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc
index 662eb62..2645514 100644
Binary files a/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc and b/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-312.pyc b/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-312.pyc
index b75b06e..fb688a6 100644
Binary files a/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc b/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc
index 0dbf14a..8955e83 100644
Binary files a/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc and b/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0029_apkinfo.cpython-312.pyc b/app/migrations/__pycache__/0029_apkinfo.cpython-312.pyc
index 13e1131..be52a52 100644
Binary files a/app/migrations/__pycache__/0029_apkinfo.cpython-312.pyc and b/app/migrations/__pycache__/0029_apkinfo.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc b/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc
index 262fa7d..51ec331 100644
Binary files a/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc and b/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc b/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc
index f48b274..02bbebf 100644
Binary files a/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc and b/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc b/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc
index 667865e..03ddff4 100644
Binary files a/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc and b/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-312.pyc b/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-312.pyc
index 13b0136..2521f09 100644
Binary files a/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-312.pyc and b/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0034_guilds.cpython-312.pyc b/app/migrations/__pycache__/0034_guilds.cpython-312.pyc
index f06f7a4..a0c0ad3 100644
Binary files a/app/migrations/__pycache__/0034_guilds.cpython-312.pyc and b/app/migrations/__pycache__/0034_guilds.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc b/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc
index f2af498..0a0305a 100644
Binary files a/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc and b/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0036_driver.cpython-312.pyc b/app/migrations/__pycache__/0036_driver.cpython-312.pyc
index 7aeeb52..0448474 100644
Binary files a/app/migrations/__pycache__/0036_driver.cpython-312.pyc and b/app/migrations/__pycache__/0036_driver.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc b/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc
index 03d4cfd..1c34822 100644
Binary files a/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc and b/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0038_auto_20250927_0848.cpython-312.pyc b/app/migrations/__pycache__/0038_auto_20250927_0848.cpython-312.pyc
index 8b19b96..79e621d 100644
Binary files a/app/migrations/__pycache__/0038_auto_20250927_0848.cpython-312.pyc and b/app/migrations/__pycache__/0038_auto_20250927_0848.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc b/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc
index b026427..334e790 100644
Binary files a/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc and b/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-312.pyc b/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-312.pyc
index f7444ed..0a82800 100644
Binary files a/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-312.pyc and b/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-312.pyc b/app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-312.pyc
index 15aa539..774f202 100644
Binary files a/app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-312.pyc and b/app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-312.pyc b/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-312.pyc
index 591592f..e798b99 100644
Binary files a/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-312.pyc and b/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0043_allproductstransport.cpython-312.pyc b/app/migrations/__pycache__/0043_allproductstransport.cpython-312.pyc
new file mode 100644
index 0000000..6098772
Binary files /dev/null and b/app/migrations/__pycache__/0043_allproductstransport.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0044_evacuationdetail.cpython-312.pyc b/app/migrations/__pycache__/0044_evacuationdetail.cpython-312.pyc
new file mode 100644
index 0000000..f0f1946
Binary files /dev/null and b/app/migrations/__pycache__/0044_evacuationdetail.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-312.pyc b/app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-312.pyc
new file mode 100644
index 0000000..f28900c
Binary files /dev/null and b/app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/0046_rasadyarappinfo.cpython-312.pyc b/app/migrations/__pycache__/0046_rasadyarappinfo.cpython-312.pyc
new file mode 100644
index 0000000..a040b7c
Binary files /dev/null and b/app/migrations/__pycache__/0046_rasadyarappinfo.cpython-312.pyc differ
diff --git a/app/migrations/__pycache__/__init__.cpython-312.pyc b/app/migrations/__pycache__/__init__.cpython-312.pyc
index e29035b..66a9919 100644
Binary files a/app/migrations/__pycache__/__init__.cpython-312.pyc and b/app/migrations/__pycache__/__init__.cpython-312.pyc differ
diff --git a/app/urls.py b/app/urls.py
index abd0ebf..d41facc 100644
--- a/app/urls.py
+++ b/app/urls.py
@@ -11,9 +11,10 @@ from app.views import get_transport_to_kill, add_kill_house, update_hatching, ge
dashboard_province_detail_for_map, TransportCarcassDashboardView, GuildsTransportCarcassDashboardView, \
AllProductsTransportDashboardView, AllProductsTransportProductsListView, update_product_date, \
send_transport_carcass_detail_for_rasadyaar, delete_free_bar_from_rasadyaar, fix_number, \
- get_evacuation_detail_by_request_code, get_evacuation_details_by_request_codes, evacuation_report_type_summary, get_all_products_transport_by_code, \
+ get_evacuation_detail_by_request_code, get_evacuation_details_by_request_codes, evacuation_report_type_summary, \
+ get_all_products_transport_by_code, \
get_all_products_transport_dashboard_by_code, get_all_products_transport_products_by_code, \
- get_all_products_transport_provinces_by_code
+ get_all_products_transport_provinces_by_code, get_ai_response
router = DefaultRouter()
@@ -236,6 +237,7 @@ urlpatterns = [
path('get-all-products-transport-products-by-code/', get_all_products_transport_products_by_code),
path('get-all-products-transport-provinces-by-code/', get_all_products_transport_provinces_by_code),
path('all_products_transport_excel/', all_products_transport_excel),
+ path('get_ai_response/', get_ai_response),
]
diff --git a/app/views.py b/app/views.py
index a1797e9..4e29fda 100644
--- a/app/views.py
+++ b/app/views.py
@@ -26,7 +26,7 @@ from app.filtersets import PoultryFilterSet, PoultryHatchingFilterSet, Transport
PoultryInfoFilterSet, HatchingCalculationsFilterSet, HatchingsFilterSet, TransportingDetailFilterSet, \
KillHouseFilterSet, TransportingDetailCustomFilterSet, CustomHatchingsFilterSet, TransportCarcassDetailFilterSet, \
DriverFilterSet, GuildsFilterSet, AllProductsTransportFilterSet
-from app.helper import SSLAdapter, get_hatching_permit_code, normalize_persian_arabic_text
+from app.helper import SSLAdapter, get_hatching_permit_code, normalize_persian_arabic_text, apply_date_filter
from app.models import Poultry, PoultryHatching, TransportingChickenDetail, Hatching, TransportingDetail, KillHouse, \
ApkInfo, TransportCarcassDetail, Guilds, Driver, InquiryCredentials, AllProductsTransport, EvacuationDetail, \
RasadyarAppInfo
@@ -987,7 +987,7 @@ class HatchingsCustomViewSet(viewsets.ModelViewSet):
if poultry:
hatching.poultry = poultry
hatching.save()
-
+
allowed_evacuation_fields = {
'PartIdCode', 'RequestId', 'MoReportId', 'ReportType', 'ReportTypeString',
'ReportDate', 'ReportDateShamsi', 'MoReason', 'MoDate', 'MoDateShamsi',
@@ -1308,7 +1308,7 @@ class TransportingDashboardViewSet(viewsets.ModelViewSet):
date__gte=date1,
date__lte=date2,
date__isnull=False
-
+
)
except ValueError:
pass
@@ -1443,31 +1443,31 @@ class TransportingDetailViewSet(viewsets.ModelViewSet):
# Query برای AllProductsTransport با product='مرغ زنده -جهت كشتار'
query_all_products = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='مرغ زنده -جهت كشتار'
)
-
+
# اعمال فیلترها روی AllProductsTransport
if PartIdCode:
query_all_products = query_all_products.filter(jihadi_destination=PartIdCode)
-
+
if RequestCode:
query_all_products = query_all_products.filter(hatching__RequestCode=RequestCode)
-
+
if date1 and date2:
query_all_products = query_all_products.filter(
date__gte=date1,
date__lte=date2,
date__isnull=False
-
+
)
-
+
if city:
query_all_products = query_all_products.filter(destination_city__icontains=city)
-
+
if province:
query_all_products = query_all_products.filter(destination_province__icontains=province)
-
+
if search:
if search != 'undefined' and search.strip():
transports = transports.filter(
@@ -1477,11 +1477,11 @@ class TransportingDetailViewSet(viewsets.ModelViewSet):
query_all_products = query_all_products.filter(
build_query(AllProductsTransportFilterSet.Meta.fields, search)
)
-
+
# تبدیل به list و ترکیب
transports_list = list(transports)
all_products_list = list(query_all_products)
-
+
# تبدیل AllProductsTransport به TransportingDetail-like objects برای sort
def get_sort_date(obj):
if hasattr(obj, 'Date') and obj.Date:
@@ -1494,13 +1494,13 @@ class TransportingDetailViewSet(viewsets.ModelViewSet):
elif hasattr(obj, 'unloading_date') and obj.unloading_date:
return obj.unloading_date
return datetime.date.min
-
+
combined_list = []
for obj in transports_list:
combined_list.append((get_sort_date(obj), 'transporting', obj))
for obj in all_products_list:
combined_list.append((get_sort_date(obj), 'all_products', obj))
-
+
combined_list.sort(key=lambda x: x[0], reverse=True)
sorted_objects = [obj for _, _, obj in combined_list]
@@ -1510,7 +1510,7 @@ class TransportingDetailViewSet(viewsets.ModelViewSet):
paginator = self.pagination_class()
page = paginator.paginate_queryset(sorted_objects, request)
-
+
if page is not None:
serialized_data = []
for obj in page:
@@ -1667,25 +1667,25 @@ class TotalKillHousesViewSet(viewsets.ModelViewSet):
self.pagination_class.page_size = int(page_size)
page = self.paginate_queryset(kill_houses)
-
+
items_to_serialize = page if page is not None else kill_houses
part_id_codes = list(kill_houses.values_list('PartIdCode', flat=True).distinct())
info_cache = {}
-
+
if part_id_codes:
date1 = request.GET.get('date1') or None
date2 = request.GET.get('date2') or None
-
+
bars_query = TransportingDetail.objects.filter(
- DesPartIdCode__in=part_id_codes,
+ DesPartIdCode__in=part_id_codes,
trash=False
).only('DesPartIdCode', 'GoodAmount', 'Out', 'Date')
-
+
if date1:
date1_obj = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date()
date2_obj = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date()
bars_query = bars_query.filter(Date__date__gte=date1_obj, Date__date__lte=date2_obj)
-
+
bars_aggregations = bars_query.values('DesPartIdCode').annotate(
total=Sum('GoodAmount'),
input_total=Sum('GoodAmount', filter=Q(Out=False)),
@@ -1694,21 +1694,21 @@ class TotalKillHousesViewSet(viewsets.ModelViewSet):
output_count=Count('id', filter=Q(Out=True)),
total_count=Count('id')
)
-
+
all_products_query = AllProductsTransport.objects.filter(
jihadi_destination__in=part_id_codes,
trash=False,
product='مرغ زنده -جهت كشتار'
).only('jihadi_destination', 'quantity', 'out', 'date', 'unloading_date')
-
+
if date1:
all_products_query = all_products_query.filter(
date__gte=date1_obj,
date__lte=date2_obj,
date__isnull=False
-
+
)
-
+
all_products_aggregations = all_products_query.values('jihadi_destination').annotate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -1717,28 +1717,28 @@ class TotalKillHousesViewSet(viewsets.ModelViewSet):
output_count=Count('id', filter=Q(out=True)),
total_count=Count('id')
)
-
+
bars_dict = {item['DesPartIdCode']: item for item in bars_aggregations}
all_products_dict = {item['jihadi_destination']: item for item in all_products_aggregations}
-
+
for part_id_code in part_id_codes:
bars_data = bars_dict.get(part_id_code, {})
all_products_data = all_products_dict.get(part_id_code, {})
-
+
total_count = (bars_data.get('total_count') or 0) + (all_products_data.get('total_count') or 0)
total_bars_quantity = (bars_data.get('total') or 0) + (all_products_data.get('total') or 0)
total_input_bars_quantity = (bars_data.get('input_total') or 0) + (all_products_data.get('input_total') or 0)
total_output_bars_quantity = (bars_data.get('output_total') or 0) + (all_products_data.get('output_total') or 0)
input_bars_count = (bars_data.get('input_count') or 0) + (all_products_data.get('input_count') or 0)
output_bars_count = (bars_data.get('output_count') or 0) + (all_products_data.get('output_count') or 0)
-
+
if total_count > 0:
total_input_bars_percent = round((input_bars_count / total_count) * 100, 1)
total_output_bars_percent = round((output_bars_count / total_count) * 100, 1)
else:
total_input_bars_percent = 0
total_output_bars_percent = 0
-
+
info_cache[part_id_code] = {
"bars": total_count,
"total_bars_quantity": total_bars_quantity,
@@ -2259,7 +2259,7 @@ def dashboard_total_kill_house(request):
build_query(filterset_class.Meta.fields, search)
)
part_id_codes = list(kill_houses.values_list('PartIdCode', flat=True))
-
+
if not part_id_codes:
return Response({
"killHouseCount": 0,
@@ -2274,12 +2274,12 @@ def dashboard_total_kill_house(request):
"low_kill_house_name": None,
"low_kill_house_amount": None,
})
-
+
# بهینهسازی: استفاده از only() برای کاهش دادههای خوانده شده
bars = TransportingDetail.objects.filter(DesPartIdCode__in=part_id_codes, trash=False).only('DesPartIdCode', 'GoodAmount', 'Out', 'Date')
-
+
all_products_transport = AllProductsTransport.objects.filter(
- jihadi_destination__in=part_id_codes,
+ jihadi_destination__in=part_id_codes,
trash=False,
product='مرغ زنده -جهت كشتار'
).only('jihadi_destination', 'quantity', 'out', 'date', 'unloading_date')
@@ -2292,27 +2292,27 @@ def dashboard_total_kill_house(request):
date__gte=date1,
date__lte=date2,
date__isnull=False
-
+
)
# بهینهسازی: ترکیب aggregation ها در یک query
kill_house_stats_bars = bars.values('DesPartIdCode').annotate(
total_amount=Sum('GoodAmount')
)
-
+
kill_house_stats_all_products = all_products_transport.values('jihadi_destination').annotate(
total_amount=Sum('quantity')
)
-
+
# بهینهسازی: استفاده از dictionary comprehension
stats_dict = {stat['DesPartIdCode']: (stat['total_amount'] or 0) for stat in kill_house_stats_bars}
-
+
for stat in kill_house_stats_all_products:
part_id = stat['jihadi_destination']
stats_dict[part_id] = stats_dict.get(part_id, 0) + (stat['total_amount'] or 0)
-
+
kill_house_stats = [
- {'DesPartIdCode': k, 'total_amount': v}
+ {'DesPartIdCode': k, 'total_amount': v}
for k, v in sorted(stats_dict.items(), key=lambda x: x[1], reverse=True)
]
@@ -2325,10 +2325,10 @@ def dashboard_total_kill_house(request):
# بهینهسازی: یک query برای هر دو kill house
kill_house_part_ids = [top_stat['DesPartIdCode'], low_stat['DesPartIdCode']]
kill_houses_dict = {kh.PartIdCode: kh for kh in KillHouse.objects.filter(PartIdCode__in=kill_house_part_ids).only('PartIdCode', 'UnitName')}
-
+
top_kill_house = kill_houses_dict.get(top_stat['DesPartIdCode'])
low_kill_house = kill_houses_dict.get(low_stat['DesPartIdCode'])
-
+
if top_kill_house:
top_kill_house_info = {
"name": top_kill_house.UnitName,
@@ -2349,7 +2349,7 @@ def dashboard_total_kill_house(request):
output_count=Count('id', filter=Q(Out=True)),
total_count=Count('id')
)
-
+
aggregation_all_products = all_products_transport.aggregate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -2732,7 +2732,7 @@ class RasadyarAppInfoViewSet(viewsets.ModelViewSet):
uploaded_file = request.FILES['file']
file_extension = uploaded_file.name.split('.')[-1] if '.' in uploaded_file.name else ''
unique_filename = f"rasadyar_app_info_{uuid.uuid4().hex}.{file_extension}" if file_extension else f"rasadyar_app_info_{uuid.uuid4().hex}"
-
+
file_url = upload_to_liara(uploaded_file, unique_filename)
instance.file = file_url
@@ -2792,17 +2792,17 @@ class TransportCarcassDetailViewSet(viewsets.ModelViewSet):
date1 = request.GET.get('date1')
code = request.GET.get('code')
filters={}
-
+
# Query برای TransportCarcassDetail
query_carcass = self.queryset.filter(jihadi_origin=code)
-
+
# Query برای AllProductsTransport با product='گوشت مرغ تازه'
query_all_products = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='گوشت مرغ تازه',
jihadi_origin=code
)
-
+
if date1:
date1 = datetime.datetime.strptime(str(request.GET['date1']),
'%Y-%m-%d').date()
@@ -2821,13 +2821,13 @@ class TransportCarcassDetailViewSet(viewsets.ModelViewSet):
)
)
query_all_products = query_all_products.filter(
-
+
date__gte=date1,
date__lte=date2,
date__isnull=False
-
+
)
-
+
if search:
if search != 'undefined' and search.strip():
query_carcass = query_carcass.filter(
@@ -2837,11 +2837,11 @@ class TransportCarcassDetailViewSet(viewsets.ModelViewSet):
query_all_products = query_all_products.filter(
build_query(AllProductsTransportFilterSet.Meta.fields, search)
)
-
+
# تبدیل به list و ترکیب
carcass_list = list(query_carcass)
all_products_list = list(query_all_products)
-
+
# تبدیل AllProductsTransport به TransportCarcassDetail-like objects برای sort
def get_sort_date(obj):
if hasattr(obj, 'product_date') and obj.product_date:
@@ -2851,17 +2851,17 @@ class TransportCarcassDetailViewSet(viewsets.ModelViewSet):
elif hasattr(obj, 'unloading_date') and obj.unloading_date:
return obj.unloading_date
return datetime.date.min
-
+
# ایجاد یک list ترکیبی با tuple (date, source_type, obj)
combined_list = []
for obj in carcass_list:
combined_list.append((get_sort_date(obj), 'carcass', obj))
for obj in all_products_list:
combined_list.append((get_sort_date(obj), 'all_products', obj))
-
+
# sort بر اساس date (از جدید به قدیم)
combined_list.sort(key=lambda x: x[0], reverse=True)
-
+
# جدا کردن objects
sorted_objects = [obj for _, _, obj in combined_list]
@@ -2872,7 +2872,7 @@ class TransportCarcassDetailViewSet(viewsets.ModelViewSet):
# Pagination روی list
paginator = self.pagination_class()
page = paginator.paginate_queryset(sorted_objects, request)
-
+
if page is not None:
# Serialize هر object با serializer مناسب
serialized_data = []
@@ -3407,12 +3407,12 @@ class TransportCarcassDashboardView(APIView):
TrackingStatusDescription__in=("تایید تخلیه",'بارگیری')).only(
'GoodAmount', 'Out')
all_products_transport_carcass = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='گوشت مرغ تازه',
jihadi_origin__in=kill_house
)
all_products_transport = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='مرغ زنده -جهت كشتار',
jihadi_destination__in=kill_house
)
@@ -3635,21 +3635,21 @@ class TransportCarcassDashboardView(APIView):
})
return Response('ok', status=status.HTTP_200_OK)
-
+
def _get_last_update_date_for_dashboard(self, queryset1, queryset2):
"""تابع helper برای دریافت آخرین تاریخ بهروزرسانی از دو queryset"""
dates = []
-
+
if queryset1.exists():
first_obj = queryset1.first()
if first_obj and hasattr(first_obj, 'modify_date') and first_obj.modify_date:
dates.append(first_obj.modify_date)
-
+
if queryset2.exists():
first_obj = queryset2.first()
if first_obj and hasattr(first_obj, 'modify_date') and first_obj.modify_date:
dates.append(first_obj.modify_date)
-
+
return max(dates) if dates else None
@@ -3671,18 +3671,18 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
code = request.GET.get('code')
date1 = request.GET.get('date1')
filters={}
-
+
query_carcass = TransportCarcassDetail.objects.filter(
jihadi_destination=code,
trash=False
)
-
+
query_all_products = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='گوشت مرغ تازه',
jihadi_destination=code
)
-
+
if date1:
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
@@ -3702,9 +3702,9 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
date__gte=date1,
date__lte=date2,
date__isnull=False
-
+
)
-
+
if search and search != 'undefined' and search.strip():
query_carcass = query_carcass.filter(
build_query(self.filterset_class.Meta.fields, search)
@@ -3712,10 +3712,10 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
query_all_products = query_all_products.filter(
build_query(AllProductsTransportFilterSet.Meta.fields, search)
)
-
+
carcass_list = list(query_carcass)
all_products_list = list(query_all_products)
-
+
def get_sort_date(obj):
if hasattr(obj, 'product_date') and obj.product_date:
return obj.product_date
@@ -3724,13 +3724,13 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
elif hasattr(obj, 'unloading_date') and obj.unloading_date:
return obj.unloading_date
return datetime.date.min
-
+
combined_list = []
for obj in carcass_list:
combined_list.append((get_sort_date(obj), 'carcass', obj))
for obj in all_products_list:
combined_list.append((get_sort_date(obj), 'all_products', obj))
-
+
combined_list.sort(key=lambda x: x[0], reverse=True)
sorted_objects = [obj for _, _, obj in combined_list]
@@ -3740,7 +3740,7 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
paginator = self.pagination_class()
page = paginator.paginate_queryset(sorted_objects, request)
-
+
if page is not None:
serialized_data = []
for obj in page:
@@ -3791,11 +3791,11 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
jihadi_destination__in=steward_jihadi_codes
).order_by('-product_date')
all_products_transport = AllProductsTransport.objects.filter(
- trash=False,
+ trash=False,
product='گوشت مرغ تازه',
jihadi_destination__in=steward_jihadi_codes
)
-
+
if date1:
date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date()
date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date()
@@ -3866,7 +3866,7 @@ class GuildsTransportCarcassViewSet(viewsets.ModelViewSet):
if st.jihadi_code and st.jihadi_code not in seen_jihadi_codes:
seen_jihadi_codes.add(st.jihadi_code)
unique_stewards.append(st)
-
+
unique_stewards.sort(
key=lambda st: (bars_dict.get(st.jihadi_code, {}) or {}).get('total_ware_house', 0) or 0,
reverse=True
@@ -3920,7 +3920,7 @@ class GuildsTransportCarcassDashboardView(APIView):
product='گوشت مرغ تازه',
jihadi_destination__in=steward
)
-
+
if date1:
date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date()
date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date()
@@ -4160,14 +4160,14 @@ def send_transport_carcass_detail_for_rasadyaar(request):
quarantine_bars = list(bars.values_list('tracking',flat=True).distinct())
quarantine_buy = list(buy_bars.values_list('TrackingCode',flat=True).distinct())
all_track = quarantine_bars + quarantine_buy
-
+
all_products_carcass = AllProductsTransport.objects.filter(
- date__gte=date1,
+ date__gte=date1,
date__lte=date2,
trash=False,
product='گوشت مرغ تازه'
).exclude(tracking__in=all_track).only('quantity','out','id','jihadi_origin', 'tracking')
-
+
all_products_live = AllProductsTransport.objects.filter(
date__gte=date_1_for_buy_bars, date__lte=date_2_for_buy_bars, date__isnull=False,
trash=False,
@@ -4182,7 +4182,7 @@ def send_transport_carcass_detail_for_rasadyaar(request):
output_count=Count('id', filter=Q(out=True)),
total_count=Count('id'),
)
-
+
all_products_carcass_summary = all_products_carcass.values('jihadi_origin').annotate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -4200,7 +4200,7 @@ def send_transport_carcass_detail_for_rasadyaar(request):
output_count=Count('id', filter=Q(Out=True)),
total_count=Count('id'),
)
-
+
all_products_live_summary = all_products_live.values('jihadi_destination').annotate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -4267,7 +4267,7 @@ def send_transport_carcass_detail_for_rasadyaar(request):
buy_dict[key]['input_count'] += row['input_count'] or 0
buy_dict[key]['output_count'] += row['output_count'] or 0
buy_dict[key]['total_count'] += row['total_count'] or 0
-
+
for row in all_products_live_summary:
key = row['jihadi_destination']
if key:
@@ -4353,16 +4353,16 @@ def get_evacuation_details_by_request_codes(request):
result = {}
hatchings = Hatching.objects.filter(RequestCode__in=request_codes, trash=False)
-
+
for hatching in hatchings:
evacuations = EvacuationDetail.objects.filter(hatching=hatching, trash=False).order_by('-create_date')
serializer = EvacuationDetailSerializer(evacuations, many=True)
result[hatching.RequestCode] = serializer.data
-
+
for code in request_codes:
if code not in result:
result[code] = []
-
+
return Response(result, status=status.HTTP_200_OK)
@@ -4393,23 +4393,23 @@ class EvacuationDetailViewSet(viewsets.ModelViewSet):
def create(self, request, *args, **kwargs):
data_list = request.data if isinstance(request.data, list) else [request.data]
-
+
total_created = 0
total_updated = 0
-
+
for item_data in data_list:
evacuation_details = item_data.get('EvacuationDetail', [])
if not evacuation_details or len(evacuation_details) == 0:
continue
-
+
request_code = item_data.get('RequestCode')
if not request_code:
continue
-
+
hatching = Hatching.objects.filter(RequestCode=request_code, trash=False).first()
if not hatching:
continue
-
+
for evacuation_data in evacuation_details:
clean_data = evacuation_data.copy()
external_id = clean_data.pop('Id', None)
@@ -4421,7 +4421,7 @@ class EvacuationDetailViewSet(viewsets.ModelViewSet):
ExternalId=external_id,
trash=False
).first()
-
+
if evacuation:
for key, value in clean_data.items():
setattr(evacuation, key, value)
@@ -4432,7 +4432,7 @@ class EvacuationDetailViewSet(viewsets.ModelViewSet):
clean_data['hatching'] = hatching
EvacuationDetail.objects.create(**clean_data)
total_created += 1
-
+
return Response({
"result": "با موفقیت ثبت شد",
"created": total_created,
@@ -4441,14 +4441,14 @@ class EvacuationDetailViewSet(viewsets.ModelViewSet):
def list(self, request, *args, **kwargs):
evacuations = self.filter_queryset(self.get_queryset())
-
+
search = request.GET.get('search')
if search:
if search != 'undefined' and search.strip():
evacuations = evacuations.filter(
build_query(['TrackingCode', 'SourceUnitName', 'DesUnitName'], search)
)
-
+
page_size = request.query_params.get('page_size', None)
if page_size:
self.pagination_class.page_size = int(page_size)
@@ -4557,7 +4557,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
location_cache = {}
context = self.get_serializer_context()
context['location_cache'] = location_cache
-
+
if page is not None:
serializer = self.get_serializer(page, many=True, context=context)
return self.get_paginated_response(serializer.data)
@@ -4635,7 +4635,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
continue
row_data = dict(zip(headers, row))
-
+
tracking_val = row_data.get("کد رهگیری") or row_data.get("رهگیری")
province_name = row_data.get("شهرستان مقصد") or row_data.get("شهرستان مقصد")
jihadi_origin_code = row_data.get("ش جهادی مبدا") or row_data.get("ش جهادی مبدا")
@@ -4654,7 +4654,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
for col_name, model_field in field_map.items():
if col_name in row_data:
value = row_data[col_name]
-
+
if model_field in ["date", "unloading_date"] and value:
try:
if isinstance(value, str):
@@ -4669,7 +4669,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
value = convert_to_miladi(value.year, value.month, value.day)
except (ValueError, AttributeError, IndexError):
value = None
-
+
if model_field == "quantity" and value:
try:
if isinstance(value, str):
@@ -4678,7 +4678,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
value = float(value)
except (ValueError, TypeError):
value = None
-
+
if model_field in ["gross_weight", "tare_weight", "net_weight"] and value:
try:
if isinstance(value, str):
@@ -4687,7 +4687,7 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
value = float(value)
except (ValueError, TypeError):
value = None
-
+
record_data[model_field] = value
hatching_obj = None
@@ -4718,12 +4718,12 @@ class AllProductsTransportViewSet(viewsets.ModelViewSet):
if hatching_obj:
new_record.hatching = hatching_obj
new_record.save()
-
+
if new_record.destination_province and new_record.origin_province:
if new_record.destination_province != new_record.origin_province:
new_record.out = True
new_record.save()
-
+
created_count += 1
return Response({
@@ -4978,7 +4978,7 @@ def _convert_transporting_detail_to_unified(obj):
'RequestCode': obj.hatching.RequestCode,
'PedigreeName': obj.hatching.PedigreeName,
}
-
+
return {
'id': obj.id,
'key': str(obj.key),
@@ -5075,7 +5075,7 @@ def _convert_all_products_to_unified(obj):
'RequestCode': obj.hatching.RequestCode,
'PedigreeName': obj.hatching.PedigreeName,
}
-
+
return {
'id': obj.id,
'key': str(obj.key),
@@ -5120,24 +5120,24 @@ def get_all_products_transport_by_code(request):
code = request.GET.get('code')
if not code:
return Response(
- {'detail': 'کد الزامی است'},
+ {'detail': 'کد الزامی است'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
transport_type = request.GET.get('type')
if transport_type not in ['in', 'out']:
return Response(
- {'detail': 'نوع باید in یا out باشد'},
+ {'detail': 'نوع باید in یا out باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
from_source = request.GET.get('from')
if from_source and from_source not in ['Poultry', 'KillHouse']:
return Response(
- {'detail': 'from باید Poultry یا KillHouse باشد'},
+ {'detail': 'from باید Poultry یا KillHouse باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
date1 = request.GET.get('date1')
date2 = request.GET.get('date2')
start_date = None
@@ -5148,14 +5148,14 @@ def get_all_products_transport_by_code(request):
end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d')
except ValueError:
pass
-
+
province = request.GET.get('province')
product_type = request.GET.get('product')
search = request.GET.get('search')
-
+
unified_results = []
seen_tracking_codes = set()
-
+
def add_if_not_duplicate(item):
tracking = item.get('tracking')
if tracking and tracking in seen_tracking_codes:
@@ -5164,7 +5164,7 @@ def get_all_products_transport_by_code(request):
seen_tracking_codes.add(tracking)
unified_results.append(item)
return True
-
+
if from_source == 'Poultry':
if transport_type == 'out':
all_products = AllProductsTransport.objects.filter(
@@ -5177,10 +5177,10 @@ def get_all_products_transport_by_code(request):
all_products = all_products.filter(destination_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
for obj in all_products:
add_if_not_duplicate(_convert_all_products_to_unified(obj))
-
+
transport_details = TransportingDetail.objects.filter(
trash=False,
hatching__poultry__PartIdCode=code,
@@ -5190,7 +5190,7 @@ def get_all_products_transport_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(Province=province)
-
+
for obj in transport_details:
add_if_not_duplicate(_convert_transporting_detail_to_unified(obj))
else:
@@ -5204,10 +5204,10 @@ def get_all_products_transport_by_code(request):
all_products = all_products.filter(origin_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
for obj in all_products:
add_if_not_duplicate(_convert_all_products_to_unified(obj))
-
+
elif from_source == 'KillHouse':
if transport_type == 'out':
carcass_details = TransportCarcassDetail.objects.filter(
@@ -5220,7 +5220,7 @@ def get_all_products_transport_by_code(request):
carcass_details = carcass_details.filter(destination_province=province)
if product_type and product_type != 'undefined':
carcass_details = carcass_details.filter(product=product_type)
-
+
for obj in carcass_details:
add_if_not_duplicate(_convert_transport_carcass_to_unified(obj))
else:
@@ -5233,10 +5233,10 @@ def get_all_products_transport_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(hatching__ProvinceName=province)
-
+
for obj in transport_details:
add_if_not_duplicate(_convert_transporting_detail_to_unified(obj))
-
+
else:
if transport_type == 'out':
bars = AllProductsTransport.objects.filter(
@@ -5248,7 +5248,7 @@ def get_all_products_transport_by_code(request):
trash=False,
jihadi_destination=code
)
-
+
if start_date and end_date:
bars = bars.filter(date__gte=start_date, date__lte=end_date)
if province and province != 'undefined':
@@ -5258,10 +5258,10 @@ def get_all_products_transport_by_code(request):
bars = bars.filter(origin_province=province)
if product_type and product_type != 'undefined':
bars = bars.filter(product=product_type)
-
+
for obj in bars:
add_if_not_duplicate(_convert_all_products_to_unified(obj))
-
+
if search and search != 'undefined' and search.strip():
search_lower = search.lower()
unified_results = [
@@ -5273,19 +5273,19 @@ def get_all_products_transport_by_code(request):
(r.get('driver_name') and search_lower in str(r['driver_name']).lower()) or
(r.get('owner') and search_lower in str(r['owner']).lower())
]
-
+
unified_results.sort(key=lambda x: x.get('date') or datetime.date.min, reverse=True)
-
+
paginator = CustomPagination()
page_size = request.query_params.get('page_size', None)
if page_size:
paginator.page_size = int(page_size)
-
+
page_number = int(request.query_params.get('page', 1))
start_index = (page_number - 1) * paginator.page_size
end_index = start_index + paginator.page_size
paginated_results = unified_results[start_index:end_index]
-
+
return Response({
'count': len(unified_results),
'next': f"?page={page_number + 1}" if end_index < len(unified_results) else None,
@@ -5301,24 +5301,24 @@ def get_all_products_transport_products_by_code(request):
code = request.GET.get('code')
if not code:
return Response(
- {'detail': 'کد الزامی است'},
+ {'detail': 'کد الزامی است'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
transport_type = request.GET.get('type')
if transport_type not in ['in', 'out']:
return Response(
- {'detail': 'نوع باید in یا out باشد'},
+ {'detail': 'نوع باید in یا out باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
from_source = request.GET.get('from')
if from_source and from_source not in ['Poultry', 'KillHouse']:
return Response(
- {'detail': 'from باید Poultry یا KillHouse باشد'},
+ {'detail': 'from باید Poultry یا KillHouse باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
date1 = request.GET.get('date1')
date2 = request.GET.get('date2')
start_date = None
@@ -5329,13 +5329,13 @@ def get_all_products_transport_products_by_code(request):
end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d')
except ValueError:
pass
-
+
province = request.GET.get('province')
product_type = request.GET.get('product')
search = request.GET.get('search')
-
- products_set = set()
-
+
+ products_set = set()
+
if from_source == 'Poultry':
if transport_type == 'out':
all_products = AllProductsTransport.objects.filter(
@@ -5348,14 +5348,14 @@ def get_all_products_transport_products_by_code(request):
all_products = all_products.filter(destination_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
products_set.update(
all_products.filter(product__isnull=False)
.exclude(product='')
.values_list('product', flat=True)
.distinct()
)
-
+
transport_details = TransportingDetail.objects.filter(
trash=False,
hatching__poultry__PartIdCode=code,
@@ -5365,7 +5365,7 @@ def get_all_products_transport_products_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(Province=province)
-
+
products_set.update(
transport_details.filter(GoodName__isnull=False)
.exclude(GoodName='')
@@ -5383,14 +5383,14 @@ def get_all_products_transport_products_by_code(request):
all_products = all_products.filter(origin_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
products_set.update(
all_products.filter(product__isnull=False)
.exclude(product='')
.values_list('product', flat=True)
.distinct()
)
-
+
elif from_source == 'KillHouse':
if transport_type == 'out':
carcass_details = TransportCarcassDetail.objects.filter(
@@ -5403,7 +5403,7 @@ def get_all_products_transport_products_by_code(request):
carcass_details = carcass_details.filter(destination_province=province)
if product_type and product_type != 'undefined':
carcass_details = carcass_details.filter(product=product_type)
-
+
products_set.update(
carcass_details.filter(product__isnull=False)
.exclude(product='')
@@ -5420,14 +5420,14 @@ def get_all_products_transport_products_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(hatching__ProvinceName=province)
-
+
products_set.update(
transport_details.filter(GoodName__isnull=False)
.exclude(GoodName='')
.values_list('GoodName', flat=True)
.distinct()
)
-
+
else:
if transport_type == 'out':
bars = AllProductsTransport.objects.filter(
@@ -5439,7 +5439,7 @@ def get_all_products_transport_products_by_code(request):
trash=False,
jihadi_destination=code
)
-
+
if start_date and end_date:
bars = bars.filter(date__gte=start_date, date__lte=end_date)
if province and province != 'undefined':
@@ -5456,16 +5456,16 @@ def get_all_products_transport_products_by_code(request):
.values_list('product', flat=True)
.distinct()
)
-
+
if search and search != 'undefined' and search.strip():
search_lower = search.lower()
products_set = {
p for p in products_set
if p and search_lower in str(p).lower()
}
-
+
products = sorted([p for p in products_set if p], key=str)
-
+
return Response({
"products": products
}, status=status.HTTP_200_OK)
@@ -5478,24 +5478,24 @@ def get_all_products_transport_provinces_by_code(request):
code = request.GET.get('code')
if not code:
return Response(
- {'detail': 'کد الزامی است'},
+ {'detail': 'کد الزامی است'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
transport_type = request.GET.get('type')
if transport_type not in ['in', 'out']:
return Response(
- {'detail': 'نوع باید in یا out باشد'},
+ {'detail': 'نوع باید in یا out باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
from_source = request.GET.get('from')
if from_source and from_source not in ['Poultry', 'KillHouse']:
return Response(
- {'detail': 'from باید Poultry یا KillHouse باشد'},
+ {'detail': 'from باید Poultry یا KillHouse باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
date1 = request.GET.get('date1')
date2 = request.GET.get('date2')
start_date = None
@@ -5506,12 +5506,12 @@ def get_all_products_transport_provinces_by_code(request):
end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d')
except ValueError:
pass
-
+
province = request.GET.get('province')
product_type = request.GET.get('product')
search = request.GET.get('search')
- provinces_set = set()
-
+ provinces_set = set()
+
if from_source == 'Poultry':
if transport_type == 'out':
all_products = AllProductsTransport.objects.filter(
@@ -5524,14 +5524,14 @@ def get_all_products_transport_provinces_by_code(request):
all_products = all_products.filter(destination_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
provinces_set.update(
all_products.filter(destination_province__isnull=False)
.exclude(destination_province='')
.values_list('destination_province', flat=True)
.distinct()
)
-
+
transport_details = TransportingDetail.objects.filter(
trash=False,
hatching__poultry__PartIdCode=code,
@@ -5541,7 +5541,7 @@ def get_all_products_transport_provinces_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(Province=province)
-
+
provinces_set.update(
transport_details.filter(Province__isnull=False)
.exclude(Province='')
@@ -5559,14 +5559,14 @@ def get_all_products_transport_provinces_by_code(request):
all_products = all_products.filter(origin_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
provinces_set.update(
all_products.filter(origin_province__isnull=False)
.exclude(origin_province='')
.values_list('origin_province', flat=True)
.distinct()
)
-
+
elif from_source == 'KillHouse':
if transport_type == 'out':
carcass_details = TransportCarcassDetail.objects.filter(
@@ -5579,7 +5579,7 @@ def get_all_products_transport_provinces_by_code(request):
carcass_details = carcass_details.filter(destination_province=province)
if product_type and product_type != 'undefined':
carcass_details = carcass_details.filter(product=product_type)
-
+
provinces_set.update(
carcass_details.filter(destination_province__isnull=False)
.exclude(destination_province='')
@@ -5596,14 +5596,14 @@ def get_all_products_transport_provinces_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(hatching__ProvinceName=province)
-
+
provinces_set.update(
transport_details.filter(hatching__ProvinceName__isnull=False)
.exclude(hatching__ProvinceName='')
.values_list('hatching__ProvinceName', flat=True)
.distinct()
)
-
+
else:
if transport_type == 'out':
bars = AllProductsTransport.objects.filter(
@@ -5615,7 +5615,7 @@ def get_all_products_transport_provinces_by_code(request):
trash=False,
jihadi_destination=code
)
-
+
if start_date and end_date:
bars = bars.filter(date__gte=start_date, date__lte=end_date)
if province and province != 'undefined':
@@ -5625,7 +5625,7 @@ def get_all_products_transport_provinces_by_code(request):
bars = bars.filter(origin_province=province)
if product_type and product_type != 'undefined':
bars = bars.filter(product=product_type)
-
+
if transport_type == 'out':
provinces_set.update(
bars.filter(destination_province__isnull=False)
@@ -5640,16 +5640,16 @@ def get_all_products_transport_provinces_by_code(request):
.values_list('origin_province', flat=True)
.distinct()
)
-
+
if search and search != 'undefined' and search.strip():
search_lower = search.lower()
provinces_set = {
p for p in provinces_set
if p and search_lower in str(p).lower()
}
-
+
provinces = sorted([p for p in provinces_set if p], key=str)
-
+
return Response({
"provinces": provinces
}, status=status.HTTP_200_OK)
@@ -5662,24 +5662,24 @@ def get_all_products_transport_dashboard_by_code(request):
code = request.GET.get('code')
if not code:
return Response(
- {'detail': 'کد الزامی است'},
+ {'detail': 'کد الزامی است'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
transport_type = request.GET.get('type')
if transport_type not in ['in', 'out']:
return Response(
- {'detail': 'نوع باید in یا out باشد'},
+ {'detail': 'نوع باید in یا out باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
from_source = request.GET.get('from')
if from_source and from_source not in ['Poultry', 'KillHouse']:
return Response(
- {'detail': 'from باید Poultry یا KillHouse باشد'},
+ {'detail': 'from باید Poultry یا KillHouse باشد'},
status=status.HTTP_400_BAD_REQUEST
)
-
+
date1 = request.GET.get('date1')
date2 = request.GET.get('date2')
start_date = None
@@ -5690,11 +5690,11 @@ def get_all_products_transport_dashboard_by_code(request):
end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d')
except ValueError:
pass
-
+
province = request.GET.get('province')
product_type = request.GET.get('product')
search = request.GET.get('search')
-
+
total_count = 0
total_quantity = 0
input_quantity = 0
@@ -5702,7 +5702,7 @@ def get_all_products_transport_dashboard_by_code(request):
input_count = 0
output_count = 0
last_update = None
-
+
if from_source == 'Poultry':
if transport_type == 'out':
all_products = AllProductsTransport.objects.filter(
@@ -5715,7 +5715,7 @@ def get_all_products_transport_dashboard_by_code(request):
all_products = all_products.filter(destination_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
agg = all_products.aggregate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -5733,7 +5733,7 @@ def get_all_products_transport_dashboard_by_code(request):
output_count += agg['output_cnt'] or 0
if agg['last_mod'] and (not last_update or agg['last_mod'] > last_update):
last_update = agg['last_mod']
-
+
transport_details = TransportingDetail.objects.filter(
trash=False,
hatching__poultry__PartIdCode=code,
@@ -5743,7 +5743,7 @@ def get_all_products_transport_dashboard_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(Province=province)
-
+
agg = transport_details.aggregate(
total=Sum('GoodAmount'),
input_total=Sum('GoodAmount', filter=Q(Out=False)),
@@ -5772,7 +5772,7 @@ def get_all_products_transport_dashboard_by_code(request):
all_products = all_products.filter(origin_province=province)
if product_type and product_type != 'undefined':
all_products = all_products.filter(product=product_type)
-
+
agg = all_products.aggregate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -5790,7 +5790,7 @@ def get_all_products_transport_dashboard_by_code(request):
output_count += agg['output_cnt'] or 0
if agg['last_mod'] and (not last_update or agg['last_mod'] > last_update):
last_update = agg['last_mod']
-
+
elif from_source == 'KillHouse':
if transport_type == 'out':
carcass_details = TransportCarcassDetail.objects.filter(
@@ -5803,7 +5803,7 @@ def get_all_products_transport_dashboard_by_code(request):
carcass_details = carcass_details.filter(destination_province=province)
if product_type and product_type != 'undefined':
carcass_details = carcass_details.filter(product=product_type)
-
+
agg = carcass_details.aggregate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -5831,7 +5831,7 @@ def get_all_products_transport_dashboard_by_code(request):
transport_details = transport_details.filter(Date__gte=start_date, Date__lte=end_date)
if province and province != 'undefined':
transport_details = transport_details.filter(hatching__ProvinceName=province)
-
+
agg = transport_details.aggregate(
total=Sum('GoodAmount'),
input_total=Sum('GoodAmount', filter=Q(Out=False)),
@@ -5849,7 +5849,7 @@ def get_all_products_transport_dashboard_by_code(request):
output_count += agg['output_cnt'] or 0
if agg['last_mod'] and (not last_update or agg['last_mod'] > last_update):
last_update = agg['last_mod']
-
+
else:
if transport_type == 'out':
all_bars = AllProductsTransport.objects.filter(
@@ -5861,7 +5861,7 @@ def get_all_products_transport_dashboard_by_code(request):
trash=False,
jihadi_destination=code
)
-
+
if start_date and end_date:
all_bars = all_bars.filter(date__gte=start_date, date__lte=end_date)
if province and province != 'undefined':
@@ -5871,12 +5871,12 @@ def get_all_products_transport_dashboard_by_code(request):
all_bars = all_bars.filter(origin_province=province)
if product_type and product_type != 'undefined':
all_bars = all_bars.filter(product=product_type)
-
+
if search and search != 'undefined' and search.strip():
all_bars = all_bars.filter(
build_query(AllProductsTransportFilterSet.Meta.fields, search)
)
-
+
aggregation = all_bars.aggregate(
total=Sum('quantity'),
input_total=Sum('quantity', filter=Q(out=False)),
@@ -5886,7 +5886,7 @@ def get_all_products_transport_dashboard_by_code(request):
total_count=Count('id'),
last_mod=Max('modify_date'),
)
-
+
total_count = aggregation['total_count'] or 0
total_quantity = aggregation['total'] or 0
input_quantity = aggregation['input_total'] or 0
@@ -5894,14 +5894,14 @@ def get_all_products_transport_dashboard_by_code(request):
input_count = aggregation['input_count'] or 0
output_count = aggregation['output_count'] or 0
last_update = aggregation['last_mod']
-
+
if total_count > 0 and (input_quantity + output_quantity) > 0:
input_percent = round((input_quantity / (input_quantity + output_quantity)) * 100, 1)
output_percent = round((output_quantity / (input_quantity + output_quantity)) * 100, 1)
else:
input_percent = 0
output_percent = 0
-
+
return Response({
"bars": int(total_count),
"input_bars": int(input_count),
@@ -5915,3 +5915,56 @@ def get_all_products_transport_dashboard_by_code(request):
"total_output_bars_percent": output_percent,
"total_output_bars_wight": int(output_quantity),
}, status=status.HTTP_200_OK)
+
+
+
+
+
+@api_view(['POST'])
+@permission_classes([AllowAny])
+@csrf_exempt
+def get_ai_response(request):
+ result_data = {}
+ models_info = request.data.get('models_info')
+
+ for model_info in models_info:
+ model_name = model_info.get("model")
+ filters = model_info.get("filters", {})
+ aggregations = model_info.get("aggregations") or []
+ fields_to_return = model_info.get("fields_to_return") or []
+ date_filter = model_info.get("date_filter")
+
+ if model_name == "Hatching":
+ queryset = Hatching.objects.filter(**filters)
+
+ elif model_name == "Poultry":
+ queryset = Poultry.objects.filter(**filters)
+
+ else:
+ continue
+
+ queryset = apply_date_filter(queryset, date_filter)
+
+ model_result = {}
+
+ if "count" in aggregations:
+ model_result["count"] = queryset.count()
+
+ if "sum" in aggregations:
+ model_result["sum"] = (
+ queryset.aggregate(total=Sum("ChickCountSum"))["total"] or 0
+ )
+
+ if fields_to_return:
+ descriptive_data = queryset.values(*fields_to_return).first()
+ if descriptive_data:
+ model_result.update(descriptive_data)
+
+ result_data[model_name] = model_result
+
+ return Response(
+ {
+ "data": result_data
+ },
+ status=status.HTTP_200_OK
+ )
diff --git a/authentication/__pycache__/__init__.cpython-312.pyc b/authentication/__pycache__/__init__.cpython-312.pyc
index 944ecb1..2adbf58 100644
Binary files a/authentication/__pycache__/__init__.cpython-312.pyc and b/authentication/__pycache__/__init__.cpython-312.pyc differ
diff --git a/authentication/__pycache__/admin.cpython-312.pyc b/authentication/__pycache__/admin.cpython-312.pyc
index 4d6d9ee..22ffd4d 100644
Binary files a/authentication/__pycache__/admin.cpython-312.pyc and b/authentication/__pycache__/admin.cpython-312.pyc differ
diff --git a/authentication/__pycache__/apps.cpython-312.pyc b/authentication/__pycache__/apps.cpython-312.pyc
index 2dd6a1c..a54dc8f 100644
Binary files a/authentication/__pycache__/apps.cpython-312.pyc and b/authentication/__pycache__/apps.cpython-312.pyc differ
diff --git a/authentication/__pycache__/models.cpython-312.pyc b/authentication/__pycache__/models.cpython-312.pyc
index be90410..65846a2 100644
Binary files a/authentication/__pycache__/models.cpython-312.pyc and b/authentication/__pycache__/models.cpython-312.pyc differ
diff --git a/authentication/__pycache__/serializers.cpython-312.pyc b/authentication/__pycache__/serializers.cpython-312.pyc
index b84f5aa..630a9b0 100644
Binary files a/authentication/__pycache__/serializers.cpython-312.pyc and b/authentication/__pycache__/serializers.cpython-312.pyc differ
diff --git a/authentication/__pycache__/urls.cpython-312.pyc b/authentication/__pycache__/urls.cpython-312.pyc
index 1c74aa0..d09345c 100644
Binary files a/authentication/__pycache__/urls.cpython-312.pyc and b/authentication/__pycache__/urls.cpython-312.pyc differ
diff --git a/authentication/__pycache__/views.cpython-312.pyc b/authentication/__pycache__/views.cpython-312.pyc
index 515b16e..9669602 100644
Binary files a/authentication/__pycache__/views.cpython-312.pyc and b/authentication/__pycache__/views.cpython-312.pyc differ
diff --git a/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc b/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc
index 98b6bfa..9f578ab 100644
Binary files a/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc and b/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc differ
diff --git a/authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-312.pyc b/authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-312.pyc
index a43e432..db50bf7 100644
Binary files a/authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-312.pyc and b/authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-312.pyc differ
diff --git a/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc b/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc
index c80288b..34ffaee 100644
Binary files a/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc and b/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc differ
diff --git a/authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-312.pyc b/authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-312.pyc
index 824ad9a..9f2637c 100644
Binary files a/authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-312.pyc and b/authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-312.pyc differ
diff --git a/authentication/migrations/__pycache__/__init__.cpython-312.pyc b/authentication/migrations/__pycache__/__init__.cpython-312.pyc
index 7149289..86c899c 100644
Binary files a/authentication/migrations/__pycache__/__init__.cpython-312.pyc and b/authentication/migrations/__pycache__/__init__.cpython-312.pyc differ