From b42c80cf1c840e902b557c54945e8470a626254d Mon Sep 17 00:00:00 2001 From: 7nimor <7nimor@gmail.com> Date: Sun, 18 Jan 2026 11:29:19 +0330 Subject: [PATCH] first commit --- .env.local | 25 + .env.prod | 22 + .idea/.gitignore | 8 + .idea/RSI.iml | 32 + .idea/dataSources.xml | 12 + .idea/inspectionProfiles/Project_Default.xml | 104 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 10 + .idea/modules.xml | 8 + .idea/vcs.xml | 7 + Dockerfile | 19 + RSI/__init__.py | 0 RSI/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 124 bytes RSI/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 131 bytes RSI/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 119 bytes RSI/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 127 bytes RSI/__pycache__/settings.cpython-310.pyc | Bin 0 -> 3106 bytes RSI/__pycache__/settings.cpython-311.pyc | Bin 0 -> 3558 bytes RSI/__pycache__/settings.cpython-312.pyc | Bin 0 -> 3479 bytes RSI/__pycache__/settings.cpython-39.pyc | Bin 0 -> 3118 bytes RSI/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1011 bytes RSI/__pycache__/urls.cpython-311.pyc | Bin 0 -> 1220 bytes RSI/__pycache__/urls.cpython-312.pyc | Bin 0 -> 1142 bytes RSI/__pycache__/urls.cpython-39.pyc | Bin 0 -> 1014 bytes RSI/__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 519 bytes RSI/__pycache__/wsgi.cpython-311.pyc | Bin 0 -> 644 bytes RSI/__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 598 bytes RSI/__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 522 bytes RSI/asgi.py | 16 + RSI/settings.py | 155 + RSI/urls.py | 24 + RSI/wsgi.py | 16 + __pycache__/helpers.cpython-310.pyc | Bin 0 -> 1093 bytes __pycache__/helpers.cpython-311.pyc | Bin 0 -> 1559 bytes __pycache__/helpers.cpython-312.pyc | Bin 0 -> 1372 bytes __pycache__/helpers.cpython-39.pyc | Bin 0 -> 1089 bytes __pycache__/manage.cpython-312.pyc | Bin 0 -> 1008 bytes __pycache__/manage.cpython-39.pyc | Bin 0 -> 801 bytes app/__init__.py | 0 app/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 124 bytes app/__pycache__/__init__.cpython-311.pyc | Bin 0 -> 131 bytes app/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 119 bytes app/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 127 bytes app/__pycache__/admin.cpython-310.pyc | Bin 0 -> 165 bytes app/__pycache__/admin.cpython-311.pyc | Bin 0 -> 186 bytes app/__pycache__/admin.cpython-312.pyc | Bin 0 -> 163 bytes app/__pycache__/admin.cpython-39.pyc | Bin 0 -> 168 bytes app/__pycache__/apps.cpython-310.pyc | Bin 0 -> 386 bytes app/__pycache__/apps.cpython-311.pyc | Bin 0 -> 485 bytes app/__pycache__/apps.cpython-312.pyc | Bin 0 -> 408 bytes app/__pycache__/apps.cpython-39.pyc | Bin 0 -> 387 bytes .../cityandprovince.cpython-311.pyc | Bin 0 -> 37273 bytes .../cityandprovince.cpython-312.pyc | Bin 0 -> 35270 bytes .../cityandprovince.cpython-39.pyc | Bin 0 -> 24725 bytes .../excel_processing.cpython-311.pyc | Bin 0 -> 56994 bytes .../excel_processing.cpython-312.pyc | Bin 0 -> 95407 bytes .../excel_processing.cpython-39.pyc | Bin 0 -> 48576 bytes app/__pycache__/filtersets.cpython-310.pyc | Bin 0 -> 3770 bytes app/__pycache__/filtersets.cpython-311.pyc | Bin 0 -> 12174 bytes app/__pycache__/filtersets.cpython-312.pyc | Bin 0 -> 12371 bytes app/__pycache__/filtersets.cpython-39.pyc | Bin 0 -> 9305 bytes app/__pycache__/helper.cpython-311.pyc | Bin 0 -> 6388 bytes app/__pycache__/helper.cpython-312.pyc | Bin 0 -> 6148 bytes app/__pycache__/helper.cpython-39.pyc | Bin 0 -> 5220 bytes app/__pycache__/helper_excel.cpython-311.pyc | Bin 0 -> 15525 bytes app/__pycache__/helper_excel.cpython-312.pyc | Bin 0 -> 14348 bytes app/__pycache__/helper_excel.cpython-39.pyc | Bin 0 -> 8744 bytes app/__pycache__/models.cpython-310.pyc | Bin 0 -> 10521 bytes app/__pycache__/models.cpython-311.pyc | Bin 0 -> 26686 bytes app/__pycache__/models.cpython-312.pyc | Bin 0 -> 33495 bytes app/__pycache__/models.cpython-39.pyc | Bin 0 -> 20675 bytes app/__pycache__/scripts.cpython-310.pyc | Bin 0 -> 1059 bytes app/__pycache__/scripts.cpython-311.pyc | Bin 0 -> 1808 bytes app/__pycache__/scripts.cpython-312.pyc | Bin 0 -> 1633 bytes app/__pycache__/scripts.cpython-39.pyc | Bin 0 -> 1060 bytes app/__pycache__/serializers.cpython-310.pyc | Bin 0 -> 8854 bytes app/__pycache__/serializers.cpython-311.pyc | Bin 0 -> 18801 bytes app/__pycache__/serializers.cpython-312.pyc | Bin 0 -> 28252 bytes app/__pycache__/serializers.cpython-39.pyc | Bin 0 -> 21610 bytes app/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1627 bytes app/__pycache__/urls.cpython-311.pyc | Bin 0 -> 5495 bytes app/__pycache__/urls.cpython-312.pyc | Bin 0 -> 6827 bytes app/__pycache__/urls.cpython-39.pyc | Bin 0 -> 5570 bytes app/__pycache__/views.cpython-310.pyc | Bin 0 -> 22610 bytes app/__pycache__/views.cpython-311.pyc | Bin 0 -> 108562 bytes app/__pycache__/views.cpython-312.pyc | Bin 0 -> 156589 bytes app/__pycache__/views.cpython-39.pyc | Bin 0 -> 122202 bytes app/admin.py | 3 + app/apps.py | 6 + app/cityandprovince.py | 663 ++ app/excel_processing.py | 2574 +++++++ app/filtersets.py | 332 + app/helper.py | 157 + app/helper_excel.py | 327 + app/migrations/0001_initial.py | 138 + ...002_remove_poultry_allowinsert_and_more.py | 29 + ...llowinsert_poultry_allowupdate_and_more.py | 33 + ...tching_date_poultryhatching_hatchingage.py | 23 + ...ltryhatching_basehatchingcount_and_more.py | 117 + ...ltryhatching_basehatchingcount_and_more.py | 143 + .../0007_transportingchickendetail.py | 34 + ...ansportingchickendetail_certid_and_more.py | 118 + ...endetail_broilerflockrequestid_and_more.py | 38 + ...sportingchickendetail_province_and_more.py | 22 + .../0011_poultryhatching_pedigreename.py | 18 + .../0012_transportingchickendetail_age.py | 18 + .../0013_poultryhatching_leftover.py | 18 + .../0014_poultry_locationnamecity_and_more.py | 23 + .../0015_hatching_transportingdetail.py | 155 + ...move_transportingdetail_certid_and_more.py | 68 + app/migrations/0017_hatching_archivedate.py | 18 + .../0018_remove_hatching_capacityfemale.py | 17 + .../0019_hatching_capacityfemale.py | 18 + app/migrations/0020_killhouse.py | 36 + ...lingave_transportingdetail_out_and_more.py | 36 + .../0022_alter_hatching_killingave.py | 18 + ...3_killhouse_cityid_killhouse_provinceid.py | 23 + .../0024_poultry_city_poultry_province.py | 23 + .../0025_delete_transportingdetail.py | 16 + app/migrations/0026_transportingdetail.py | 60 + ...g_samasat_discharge_percentage_and_more.py | 31 + app/migrations/0028_hatching_goodsum.py | 18 + app/migrations/0029_apkinfo.py | 34 + app/migrations/0030_transportcarcassdetail.py | 52 + app/migrations/0031_auto_20250921_1447.py | 49 + .../0032_delete_transportcarcassdetail.py | 16 + app/migrations/0033_transportcarcassdetail.py | 65 + app/migrations/0034_guilds.py | 36 + app/migrations/0035_guilds_is_steward.py | 18 + app/migrations/0036_driver.py | 43 + app/migrations/0037_driver_product.py | 18 + app/migrations/0038_auto_20250927_0848.py | 23 + ...9_alter_transportcarcassdetail_tracking.py | 18 + ...040_transportcarcassdetail_product_date.py | 18 + ...transportcarcassdetail_has_product_date.py | 18 + ...ed_by_alter_driver_modified_by_and_more.py | 64 + app/migrations/0043_allproductstransport.py | 62 + app/migrations/0044_evacuationdetail.py | 56 + ...ondetail_broilerflockrequestid_and_more.py | 288 + app/migrations/0046_rasadyarappinfo.py | 34 + app/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-310.pyc | Bin 0 -> 4963 bytes .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 11245 bytes .../__pycache__/0001_initial.cpython-312.pyc | Bin 0 -> 11573 bytes .../__pycache__/0001_initial.cpython-39.pyc | Bin 0 -> 4548 bytes ...ultry_allowinsert_and_more.cpython-310.pyc | Bin 0 -> 614 bytes ...ultry_allowinsert_and_more.cpython-311.pyc | Bin 0 -> 912 bytes ...ultry_allowinsert_and_more.cpython-312.pyc | Bin 0 -> 836 bytes ...oultry_allowinsert_and_more.cpython-39.pyc | Bin 0 -> 615 bytes ...ultry_allowupdate_and_more.cpython-310.pyc | Bin 0 -> 752 bytes ...ultry_allowupdate_and_more.cpython-311.pyc | Bin 0 -> 1212 bytes ...ultry_allowupdate_and_more.cpython-312.pyc | Bin 0 -> 1134 bytes ...oultry_allowupdate_and_more.cpython-39.pyc | Bin 0 -> 753 bytes ...oultryhatching_hatchingage.cpython-310.pyc | Bin 0 -> 706 bytes ...oultryhatching_hatchingage.cpython-311.pyc | Bin 0 -> 999 bytes ...oultryhatching_hatchingage.cpython-312.pyc | Bin 0 -> 925 bytes ...poultryhatching_hatchingage.cpython-39.pyc | Bin 0 -> 707 bytes ...basehatchingcount_and_more.cpython-310.pyc | Bin 0 -> 1652 bytes ...basehatchingcount_and_more.cpython-311.pyc | Bin 0 -> 2953 bytes ...basehatchingcount_and_more.cpython-312.pyc | Bin 0 -> 2803 bytes ..._basehatchingcount_and_more.cpython-39.pyc | Bin 0 -> 1653 bytes ...basehatchingcount_and_more.cpython-310.pyc | Bin 0 -> 2007 bytes ...basehatchingcount_and_more.cpython-311.pyc | Bin 0 -> 4328 bytes ...basehatchingcount_and_more.cpython-312.pyc | Bin 0 -> 4198 bytes ..._basehatchingcount_and_more.cpython-39.pyc | Bin 0 -> 2008 bytes ..._transportingchickendetail.cpython-310.pyc | Bin 0 -> 1469 bytes ..._transportingchickendetail.cpython-311.pyc | Bin 0 -> 2409 bytes ..._transportingchickendetail.cpython-312.pyc | Bin 0 -> 2515 bytes ...7_transportingchickendetail.cpython-39.pyc | Bin 0 -> 1470 bytes ...ckendetail_certid_and_more.cpython-310.pyc | Bin 0 -> 1634 bytes ...ckendetail_certid_and_more.cpython-311.pyc | Bin 0 -> 3566 bytes ...ckendetail_certid_and_more.cpython-312.pyc | Bin 0 -> 3446 bytes ...ickendetail_certid_and_more.cpython-39.pyc | Bin 0 -> 1635 bytes ...lerflockrequestid_and_more.cpython-310.pyc | Bin 0 -> 893 bytes ...lerflockrequestid_and_more.cpython-311.pyc | Bin 0 -> 1444 bytes ...lerflockrequestid_and_more.cpython-312.pyc | Bin 0 -> 1364 bytes ...ilerflockrequestid_and_more.cpython-39.pyc | Bin 0 -> 894 bytes ...endetail_province_and_more.cpython-310.pyc | Bin 0 -> 709 bytes ...endetail_province_and_more.cpython-311.pyc | Bin 0 -> 1003 bytes ...endetail_province_and_more.cpython-312.pyc | Bin 0 -> 929 bytes ...kendetail_province_and_more.cpython-39.pyc | Bin 0 -> 710 bytes ...ultryhatching_pedigreename.cpython-310.pyc | Bin 0 -> 629 bytes ...ultryhatching_pedigreename.cpython-311.pyc | Bin 0 -> 840 bytes ...ultryhatching_pedigreename.cpython-312.pyc | Bin 0 -> 768 bytes ...oultryhatching_pedigreename.cpython-39.pyc | Bin 0 -> 630 bytes ...nsportingchickendetail_age.cpython-310.pyc | Bin 0 -> 607 bytes ...nsportingchickendetail_age.cpython-311.pyc | Bin 0 -> 815 bytes ...nsportingchickendetail_age.cpython-312.pyc | Bin 0 -> 743 bytes ...ansportingchickendetail_age.cpython-39.pyc | Bin 0 -> 608 bytes ...3_poultryhatching_leftover.cpython-310.pyc | Bin 0 -> 591 bytes ...3_poultryhatching_leftover.cpython-311.pyc | Bin 0 -> 799 bytes ...3_poultryhatching_leftover.cpython-312.pyc | Bin 0 -> 727 bytes ...13_poultryhatching_leftover.cpython-39.pyc | Bin 0 -> 592 bytes ..._locationnamecity_and_more.cpython-310.pyc | Bin 0 -> 667 bytes ..._locationnamecity_and_more.cpython-311.pyc | Bin 0 -> 963 bytes ..._locationnamecity_and_more.cpython-312.pyc | Bin 0 -> 889 bytes ...y_locationnamecity_and_more.cpython-39.pyc | Bin 0 -> 668 bytes ...atching_transportingdetail.cpython-310.pyc | Bin 0 -> 5752 bytes ...atching_transportingdetail.cpython-311.pyc | Bin 0 -> 13301 bytes ...atching_transportingdetail.cpython-312.pyc | Bin 0 -> 13690 bytes ...hatching_transportingdetail.cpython-39.pyc | Bin 0 -> 5265 bytes ...tingdetail_certid_and_more.cpython-310.pyc | Bin 0 -> 1095 bytes ...tingdetail_certid_and_more.cpython-311.pyc | Bin 0 -> 2035 bytes ...tingdetail_certid_and_more.cpython-312.pyc | Bin 0 -> 1936 bytes ...rtingdetail_certid_and_more.cpython-39.pyc | Bin 0 -> 1096 bytes .../0017_hatching_archivedate.cpython-310.pyc | Bin 0 -> 596 bytes .../0017_hatching_archivedate.cpython-311.pyc | Bin 0 -> 805 bytes .../0017_hatching_archivedate.cpython-312.pyc | Bin 0 -> 733 bytes .../0017_hatching_archivedate.cpython-39.pyc | Bin 0 -> 597 bytes ...ve_hatching_capacityfemale.cpython-310.pyc | Bin 0 -> 526 bytes ...ve_hatching_capacityfemale.cpython-311.pyc | Bin 0 -> 689 bytes ...ve_hatching_capacityfemale.cpython-312.pyc | Bin 0 -> 622 bytes ...ove_hatching_capacityfemale.cpython-39.pyc | Bin 0 -> 527 bytes ...19_hatching_capacityfemale.cpython-310.pyc | Bin 0 -> 599 bytes ...19_hatching_capacityfemale.cpython-311.pyc | Bin 0 -> 809 bytes ...19_hatching_capacityfemale.cpython-312.pyc | Bin 0 -> 737 bytes ...019_hatching_capacityfemale.cpython-39.pyc | Bin 0 -> 600 bytes .../0020_killhouse.cpython-310.pyc | Bin 0 -> 1403 bytes .../0020_killhouse.cpython-311.pyc | Bin 0 -> 2377 bytes .../0020_killhouse.cpython-312.pyc | Bin 0 -> 2440 bytes .../__pycache__/0020_killhouse.cpython-39.pyc | Bin 0 -> 1404 bytes ...portingdetail_out_and_more.cpython-310.pyc | Bin 0 -> 1095 bytes ...portingdetail_out_and_more.cpython-311.pyc | Bin 0 -> 1798 bytes ...portingdetail_out_and_more.cpython-312.pyc | Bin 0 -> 1837 bytes ...sportingdetail_out_and_more.cpython-39.pyc | Bin 0 -> 1096 bytes ..._alter_hatching_killingave.cpython-310.pyc | Bin 0 -> 618 bytes ..._alter_hatching_killingave.cpython-311.pyc | Bin 0 -> 827 bytes ..._alter_hatching_killingave.cpython-312.pyc | Bin 0 -> 755 bytes ...2_alter_hatching_killingave.cpython-39.pyc | Bin 0 -> 619 bytes ...ityid_killhouse_provinceid.cpython-310.pyc | Bin 0 -> 665 bytes ...ityid_killhouse_provinceid.cpython-311.pyc | Bin 0 -> 965 bytes ...ityid_killhouse_provinceid.cpython-312.pyc | Bin 0 -> 891 bytes ...cityid_killhouse_provinceid.cpython-39.pyc | Bin 0 -> 666 bytes ...ltry_city_poultry_province.cpython-310.pyc | Bin 0 -> 663 bytes ...ltry_city_poultry_province.cpython-311.pyc | Bin 0 -> 963 bytes ...ltry_city_poultry_province.cpython-312.pyc | Bin 0 -> 889 bytes ...ultry_city_poultry_province.cpython-39.pyc | Bin 0 -> 664 bytes ..._delete_transportingdetail.cpython-311.pyc | Bin 0 -> 670 bytes ..._delete_transportingdetail.cpython-312.pyc | Bin 0 -> 603 bytes ...5_delete_transportingdetail.cpython-39.pyc | Bin 0 -> 509 bytes .../0026_transportingdetail.cpython-311.pyc | Bin 0 -> 4765 bytes .../0026_transportingdetail.cpython-312.pyc | Bin 0 -> 4897 bytes .../0026_transportingdetail.cpython-39.pyc | Bin 0 -> 2296 bytes ...charge_percentage_and_more.cpython-311.pyc | Bin 0 -> 1671 bytes ...charge_percentage_and_more.cpython-312.pyc | Bin 0 -> 1712 bytes ...scharge_percentage_and_more.cpython-39.pyc | Bin 0 -> 1053 bytes .../0028_hatching_goodsum.cpython-311.pyc | Bin 0 -> 808 bytes .../0028_hatching_goodsum.cpython-312.pyc | Bin 0 -> 736 bytes .../0028_hatching_goodsum.cpython-39.pyc | Bin 0 -> 600 bytes .../__pycache__/0029_apkinfo.cpython-311.pyc | Bin 0 -> 2221 bytes .../__pycache__/0029_apkinfo.cpython-312.pyc | Bin 0 -> 2282 bytes .../__pycache__/0029_apkinfo.cpython-39.pyc | Bin 0 -> 1350 bytes ...030_transportcarcassdetail.cpython-312.pyc | Bin 0 -> 3970 bytes ...0030_transportcarcassdetail.cpython-39.pyc | Bin 0 -> 1857 bytes .../0031_auto_20250921_1447.cpython-312.pyc | Bin 0 -> 2363 bytes .../0031_auto_20250921_1447.cpython-39.pyc | Bin 0 -> 1357 bytes ...ete_transportcarcassdetail.cpython-312.pyc | Bin 0 -> 600 bytes ...lete_transportcarcassdetail.cpython-39.pyc | Bin 0 -> 506 bytes ...033_transportcarcassdetail.cpython-312.pyc | Bin 0 -> 5376 bytes ...0033_transportcarcassdetail.cpython-39.pyc | Bin 0 -> 2511 bytes .../__pycache__/0034_guilds.cpython-312.pyc | Bin 0 -> 2423 bytes .../__pycache__/0034_guilds.cpython-39.pyc | Bin 0 -> 1387 bytes .../0035_guilds_is_steward.cpython-312.pyc | Bin 0 -> 693 bytes .../0035_guilds_is_steward.cpython-39.pyc | Bin 0 -> 558 bytes .../__pycache__/0036_driver.cpython-312.pyc | Bin 0 -> 3031 bytes .../__pycache__/0036_driver.cpython-39.pyc | Bin 0 -> 1646 bytes .../0037_driver_product.cpython-312.pyc | Bin 0 -> 713 bytes .../0037_driver_product.cpython-39.pyc | Bin 0 -> 574 bytes .../0038_auto_20250927_0848.cpython-312.pyc | Bin 0 -> 869 bytes .../0038_auto_20250927_0848.cpython-39.pyc | Bin 0 -> 644 bytes ...portcarcassdetail_tracking.cpython-312.pyc | Bin 0 -> 780 bytes ...sportcarcassdetail_tracking.cpython-39.pyc | Bin 0 -> 638 bytes ...carcassdetail_product_date.cpython-312.pyc | Bin 0 -> 765 bytes ...tcarcassdetail_product_date.cpython-39.pyc | Bin 0 -> 628 bytes ...assdetail_has_product_date.cpython-312.pyc | Bin 0 -> 766 bytes ...cassdetail_has_product_date.cpython-39.pyc | Bin 0 -> 631 bytes ...river_modified_by_and_more.cpython-312.pyc | Bin 0 -> 4076 bytes ...driver_modified_by_and_more.cpython-39.pyc | Bin 0 -> 1771 bytes .../0043_allproductstransport.cpython-39.pyc | Bin 0 -> 2434 bytes .../0044_evacuationdetail.cpython-39.pyc | Bin 0 -> 2215 bytes ...ilerflockrequestid_and_more.cpython-39.pyc | Bin 0 -> 3565 bytes .../0046_rasadyarappinfo.cpython-39.pyc | Bin 0 -> 1402 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 135 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 142 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 130 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 138 bytes app/models.py | 720 ++ app/scripts.py | 24 + app/serializers.py | 653 ++ app/tests.py | 3 + app/urls.py | 239 + app/views.py | 5891 +++++++++++++++++ authentication/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 135 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 142 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 130 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 138 bytes .../__pycache__/admin.cpython-310.pyc | Bin 0 -> 176 bytes .../__pycache__/admin.cpython-311.pyc | Bin 0 -> 197 bytes .../__pycache__/admin.cpython-312.pyc | Bin 0 -> 174 bytes .../__pycache__/admin.cpython-39.pyc | Bin 0 -> 179 bytes .../__pycache__/apps.cpython-310.pyc | Bin 0 -> 430 bytes .../__pycache__/apps.cpython-311.pyc | Bin 0 -> 529 bytes .../__pycache__/apps.cpython-312.pyc | Bin 0 -> 452 bytes .../__pycache__/apps.cpython-39.pyc | Bin 0 -> 431 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 2551 bytes .../__pycache__/models.cpython-311.pyc | Bin 0 -> 4557 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 4266 bytes .../__pycache__/models.cpython-39.pyc | Bin 0 -> 2717 bytes .../__pycache__/serializers.cpython-310.pyc | Bin 0 -> 1207 bytes .../__pycache__/serializers.cpython-311.pyc | Bin 0 -> 1763 bytes .../__pycache__/serializers.cpython-312.pyc | Bin 0 -> 1481 bytes .../__pycache__/serializers.cpython-39.pyc | Bin 0 -> 1288 bytes .../__pycache__/urls.cpython-310.pyc | Bin 0 -> 545 bytes .../__pycache__/urls.cpython-311.pyc | Bin 0 -> 904 bytes .../__pycache__/urls.cpython-312.pyc | Bin 0 -> 812 bytes .../__pycache__/urls.cpython-39.pyc | Bin 0 -> 548 bytes .../__pycache__/views.cpython-310.pyc | Bin 0 -> 1079 bytes .../__pycache__/views.cpython-311.pyc | Bin 0 -> 1699 bytes .../__pycache__/views.cpython-312.pyc | Bin 0 -> 1497 bytes .../__pycache__/views.cpython-39.pyc | Bin 0 -> 1156 bytes authentication/admin.py | 3 + authentication/apps.py | 6 + authentication/migrations/0001_initial.py | 73 + ..._lat_city_lng_province_lat_province_lng.py | 33 + .../migrations/0003_auto_20250809_1248.py | 61 + .../migrations/0004_province_tel_prefix.py | 18 + authentication/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-310.pyc | Bin 0 -> 2094 bytes .../__pycache__/0001_initial.cpython-311.pyc | Bin 0 -> 4654 bytes .../__pycache__/0001_initial.cpython-312.pyc | Bin 0 -> 5106 bytes .../__pycache__/0001_initial.cpython-39.pyc | Bin 0 -> 2095 bytes ..._province_lat_province_lng.cpython-311.pyc | Bin 0 -> 1170 bytes ..._province_lat_province_lng.cpython-312.pyc | Bin 0 -> 1092 bytes ...g_province_lat_province_lng.cpython-39.pyc | Bin 0 -> 711 bytes .../0003_auto_20250809_1248.cpython-312.pyc | Bin 0 -> 1392 bytes .../0003_auto_20250809_1248.cpython-39.pyc | Bin 0 -> 833 bytes .../0004_province_tel_prefix.cpython-312.pyc | Bin 0 -> 746 bytes .../0004_province_tel_prefix.cpython-39.pyc | Bin 0 -> 609 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 146 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 153 bytes .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 141 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 149 bytes authentication/models.py | 67 + authentication/serializers.py | 21 + authentication/tests.py | 3 + authentication/urls.py | 25 + authentication/views.py | 23 + cron_for_city.py | 11 + cron_for_code.py | 8 + docker-compose.yml | 7 + helpers.py | 26 + manage.py | 22 + requirements.txt | 21 + 354 files changed, 14705 insertions(+) create mode 100644 .env.local create mode 100644 .env.prod create mode 100644 .idea/.gitignore create mode 100644 .idea/RSI.iml create mode 100644 .idea/dataSources.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 Dockerfile create mode 100644 RSI/__init__.py create mode 100644 RSI/__pycache__/__init__.cpython-310.pyc create mode 100644 RSI/__pycache__/__init__.cpython-311.pyc create mode 100644 RSI/__pycache__/__init__.cpython-312.pyc create mode 100644 RSI/__pycache__/__init__.cpython-39.pyc create mode 100644 RSI/__pycache__/settings.cpython-310.pyc create mode 100644 RSI/__pycache__/settings.cpython-311.pyc create mode 100644 RSI/__pycache__/settings.cpython-312.pyc create mode 100644 RSI/__pycache__/settings.cpython-39.pyc create mode 100644 RSI/__pycache__/urls.cpython-310.pyc create mode 100644 RSI/__pycache__/urls.cpython-311.pyc create mode 100644 RSI/__pycache__/urls.cpython-312.pyc create mode 100644 RSI/__pycache__/urls.cpython-39.pyc create mode 100644 RSI/__pycache__/wsgi.cpython-310.pyc create mode 100644 RSI/__pycache__/wsgi.cpython-311.pyc create mode 100644 RSI/__pycache__/wsgi.cpython-312.pyc create mode 100644 RSI/__pycache__/wsgi.cpython-39.pyc create mode 100644 RSI/asgi.py create mode 100644 RSI/settings.py create mode 100644 RSI/urls.py create mode 100644 RSI/wsgi.py create mode 100644 __pycache__/helpers.cpython-310.pyc create mode 100644 __pycache__/helpers.cpython-311.pyc create mode 100644 __pycache__/helpers.cpython-312.pyc create mode 100644 __pycache__/helpers.cpython-39.pyc create mode 100644 __pycache__/manage.cpython-312.pyc create mode 100644 __pycache__/manage.cpython-39.pyc create mode 100644 app/__init__.py create mode 100644 app/__pycache__/__init__.cpython-310.pyc create mode 100644 app/__pycache__/__init__.cpython-311.pyc create mode 100644 app/__pycache__/__init__.cpython-312.pyc create mode 100644 app/__pycache__/__init__.cpython-39.pyc create mode 100644 app/__pycache__/admin.cpython-310.pyc create mode 100644 app/__pycache__/admin.cpython-311.pyc create mode 100644 app/__pycache__/admin.cpython-312.pyc create mode 100644 app/__pycache__/admin.cpython-39.pyc create mode 100644 app/__pycache__/apps.cpython-310.pyc create mode 100644 app/__pycache__/apps.cpython-311.pyc create mode 100644 app/__pycache__/apps.cpython-312.pyc create mode 100644 app/__pycache__/apps.cpython-39.pyc create mode 100644 app/__pycache__/cityandprovince.cpython-311.pyc create mode 100644 app/__pycache__/cityandprovince.cpython-312.pyc create mode 100644 app/__pycache__/cityandprovince.cpython-39.pyc create mode 100644 app/__pycache__/excel_processing.cpython-311.pyc create mode 100644 app/__pycache__/excel_processing.cpython-312.pyc create mode 100644 app/__pycache__/excel_processing.cpython-39.pyc create mode 100644 app/__pycache__/filtersets.cpython-310.pyc create mode 100644 app/__pycache__/filtersets.cpython-311.pyc create mode 100644 app/__pycache__/filtersets.cpython-312.pyc create mode 100644 app/__pycache__/filtersets.cpython-39.pyc create mode 100644 app/__pycache__/helper.cpython-311.pyc create mode 100644 app/__pycache__/helper.cpython-312.pyc create mode 100644 app/__pycache__/helper.cpython-39.pyc create mode 100644 app/__pycache__/helper_excel.cpython-311.pyc create mode 100644 app/__pycache__/helper_excel.cpython-312.pyc create mode 100644 app/__pycache__/helper_excel.cpython-39.pyc create mode 100644 app/__pycache__/models.cpython-310.pyc create mode 100644 app/__pycache__/models.cpython-311.pyc create mode 100644 app/__pycache__/models.cpython-312.pyc create mode 100644 app/__pycache__/models.cpython-39.pyc create mode 100644 app/__pycache__/scripts.cpython-310.pyc create mode 100644 app/__pycache__/scripts.cpython-311.pyc create mode 100644 app/__pycache__/scripts.cpython-312.pyc create mode 100644 app/__pycache__/scripts.cpython-39.pyc create mode 100644 app/__pycache__/serializers.cpython-310.pyc create mode 100644 app/__pycache__/serializers.cpython-311.pyc create mode 100644 app/__pycache__/serializers.cpython-312.pyc create mode 100644 app/__pycache__/serializers.cpython-39.pyc create mode 100644 app/__pycache__/urls.cpython-310.pyc create mode 100644 app/__pycache__/urls.cpython-311.pyc create mode 100644 app/__pycache__/urls.cpython-312.pyc create mode 100644 app/__pycache__/urls.cpython-39.pyc create mode 100644 app/__pycache__/views.cpython-310.pyc create mode 100644 app/__pycache__/views.cpython-311.pyc create mode 100644 app/__pycache__/views.cpython-312.pyc create mode 100644 app/__pycache__/views.cpython-39.pyc create mode 100644 app/admin.py create mode 100644 app/apps.py create mode 100644 app/cityandprovince.py create mode 100644 app/excel_processing.py create mode 100644 app/filtersets.py create mode 100644 app/helper.py create mode 100644 app/helper_excel.py create mode 100644 app/migrations/0001_initial.py create mode 100644 app/migrations/0002_remove_poultry_allowinsert_and_more.py create mode 100644 app/migrations/0003_poultry_allowinsert_poultry_allowupdate_and_more.py create mode 100644 app/migrations/0004_poultryhatching_date_poultryhatching_hatchingage.py create mode 100644 app/migrations/0005_remove_poultryhatching_basehatchingcount_and_more.py create mode 100644 app/migrations/0006_poultryhatching_basehatchingcount_and_more.py create mode 100644 app/migrations/0007_transportingchickendetail.py create mode 100644 app/migrations/0008_transportingchickendetail_certid_and_more.py create mode 100644 app/migrations/0009_transportingchickendetail_broilerflockrequestid_and_more.py create mode 100644 app/migrations/0010_transportingchickendetail_province_and_more.py create mode 100644 app/migrations/0011_poultryhatching_pedigreename.py create mode 100644 app/migrations/0012_transportingchickendetail_age.py create mode 100644 app/migrations/0013_poultryhatching_leftover.py create mode 100644 app/migrations/0014_poultry_locationnamecity_and_more.py create mode 100644 app/migrations/0015_hatching_transportingdetail.py create mode 100644 app/migrations/0016_remove_transportingdetail_certid_and_more.py create mode 100644 app/migrations/0017_hatching_archivedate.py create mode 100644 app/migrations/0018_remove_hatching_capacityfemale.py create mode 100644 app/migrations/0019_hatching_capacityfemale.py create mode 100644 app/migrations/0020_killhouse.py create mode 100644 app/migrations/0021_hatching_killingave_transportingdetail_out_and_more.py create mode 100644 app/migrations/0022_alter_hatching_killingave.py create mode 100644 app/migrations/0023_killhouse_cityid_killhouse_provinceid.py create mode 100644 app/migrations/0024_poultry_city_poultry_province.py create mode 100644 app/migrations/0025_delete_transportingdetail.py create mode 100644 app/migrations/0026_transportingdetail.py create mode 100644 app/migrations/0027_hatching_samasat_discharge_percentage_and_more.py create mode 100644 app/migrations/0028_hatching_goodsum.py create mode 100644 app/migrations/0029_apkinfo.py create mode 100644 app/migrations/0030_transportcarcassdetail.py create mode 100644 app/migrations/0031_auto_20250921_1447.py create mode 100644 app/migrations/0032_delete_transportcarcassdetail.py create mode 100644 app/migrations/0033_transportcarcassdetail.py create mode 100644 app/migrations/0034_guilds.py create mode 100644 app/migrations/0035_guilds_is_steward.py create mode 100644 app/migrations/0036_driver.py create mode 100644 app/migrations/0037_driver_product.py create mode 100644 app/migrations/0038_auto_20250927_0848.py create mode 100644 app/migrations/0039_alter_transportcarcassdetail_tracking.py create mode 100644 app/migrations/0040_transportcarcassdetail_product_date.py create mode 100644 app/migrations/0041_transportcarcassdetail_has_product_date.py create mode 100644 app/migrations/0042_alter_driver_created_by_alter_driver_modified_by_and_more.py create mode 100644 app/migrations/0043_allproductstransport.py create mode 100644 app/migrations/0044_evacuationdetail.py create mode 100644 app/migrations/0045_remove_evacuationdetail_broilerflockrequestid_and_more.py create mode 100644 app/migrations/0046_rasadyarappinfo.py create mode 100644 app/migrations/__init__.py create mode 100644 app/migrations/__pycache__/0001_initial.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0001_initial.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0001_initial.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0003_poultry_allowinsert_poultry_allowupdate_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0007_transportingchickendetail.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0007_transportingchickendetail.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0007_transportingchickendetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0007_transportingchickendetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0017_hatching_archivedate.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0017_hatching_archivedate.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0017_hatching_archivedate.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0017_hatching_archivedate.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0020_killhouse.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0020_killhouse.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0020_killhouse.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0020_killhouse.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-310.pyc create mode 100644 app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0025_delete_transportingdetail.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0025_delete_transportingdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0025_delete_transportingdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0026_transportingdetail.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0026_transportingdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0028_hatching_goodsum.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0028_hatching_goodsum.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0029_apkinfo.cpython-311.pyc create mode 100644 app/migrations/__pycache__/0029_apkinfo.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0029_apkinfo.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0030_transportcarcassdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0031_auto_20250921_1447.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0033_transportcarcassdetail.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0033_transportcarcassdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0034_guilds.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0034_guilds.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0035_guilds_is_steward.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0036_driver.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0036_driver.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0037_driver_product.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0037_driver_product.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0038_auto_20250927_0848.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0038_auto_20250927_0848.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0041_transportcarcassdetail_has_product_date.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-312.pyc create mode 100644 app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0043_allproductstransport.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0044_evacuationdetail.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-39.pyc create mode 100644 app/migrations/__pycache__/0046_rasadyarappinfo.cpython-39.pyc create mode 100644 app/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 app/migrations/__pycache__/__init__.cpython-311.pyc create mode 100644 app/migrations/__pycache__/__init__.cpython-312.pyc create mode 100644 app/migrations/__pycache__/__init__.cpython-39.pyc create mode 100644 app/models.py create mode 100644 app/scripts.py create mode 100644 app/serializers.py create mode 100644 app/tests.py create mode 100644 app/urls.py create mode 100644 app/views.py create mode 100644 authentication/__init__.py create mode 100644 authentication/__pycache__/__init__.cpython-310.pyc create mode 100644 authentication/__pycache__/__init__.cpython-311.pyc create mode 100644 authentication/__pycache__/__init__.cpython-312.pyc create mode 100644 authentication/__pycache__/__init__.cpython-39.pyc create mode 100644 authentication/__pycache__/admin.cpython-310.pyc create mode 100644 authentication/__pycache__/admin.cpython-311.pyc create mode 100644 authentication/__pycache__/admin.cpython-312.pyc create mode 100644 authentication/__pycache__/admin.cpython-39.pyc create mode 100644 authentication/__pycache__/apps.cpython-310.pyc create mode 100644 authentication/__pycache__/apps.cpython-311.pyc create mode 100644 authentication/__pycache__/apps.cpython-312.pyc create mode 100644 authentication/__pycache__/apps.cpython-39.pyc create mode 100644 authentication/__pycache__/models.cpython-310.pyc create mode 100644 authentication/__pycache__/models.cpython-311.pyc create mode 100644 authentication/__pycache__/models.cpython-312.pyc create mode 100644 authentication/__pycache__/models.cpython-39.pyc create mode 100644 authentication/__pycache__/serializers.cpython-310.pyc create mode 100644 authentication/__pycache__/serializers.cpython-311.pyc create mode 100644 authentication/__pycache__/serializers.cpython-312.pyc create mode 100644 authentication/__pycache__/serializers.cpython-39.pyc create mode 100644 authentication/__pycache__/urls.cpython-310.pyc create mode 100644 authentication/__pycache__/urls.cpython-311.pyc create mode 100644 authentication/__pycache__/urls.cpython-312.pyc create mode 100644 authentication/__pycache__/urls.cpython-39.pyc create mode 100644 authentication/__pycache__/views.cpython-310.pyc create mode 100644 authentication/__pycache__/views.cpython-311.pyc create mode 100644 authentication/__pycache__/views.cpython-312.pyc create mode 100644 authentication/__pycache__/views.cpython-39.pyc create mode 100644 authentication/admin.py create mode 100644 authentication/apps.py create mode 100644 authentication/migrations/0001_initial.py create mode 100644 authentication/migrations/0002_city_lat_city_lng_province_lat_province_lng.py create mode 100644 authentication/migrations/0003_auto_20250809_1248.py create mode 100644 authentication/migrations/0004_province_tel_prefix.py create mode 100644 authentication/migrations/__init__.py create mode 100644 authentication/migrations/__pycache__/0001_initial.cpython-310.pyc create mode 100644 authentication/migrations/__pycache__/0001_initial.cpython-311.pyc create mode 100644 authentication/migrations/__pycache__/0001_initial.cpython-312.pyc create mode 100644 authentication/migrations/__pycache__/0001_initial.cpython-39.pyc create mode 100644 authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-311.pyc create mode 100644 authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-312.pyc create mode 100644 authentication/migrations/__pycache__/0002_city_lat_city_lng_province_lat_province_lng.cpython-39.pyc create mode 100644 authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc create mode 100644 authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-39.pyc create mode 100644 authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-312.pyc create mode 100644 authentication/migrations/__pycache__/0004_province_tel_prefix.cpython-39.pyc create mode 100644 authentication/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 authentication/migrations/__pycache__/__init__.cpython-311.pyc create mode 100644 authentication/migrations/__pycache__/__init__.cpython-312.pyc create mode 100644 authentication/migrations/__pycache__/__init__.cpython-39.pyc create mode 100644 authentication/models.py create mode 100644 authentication/serializers.py create mode 100644 authentication/tests.py create mode 100644 authentication/urls.py create mode 100644 authentication/views.py create mode 100644 cron_for_city.py create mode 100644 cron_for_code.py create mode 100644 docker-compose.yml create mode 100644 helpers.py create mode 100644 manage.py create mode 100644 requirements.txt diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..d4245d4 --- /dev/null +++ b/.env.local @@ -0,0 +1,25 @@ +SECRET_KEY=django-insecure-rd)c)2#!cf&a^+(-*nwh_lm5yoo!5bxnfw=k&ll_jilx+uf4#a +DEBUG=True +ALLOWED_HOSTS=rsibackend.rasadyaar.ir,127.0.0.1,rasadyaar.ir,rasadyar.net,rsibackend.rasadyar.com,rasadyar.com +DB_NAME=rsi +DB_USER=postgres +DB_PASSWORD=hbZnuB4pipCPooBp4BApeR2njtbwa3PDJlKbEdbR5D86Vo6jvoxl3MDpPm2ZfQAu +DB_HOST=31.7.78.133 +DB_PORT=14339 +CELERY_BROKER_URL=redis://redis://localhost:6379 +CELERY_RESULT_BACKEND=redis://redis://localhost:6379 +CELERY_ACCEPT_CONTENT=application/json +CELERY_TASK_SERIALIZER=json +CELERY_RESULT_SERIALIZER=json +CELERY_TIMEZONE=Asia/Tehran +CORS_ORIGIN_ALLOW_ALL=True +CORS_ORIGIN_WHITELIST=http://localhost:8080,http://127.0.0.1:8080,http://127.0.0.1:3000,http://localhost:3000,https://rsibackend.rasadyaar.ir,https://rasadyaar.ir,https://rasadyar.net,https://rsibackend.rasadyar.com,https://rasadyar.com +CORS_ALLOWED_ORIGINS=http://localhost:8080,http://127.0.0.1:8080,http://127.0.0.1:3000,http://localhost:3000,https://rsibackend.rasadyaar.ir,https://rasadyaar.ir,https://rasadyar.net,https://rsibackend.rasadyar.com,https://rasadyar.com +SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https +SECURE_SSL_REDIRECT=False +SESSION_COOKIE_SECURE=True +CSRF_COOKIE_SECURE=True +REDIS_URL=redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 + + +ENV RUNNING_IN_DOCKER=0 \ No newline at end of file diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..c71bee7 --- /dev/null +++ b/.env.prod @@ -0,0 +1,22 @@ +SECRET_KEY=django-insecure-rd)c)2#!cf&a^+(-*nwh_lm5yoo!5bxnfw=k&ll_jilx+uf4#a +DEBUG=True +ALLOWED_HOSTS=rsibackend.rasadyaar.ir,127.0.0.1,rasadyaar.ir,rasadyar.net,rsibackend.rasadyar.com,rasadyar.com +DB_NAME=rsi +DB_USER=postgres +DB_PASSWORD=hbZnuB4pipCPooBp4BApeR2njtbwa3PDJlKbEdbR5D86Vo6jvoxl3MDpPm2ZfQAu +DB_HOST=31.7.78.133 +DB_PORT=14339 +CELERY_BROKER_URL=redis://redis://localhost:6379 +CELERY_RESULT_BACKEND=redis://redis://localhost:6379 +CELERY_ACCEPT_CONTENT=application/json +CELERY_TASK_SERIALIZER=json +CELERY_RESULT_SERIALIZER=json +CELERY_TIMEZONE=Asia/Tehran +CORS_ORIGIN_ALLOW_ALL=True +CORS_ORIGIN_WHITELIST=http://localhost:8080,http://127.0.0.1:8080,http://127.0.0.1:3000,http://localhost:3000,https://rsibackend.rasadyaar.ir,https://rasadyaar.ir,https://rasadyar.net,https://rsibackend.rasadyar.com,https://rasadyar.com +CORS_ALLOWED_ORIGINS=http://localhost:8080,http://127.0.0.1:8080,http://127.0.0.1:3000,http://localhost:3000,https://rsibackend.rasadyaar.ir,https://rasadyaar.ir,https://rasadyar.net,https://rsibackend.rasadyar.com,https://rasadyar.com +SECURE_PROXY_SSL_HEADER=HTTP_X_FORWARDED_PROTO,https +SECURE_SSL_REDIRECT=False +SESSION_COOKIE_SECURE=True +CSRF_COOKIE_SECURE=True +REDIS_URL=redis://:ydnW4hwzuDRYcTX3FWCHgQ1f@apo.liara.cloud:33740/0 \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/RSI.iml b/.idea/RSI.iml new file mode 100644 index 0000000..cfcee21 --- /dev/null +++ b/.idea/RSI.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml new file mode 100644 index 0000000..bbadf7d --- /dev/null +++ b/.idea/dataSources.xml @@ -0,0 +1,12 @@ + + + + + postgresql + true + org.postgresql.Driver + jdbc:postgresql://31.7.78.133:14339/rsi + $ProjectFileDir$ + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..3da04d2 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,104 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..35f7c8b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..48c3c01 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..62bd7a0 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a90bb1e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +# Dockerfile +FROM ghcr.io/seniorkian/python39-rsi:1.0.0 +ENV TZ="Asia/Tehran" + +# Set working directory +WORKDIR /app + +# فقط کپی requirements و نصب پکیج‌های پایتون +COPY ./requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Copy project files +COPY . . + +# Expose Django port +EXPOSE 8000 + +# Run Django development server +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] diff --git a/RSI/__init__.py b/RSI/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/RSI/__pycache__/__init__.cpython-310.pyc b/RSI/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8027ad7ddf9dac0155c2fc971237e847d13e0a8 GIT binary patch literal 124 zcmd1j<>g`kg5bJ?=^*+sh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DW#VV#Ku{bfM pGO;KoDA*H>>P{wCAAY(d13PUi1CZpdRLl<~J}@&fGJary5k<^EF#tXI8My!e literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/__init__.cpython-312.pyc b/RSI/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de388e45c835c3aee9b25650688c901ca2afc969 GIT binary patch literal 119 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 literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/settings.cpython-39.pyc b/RSI/__pycache__/settings.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5992137c0f17f030369e923284d026e05816a5ad GIT binary patch literal 3118 zcmb7G-EZ4Q5*I1z!;-Byj`PvDN!2!AN)rlci@P>Bw53JLAtH$aNyY6p06}ZlG97-E zOT{&x3KZyHkq4`9_xIe}zTVTl-BTZe0=Xe2*@_(CQc=5{ot>GTot@t-?X|T^4t_uX z>s#l?^<3`X>0t4<0)y|M(cidS4(Ct~bC`EI#KAl7@?IY0xhYRT0`LU4;1yAk%aJ@O z{mPw`C%MCw!xdB^+({MM>LfSe&>9gAYbO_Q0qAuioLt1k2}eUx!KJMn+8{-;@hb;5 zrcz~)x-_F#Cfvy;t^nuqD2J=RbLa}ZSK)mXuc2$W2BQmj9r}yEa}I|$UI`-(eSj~a z>v$7io>{pv;bzp;Q|j6&^}#81eZt|bS4D?ITlhotA-;ib;G6g(uzM5Nv;O0(|HR=& z0=kJm#kWQrzWs_vAK^Qwj_;z6@dfk=v`?Yknyq;cHzxea?MV*bf5D?WGwx@nJG*<1 za}Pg2jm!hy$Tc3?4LFR7d}#ZlpiW5~JN}5)_k*ae8)`j_fZL!ak|Ldg<;?|iQfc^%{U01A#KjRZBEU{2c*6~cHO$`(6}D# zpY6u>F)T!!sQ%J+$AtcswIZ^=u+V?feC{m? zAJ9d8(Cewa9ZT(5vetU4=t)HcA<+$nw#y2#vOU;gYf`79?JBbML^Dj|HTR%VO*W_d z7Kec!N6wy@1v$C2%pJ!E$<`7xRUv*HABTh{SC=L!p%kKie!_zZdjuNSmo;KIr(t?J z6jg^oL=T9KNkmaCA~d%4BikcKLG*&R-)7{fy@^I$Hf&?YQapc6uqA?>D#J^njdbZES6^towL920o5y&tv@WGq( z^?yWZv@f=xd*+a%1<}7R`I3fY(GTgZ5G^P!Z(@EXi^|>UIW1`Y?H!wNo#Bf^d-wuS zD1P5gk4Otsv@J%s4A>UOkxP^2%tB1O&;@vld!R~uJV&1>XGk|^)6_&8S(5!6TL8=< zcm!wH5R!Y#cFs$QnCy*5$^G|`jL1&_(>VETCVL8nG@S3SoQ661VoCTkgzr$8&ou;A z+Li#FJsAnIsvE2<_4`&vm9)O8YCR*_Orv!~M~(<-4&lwxo0Txxx5sXr+?lP5_s)VB z1~eW4NPcpykRA_%aP&DU$=g;>>M9vAFcckCfzy`^V^`DVjGI=0jOc5+*(kE2(%Vsc z3KLR2CZtNNJl9}CDh`zhWRn|bPIv((E)}<(5oBA?c8H6eU;g`eC8|N~N}eo5Da+8% zrWAmTEvSzU&h{q`D2b#vtw7_L7>?(-c8b7fQ;8r-zIk6uUB`F4vDYE~C_XsT|Mq?L zr-1Cwd^|Jo-TNBojXe@M!*doITyp>IN+yOR@|98;7Zm@Rg> zrRj#H=_+J`m0cHU&kAkZrGyD_G$wD$>^@OVrK1{VQi7Wq%5k%CpOq}Qq=uHoiZlR# z$E*~>1?DjC^M`&8>RzPgnQ0%LRNx1&xrz`#`yz< zuLfD^nX1$=SiudBNEBUy7(`c~Lz|iW{6k@y2oMekj;XfNApA2IeUVD1-RoQOT#NqEBx3+)eKgU<_p7FPv6d-4Kzh1&p| GLg9b+N)NCA literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/urls.cpython-310.pyc b/RSI/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5da7e318c42a0eb29d5483b92012d5240062b430 GIT binary patch literal 1011 zcmb7DO^?$s5Ovb@W3%05C5~KtOCyy;tTDK?Z|e3=D=lt z4L^gwkt-+u0umBqHZ`$xnY?}!tmXi;hRboB{7C6p>J@JYlD@n4AU48 zG&T}{$k|7o;0rj;rD8Z2fW&v0WxwD9=UgH-UA$>9^H&&*jtl z9;tw?FnQ)iDXs7So^XJ50LG^Ez}jnxzm1QY{$c^+wOGtgTSZ`mQTeTcu}97EflLK2 z52?VW1DzYz1Qw$?J{X8ENZE(#wjU2(O|BKugl>tthNt2_dn75h&EN@_v?|y$59;+P SYyldcoq5B~&>MP#pT7V-wKw4a literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/urls.cpython-311.pyc b/RSI/__pycache__/urls.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef1d773a6b560eb914ed66f24f540690dcd7e613 GIT binary patch literal 1220 zcmb7DO>5LZ7@lNjzf$T_1uLb8k+yCFHNm0>Q$G-EYe77;dRc^Rn#}HINirdmRl65^ z?9Cnu_6JBs{4=|-hmxx&ZwtNEi|@>CU=V?>4_TyE%lu zijS<7#*_1pF!_L7R70-fs=gAaHB}MwoSzGD4F~yJUO_6N*u_+B7czo&F`J#L2z`M* zY7&`;G4B>m60Tr*cIx#b5hui1(1#A6|8u$XM` zY>_BtZR#Y3roCuUvfGLM$W9U(hkTd#9#2TjItk?j7&u87dF|0R+#nn9d%$8!ybzdz z5ohF6n^VFmwKM{)l_U|jOw(l!H{7-zHd&U=VS!0Q^R}^SCM@zCZVIpo>A9&rd20v2 z#Vu{46FO3^Oe;xm8RU`c5<4Vb5V1J12x-JDAi;j!j-qjJBvay7$9PeJC}5&O_!Ww6 zEmx~6qG&60{Eq8|O)x>`6QzmW&HUMt#t@JK+as`aStpILmDb3v(RLWZ@J!?wyCO~b zXSI7iYnotSmZ>TNlDDes+Bb2EbtTQ)Zs3KwnquL2S{$Rh1sONH6}tm+!^CssQ8K$% zehx^&E(T-GZb{fHgg@8IX|Z01<5jPxm&O%=5lQUr#c+2~IyF&dj3E-|MHq80p(z#| z>D0u5_>9hB8C_gnw_d^JkX?X`X#b*gFJNxRrw`%^K*asz?_n6`6h#@T6$KBG7zk3X z_Yj$U&(MwD@7`en<;w@_hu4no99zc^`*>l17tV0$V7*tKJJ~$h>@D8y&s&3etB=

Eqm~xr&;ro}KHKTGh>(WqLy(GT*Mfz&=enVRyhh5z+*AD8p;7S8>W{ zpZLNy%{M)Q*9R<0Js}87_&Sb4E-<45K{y5mjs?Zzz!Z-;(};MS zU`~i@Vi-LkQtmoVKz(ipeJ|%C&w}self?(4rBup9l}y*w%2Sl7V^G& zG$so;@nZ6@A>)Q+E=L~cw>F@$V1o5;DyZlYCWY8aaUth9aQ%-OiMKu8mLyH&i}riDAXmG0QC@pjnK@IqvcT~Ma{v)YY_b{#OV zsML@N#oMqf^OroamY$WpAPy7D$dGhAtK{h6l*&89x;Fs1i3ojll$_zk(+Nd5L}08l ztV(;O@K;tXtF+s2yxQ$-Htz_G5G>qaa9_1-dZJB+Aj8Tsjd&-@)Zjj|AE2=5h5wOoKs09*zPu^lLw~n}<_cxwduX z^W7bH+ud2(UK*k6-%)kHHuvS({`|esRdq`Cn*qi@ DzdKE# literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/urls.cpython-39.pyc b/RSI/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aeebbb9f5e550a33aa284b977eb7579081ae63f1 GIT binary patch literal 1014 zcmb7D&1&2*5SG2(pEyYy=nLq!F>GxbdRm(P&^9y>dPv&KvfwC|c2|of8A)yvU-LA5 zp5A=zsjpBdbfopdwoqtgEJnl3H{X03k;B6n!MgqWf;T;czPZEh8o=Qt{N@5Sie`ug zG%N!V&ceXiy|O2wStR*0L}cAxd>;6Cv75bTk&m%Z7D?p>iICQXP? z{PFSv7fLSpvev|MCGkROe0g<_E3MY7uxT8BSTTHE>#`!&GA+$DF1fK-tJ*Sy0l{Fa z@F&hbn-rfxx=@;7E&)kwFsqUg!?0m&8e>>1Yb!I&GO7xb(lwDwwJldDkujM)O;0kb zDqfh(1!qv+WbxZuA^^)wu9ld9^R8=5}; zq>FbQxCVAQgj8sDbvzzVy1rIQunCq#u+y=#$4UIUB*r|xfyU?#>fcx>yJFfANj>8& zop*rsKWtolN=)uRj*~waoy(%EDVIwS!Pj%Gx!c|9bMA$~Kn1SH#j@iBFFGlw8@V>u zkvhS*B)iy&7v-PX-jr&Yfq>geW9RU=<0Of{!$6}XX#0c;E|aj0oZ{`Ui*5$qpEVCj z4RodDg&(D?dGx!(12z!|n>8aRuOt3G*=vV+4&#;Qvj<&AAcWQYM#I>nc7LZ$4KEMr z$hjlKEo&o((eCdI#22L9L-pGa{AM~AvMT16#1MK%bPn%j?tYh-R(I{_nNYMY+4BIB R%mHlC(Lr$3I|$(W`3t|=Ikf-) literal 0 HcmV?d00001 diff --git a/RSI/__pycache__/wsgi.cpython-310.pyc b/RSI/__pycache__/wsgi.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca486370f37f10a2f8ac01b09365eecf16815b48 GIT binary patch literal 519 zcmYjO!EO^V5cN7~Q8^Z2QR`B#O|>)Mt(FPq!&^&sICk=GOz|C*3#*1$;t+ln9pU~8ePet z(az_D_lg)AbRe`PvSwQlXbD_Gw{U_*ZGYn`WmXcTNZOya#7LfPGwdotqv(d(Df@p)OCU0h72vWm249i-z#5(i+{+M$gpH7Z!hD-+`FJ+>dr ubqm~vzYj*Imri=AHqu=Z+txdLR8$X;&XYsV!?zr1sAx!2 z$qqT*=Qu)6M`51KjzpLuqrG03Wju*Ook-E^8N6qPA(c7OL>RJkc0i>t;EAIBgyTJ` z5S@Y6ncDGvCL`ssVJKp`&=kqkN8vy69{K}$q@~X=xjFMc6!ZC#m`{5zi#mWt~uW(hWxn6JVyfOH*QI>nz@%638^S67F zyC%i_2v7&cO>IKR)T)xo6iT-a#5uiPwh25K|KBHIeQ}@l=Xpe;6W~f~g2W*i3g`HWOxNmYr#8dh5xf zNB;)N#s9;LQbE|0A|AXcx%K31($Egfy!Yn4_kG_R=JVPbL2gZVYT`Xc=vNsmSLM=~ z9XaO%;;4r>=AOho?5r=n)bIHi0Up(sEmw9_zw(zJukagFZxLbSA@HY{sou)OYp$H0 zlh@r=o5orVL_!BTr!Tv0n&o-~u?+}mTMBP8ZNN}F1iC0@QnDinlo`rss`;^mdlJSV z>6qnWo>D9YPWye9Wm3e<3a$EmhxgPmq&f#Glp{;$396L?7lsamguB!LkfF7i*$P9h zV-xTZQ;A+`igg--3Lgd!!l6E~I^>W^JxM{?@Wdn{B!9{gJ55~NO29_tU35)GvAOr` zNvCxXb@vYs+nrW7dU3G#>iPcZs+&A8V69MzX;zDB6gm1RDm-n9n+p*^?6e0ZWbQkX zq6%s(a;*yD8aWKuv9v|~8rw%SE7e@A?{2+u`14)12ifGJw!L_}M|s1QxW9l*=#IZW w#`vFC#g*AQ!sIu){{wmN$Qk*LHol^bFPp)q#y9l%XXEyH~4POq2#Qqq1`Q^rx219oEn$bfow{_7-V%dUdw2uWhFatu6cmI zLVN7<38}bNn?M3|Vf?OciWqYj&FrSykHw zAfpd8vnsjkWnuRuL|(Ix#K%B!b$(*`_bTrXV-Uk!_gq)pKtnKK3zW^ z;?ENY-YZkMUMF-oM|#c!wJyBeib!(Qo-~j(MUv0~vr@G+A;yOiW@4#*IM`wPMe1gO uoA8(Q&nBg*^2x1mLas&4k#f>_gP2t7&^_Od^8$BGTo*(8MVB7ZWBLy|qMx1s literal 0 HcmV?d00001 diff --git a/RSI/asgi.py b/RSI/asgi.py new file mode 100644 index 0000000..c8f3879 --- /dev/null +++ b/RSI/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for RSI project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'RSI.settings') + +application = get_asgi_application() diff --git a/RSI/settings.py b/RSI/settings.py new file mode 100644 index 0000000..bce8cf1 --- /dev/null +++ b/RSI/settings.py @@ -0,0 +1,155 @@ +""" +Django settings for RSI project. + +Generated by 'django-admin startproject' using Django 4.2.19. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" + +import socket +from pathlib import Path +import os +from dotenv import load_dotenv + +BASE_DIR = Path(__file__).resolve().parent.parent + +loc_ip = socket.gethostbyname(socket.gethostname()) + +SECRET_KEY = os.environ.get("SECRET_KEY") + +if not os.getenv("RUNNING_IN_DOCKER"): + dotenv_path = BASE_DIR / ".env.local" + load_dotenv(dotenv_path) + +DEBUG = os.environ.get("DEBUG") + +ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(',') + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'corsheaders', + 'rest_framework', + 'app', + 'authentication', + 'django_filters', + +] + +MIDDLEWARE = [ + "corsheaders.middleware.CorsMiddleware", + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'RSI.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'RSI.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': os.environ.get("DB_NAME"), + 'USER': os.environ.get("DB_USER"), + 'PASSWORD': os.environ.get("DB_PASSWORD"), + 'HOST': os.environ.get("DB_HOST"), + 'PORT': os.environ.get("DB_PORT"), + } + +} + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +DATA_UPLOAD_MAX_MEMORY_SIZE = 154857600 + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + + +REST_FRAMEWORK = { + 'DEFAULT_PERMISSION_CLASSES': ( + 'rest_framework.permissions.IsAuthenticated', + ), + 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] + +} + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +CORS_ORIGIN_ALLOW_CREDENTIALS = True +CORS_ORIGIN_ALLOW_ALL = os.environ.get("CORS_ORIGIN_ALLOW_ALL", "False").lower() == "true" +CORS_ORIGIN_WHITELIST = os.environ.get("CORS_ORIGIN_WHITELIST").split(',') + +CORS_ALLOWED_ORIGINS = os.environ.get("CORS_ORIGIN_WHITELIST").split(',') + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/RSI/urls.py b/RSI/urls.py new file mode 100644 index 0000000..44d04fe --- /dev/null +++ b/RSI/urls.py @@ -0,0 +1,24 @@ +""" +URL configuration for RSI project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/4.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path , include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('authentication/', include('authentication.urls')), + path('app/', include('app.urls')) +] \ No newline at end of file diff --git a/RSI/wsgi.py b/RSI/wsgi.py new file mode 100644 index 0000000..043abda --- /dev/null +++ b/RSI/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for RSI project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'RSI.settings') + +application = get_wsgi_application() diff --git a/__pycache__/helpers.cpython-310.pyc b/__pycache__/helpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bbcbf540e47ed7efc413eb0cd91b7cc20a6c2cd GIT binary patch literal 1093 zcmZWo%Wl*#6t(l3%nMCXL9{}!p3R6gLa0(JAr^#3cUF;cV|SY3Bvacd3`$q+7JdLB zwGx~D2Vda@8&>@VR$P1fQn`|yYy0Nj<8zPe;jo9mUVZpI{S_ee$1QGJ1dBBoI)jNL zjwK@Q8%SIRB*4xOWmrZe!srF!5s!}%k4114l9&&8!aK*9Bs}HaV?;W<$NTV2Io?F$ z;W^|)*%;g9H*6}hrrZ_^yrN>JsH-z<@!Q;m+%yb}H5mECW9nZFdHhs4l*Ua}MiloY<7oij{&=+oQCsc_W=apme`sa&e+M5KHb| z{R>Az&FPFOR+3@KK7)Ia_6(^31pDdl>c-P8#Wdq{rncT~zTDasawe3X%;qYFs04;i zVM#1})k^??(VKFrbp*j4esAA-}OJ=6lgBh2wv?D*xu3YrbM<2iDAjZJNsRI3oIoFHMV%chQHU=q-# z9-bD)_VZdcW#tt{?p(#touf;2&c=3jm>yRDsJyuQY3E!T8zJ=7vHOp(w_tA6W)82sMRqUmZ YK3lws=kBW7RZP(UfQ-UklE#D1KYZN(*8l(j literal 0 HcmV?d00001 diff --git a/__pycache__/helpers.cpython-311.pyc b/__pycache__/helpers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a940fd3249012668993d3410b8292db1e7cb78be GIT binary patch literal 1559 zcmZux&2QX96rb_OW;c$@Zk03*AKeO}MoUF1)N*Mls7*>#0V|-u!4z4}&SdN0k7aBZ zQf-9~ITR^ETu>qb(jHJ~6%PCn`~lu-rCK9#;*{H>a4Hwx*c&(5Fdjd@dGlt*@ArOh ze%19!1nryUf7^dZ2>m4n2TdI*`=5fcg$N?pL5BEB4t6C&!a|oF*;Nb$BMB`dqHG|d zQfWsIB9?T>EVynTl{9m;}*&N`a_dnQVt1ZP0R#gkS~#y8U!=M!Zvot}-~7Z0l) zENB&Af<+`oj7NzH4=@4KTA_DQ7k9@J(SsBpZ#!VxEzI}jt_=9$W<%zcHDZM{v|Y-} zg{Fmmo6)w;T~?HBey3v(VT{Pn3<6@G z(!X8YT#Rp|wb>!U>KmDOpr&R0hgwp*1burZIdwko4?js}F6P#L`O*Uw{IqKPUXIQG z@+8Nmi+XU{@g|`zM7{&e*)7=f+t^sJf=F}4;tnQ)C5otAHS|NvVXwd>6R81H#cB(V z01p79a)wGkL$0-aCvv^4+W3jW$6SrP7B4XxL{2zPoE)~6<+LIvyA#-}aK>qPgV#aC zDAi}4==H~Xz3273-#_c0yEZs?Ez#?J{rW(^9>0@nweROQ-%hmpwv{OL3?@iwv)QOH z$TQ+|aByg@LM79$eD=ixRPyNhVFFEFC2N+~_7}*?0$dK%379CryqE=vvutL6m2)F2 zTEY6KBu15zv@B#=0?3J3lOZd`0~h&50NiBoQ^e@V7-`?W_vX#V`~BXV z-z;k$aO_?*{9hG-zol_F^rc`PtBFMY#a*tAy zsWCZ$$__Aa2n9!>#8Ii@XjFCdo@VQ!ww5Jn93E|TAQKeTEj-0d{9EjRqTRA9!f@Tl z3z_SRdDjhNngvo{aNUnHFDPetRjzH!*5VZ7J$K9FUMQ^4yNT*_+q*EqSa?`pyKwEj ztCz1`XTcWZ$;wub&!N8%6;zVrD7Il-JKn!Me)`N%TOKbief|!w9|pCj(4h?=DUkN$ z3W^;_4^e`g99$+P>g_nX!FcMXu^akfhjLoU#|5pjq6MIf#@%N zp^pvg+xn<}e$W`q4L%({dG^lx!^SyujEwWQ^?y_h`pc~K-!75(-(pzDop&II?yMZp zF&zqKmXqD-%+E7TQcjg+jJin@*}1X+G}(Z98mC^sPvaDqz@w|`btL^rF#=%}nI|k2 zW;+hDFe=(c9Gk_sn_1Kr70!|@NFT3>5}LLbw6maSZT>u-A)7d{QS@PKHTJFM$ZGx= z{qn)ybFUAr=AL!2|Hjy?e{<&cYrmV#fj88e1sq6Nt7TU?vIt@s4@})nY(@4-%s*Pe zR-C>bT%smwwChEkc!h4PV0W`1;j$yjZj^OdFjd^9BeF8eP`Zbo?k literal 0 HcmV?d00001 diff --git a/__pycache__/helpers.cpython-39.pyc b/__pycache__/helpers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa626db2ce2150412bbb5ee1448629b5bc6c7478 GIT binary patch literal 1089 zcmZWo&2H2%5ccG6vwzhVQA7)ZUiY%%j1W|6CB!8_dy9%JH}-B*^0T#_(naa1y}}D1 zq*mh6_uvh<`O2xUz=?6TY^&nP;~9H0^Ue4(>-ReZ$MLUM=}(7{-`2Q2JTx|Nst5%q z95NEy)yW`tVh615W^V4q9+20Bd)z-G+!xNN8~eP+1Kv7=IN%{~pOLu5JG_f)$YF;J z`&Sr~L_;w5-?52^s(epK)Y5|Kv@9;c!286y+#Z0&22S-5g&;9-5<47Xmpie?ZBh?I z`)06NDP86_;jV0RHdKA6-PT71}3DmV7Z{wbSTYBUS(GAQF>UhY399XLQOW%j15|j#0f1dr4#uog4Az>DKezyqG4t+e|S&W0G#~yxH9s*;Gh1n$Dz; zt^rPEMF<{#&0gZ7{cqSiu#THJ)dLiooI_1&sGSS<+_@kpZtY^x5Di_^KHy9Xo#w)X z3$3fmi4>DkrmPrx#+wNyjh~l=-Zw61Gvis;8{o2!Sfa%Sz0J*+kk+BaVj#djDN(kN*KRszww*hyQsT+Rhsen4K3sEDnvmbfDoR5 zTtof8=GrU`=EtbimdQuxEG->ztIa01!PrDZ z8#eHi(59P|S(O(Jzv88Z4;@!UVge~tmFc_qm*@BsmL*lzJOs=1>#h$#uG@@m6h*_f zTtYow#Ws1=^S-W&eo7p>%d?Z7-EKtW>KPzS%aCkVAkZA;iV%0B4YqIH`-wc8b-q?Sk2?* zMe5gr!H`q~&!av&>N-9rk#t-~HpqM+2xXq*JE0U*I(1GY4VS{=H%(Njw&@aul{D42 z^+btvkcm@^#ZIz+Jj!SNb7`A8@r^bXK^B&?)eXwwE;SC=A`J)GN`!>O{`aksMTZYjyv}NL5U9AlC^|!J(+yAR& zs>khckD`8<8iuFYQr>))$(07oX9Je9ZAy`yRSBQ{CuD>j2=~-R3JZ{|;wv NpKY0d_lp6A{S8-<12O;r literal 0 HcmV?d00001 diff --git a/__pycache__/manage.cpython-39.pyc b/__pycache__/manage.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2927cf79600363ecb7131db12066585c61b78f90 GIT binary patch literal 801 zcmZuv&rcLF6mC1SKSUrL3=vPgku`C|lL;~6hTQ-L7s9R~Y&L1?w7V8&TGDnl>;^oD ze})G=^4EBut0(^jW1_FSkZ`a`zs~f1eeZi;%a@iG5R4y#7awm3LO;XL{Q-OE4NR8+ z2-HUc3zFeJo~@)$L?q%bs2|B#RL+QfDx+(Jksw{vs7_zDPPrbLbw^W^=Uj_tnbMLL zUS-Np=+IcoMXt1R-g2+Tl6vmWT=ENwp-vj`ZUiAg>NZR_0PyG(e|T@9Sed}R@{tVnYy>@*5BFx>w5>I^jNHVPF}I^} zgUrK`yhv}5T?FdyC#}ta<&KL9=k__+H<%|&&L?G@bERv*a*qHIS;hpf;DF>WiOHYG z6}t@kWu39WWUNssYm5n#GG=3l*ardbIGX1Y0-@|ZSej*cl^aoH@^yG)Eg`kg5bJ?=^*+sh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DW#VV#Ku{bfM tGO;KoDA+S5v7jI(K0Y%qvm`!Vub}c4hfQvNN@-529Y|v_6OdqG007cV7>NJ? literal 0 HcmV?d00001 diff --git a/app/__pycache__/__init__.cpython-311.pyc b/app/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d019d5bf624f2c9c12ec74f44d4ce002160472d4 GIT binary patch literal 131 zcmZ3^%ge<81oiH}(?RrO5CH>>P{wCAAY(d13PUi1CZpd&ryk0@&FAkgB{FKt1RJ$TppfZp_#r#0x12ZEd;|B&9QN#=s0{~F2 B8Vmpc literal 0 HcmV?d00001 diff --git a/app/__pycache__/__init__.cpython-312.pyc b/app/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e585a3fa27d82b170755d24a99c4c437de1844ed GIT binary patch literal 119 zcmX@j%ge<81go7mGC}lX5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!5_7hS2@3X%Nh~Oc siI30B%PfhH*DI*}#bJ}1pHiBWYFESxRK^Iz#UREg`kf{M%bnIQTxh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2D7#VRH@uOK-l wD6u#(r82Q7J}B5TCb6I(CO$qhFS8^*Uaz3?7Kcr4eoARhsvSu8XCP((04n$z;Q#;t literal 0 HcmV?d00001 diff --git a/app/__pycache__/admin.cpython-310.pyc b/app/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd8ac1be717ab50474728df3dcd4c57a3b426572 GIT binary patch literal 165 zcmd1j<>g`kg5bJ?=}tiUF^Gc(44TX@fuanW zjJH@5Q*tx&{4|-O_)@YG^V0M6lJoOQiZYXmKnAR2C}IXuVB(jIi&acfVsTTZlX-=wL5eHBWBM=wM0*MdIjEsyo7!)pGLq%*r6#!UtD~kXC literal 0 HcmV?d00001 diff --git a/app/__pycache__/admin.cpython-312.pyc b/app/__pycache__/admin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ba60a10ae688b9048ed1893c0135595cd996e00 GIT binary patch literal 163 zcmX@j%ge<81go7mGM#|*V-N=hn4pZ$0zk%eh7^Vr#vF!R#wbQchDs()=9eI8O~zZS zi7C06d48HqxA;=B67$mY^^)`RN{TX*ikN{4Rx*4Bsrx1DY!wp}>=~0-P!I#wpjS}& ji^C>2KczG$)vkyGsD=@Ui$RPJ%#4hT_ZSq4*nk`WU85ug literal 0 HcmV?d00001 diff --git a/app/__pycache__/admin.cpython-39.pyc b/app/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a101e308572f27bd9818a9b8677d9ebb90439526 GIT binary patch literal 168 zcmYe~<>g`kf{M%bnNC3ZF^Gc(44TX@fuanW zjJH@5Q*tx&{4|-O_)@YG^V0M6lJoOQiZYXmKnAR2C}IXuVB(jei&ac+UO{q9P-1an nN@ZeEd{D4wOkzPn4A>04g34PQHo5sJr8%i~j6hwVftUdRD*Yxd literal 0 HcmV?d00001 diff --git a/app/__pycache__/apps.cpython-310.pyc b/app/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e3c71606344371de344a29d5a657e9a75b8d9fd GIT binary patch literal 386 zcmYjNJ5Iwu5S{gIkQ0&yr9()xZhQcQPyz@4e)z>eU^2~D%_|pyHD;i+Thj3?PfU1Kf@jngdkYRhTJL&+~Mw0UpplK Whi*OpV;7!pueNo#Qj5VH2nc-`pp6I` zw1BiJknZB64)DTf6E>330W`Po0 z;x=~tjH!~_b7Fri9Bvmq)o)1d8B#gWy4pPKUUtsA>?u!Vg?DNQl?+xybxxC?wX7d3 zjM}oaGik~-Dl@CJZBt81+2GP><5H5e(o`6&^GBOGk4M{F%3l&)a9ZhzxP<-1@4ed6 TaCZfN)2#3=zkd8fsmHzmmH~1@ literal 0 HcmV?d00001 diff --git a/app/__pycache__/apps.cpython-312.pyc b/app/__pycache__/apps.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71dcad53f7eed616e4e5da4f128e0f1f65221c07 GIT binary patch literal 408 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/cityandprovince.cpython-312.pyc b/app/__pycache__/cityandprovince.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34938e6568c58997e8870779e29b1ca0875c4457 GIT binary patch literal 35270 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/excel_processing.cpython-311.pyc b/app/__pycache__/excel_processing.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c92547f8d47603e66c9deedb154cc7e9c45a3322 GIT binary patch literal 56994 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 Xl2Ov|9nnfgw`Kc8tHe}XdHMeV93-87 literal 0 HcmV?d00001 diff --git a/app/__pycache__/excel_processing.cpython-312.pyc b/app/__pycache__/excel_processing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8db9715ee9c0dea5363ef706e3cd8eece7fc0e1 GIT binary patch literal 95407 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 P%SIdi6~izpORfI^{AgYU literal 0 HcmV?d00001 diff --git a/app/__pycache__/filtersets.cpython-311.pyc b/app/__pycache__/filtersets.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7018363ac2f7ab4aa3796646f5352d4f32883295 GIT binary patch literal 12174 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/filtersets.cpython-312.pyc b/app/__pycache__/filtersets.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfe4609f553e4b4b3fe9604a5b50a216481a73df GIT binary patch literal 12371 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/filtersets.cpython-39.pyc b/app/__pycache__/filtersets.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4acabfde3d2523d3856aa787f4e9c66a11aef646 GIT binary patch literal 9305 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 WsZxoaEI~Z^(icn5mqtsuQtm%rp=E;r literal 0 HcmV?d00001 diff --git a/app/__pycache__/helper.cpython-311.pyc b/app/__pycache__/helper.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65008ca7f01737441120df1b68ca9dab7bb7b84e GIT binary patch literal 6388 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 b_iS$~ZGLt_pw8!Y0_~jN{d)pGQ@Z{Ko_Ur; literal 0 HcmV?d00001 diff --git a/app/__pycache__/helper.cpython-39.pyc b/app/__pycache__/helper.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65d0266c0eeff5111a528feb3f57f9272d7b2827 GIT binary patch literal 5220 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 axsQ!n)Mv8c%HaOc=!ka&|Gu>9x&Hy+ZBqvT literal 0 HcmV?d00001 diff --git a/app/__pycache__/helper_excel.cpython-311.pyc b/app/__pycache__/helper_excel.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..726e4f89ff919f85e951ed718a6723b046da0287 GIT binary patch literal 15525 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 F{=ZJN7N`IK literal 0 HcmV?d00001 diff --git a/app/__pycache__/helper_excel.cpython-39.pyc b/app/__pycache__/helper_excel.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff0e54bdbbdbdb9593944a4502d7f14d533f4322 GIT binary patch literal 8744 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 Tr-V{#*8GzX+P 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 RDHhl;5DONEqICKQ{%^XjF(Ci| literal 0 HcmV?d00001 diff --git a/app/__pycache__/models.cpython-312.pyc b/app/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b996c78e9498d9c42bb30ed32674213cf707323f GIT binary patch literal 33495 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 F{|iwTVQK&X literal 0 HcmV?d00001 diff --git a/app/__pycache__/models.cpython-39.pyc b/app/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa56fc70d76ae63bb5f08a16b94efcd47dfee60b GIT binary patch literal 20675 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/scripts.cpython-310.pyc b/app/__pycache__/scripts.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcfab77e7c1784c65ffdd879689535fe07fd1625 GIT binary patch literal 1059 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/scripts.cpython-39.pyc b/app/__pycache__/scripts.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b55f85db0d7991f816a5bf840403341c8fd19812 GIT binary patch literal 1060 zcmZ8g&ui2`6wV~sB%A%I6vR?g@Zy3j#iNK?TBK5Gm$s)+3DeAUn|1P|Z)V#rv>>e4 z{tvsy{ypC2>dAk>gZd_JY3+ph=6f&iCGUNCp{-VE;X42RF5Pl1>xVJ!t{NKeam%j= z%wj}X8Horn+!l7`L{7yW;byg{R&iH&nIHLC5CxT86ZI^N!isyMku{@c#eLDr+EF{} zL>*%BHVcMiN_dAm)!Afq7Jjp)=$n$L%Nl!DulW&OzXJiF@my2WM(rmCo_i;W;18*j9lij+7+4A zm^UYvyx?tUr~Y8u+68DCG;L@(X-44^no^Mrrsk*KrCiQ`n}V4)Wkt@x z#y)x-@bJ)naX8|MlDaLqKoSENRB@)=A{P_w9i>8X&_Mx=Lwq=a4rW2iK-=WIlAdy1 zDtcC5g+03JrXWTt=|mF0uc(w*A|~ z?K%MotE)-i8Q$IQJUI3caWLB+5Ar{-u z3dV)3BnIE))Y*vU!=ld)Au#sJ!Zx!g`-~?AP*s5Jn|X!033+_)HMc=v{%bIeR-IJJ g-GQejJ9vXNj0Jyd##t^QGzngI*C6Sl8UeA%Uo&PW%K!iX literal 0 HcmV?d00001 diff --git a/app/__pycache__/serializers.cpython-310.pyc b/app/__pycache__/serializers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ac6336f64e01b86582340a3e884fb40b41c31cc GIT binary patch literal 8854 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/serializers.cpython-311.pyc b/app/__pycache__/serializers.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d2373eedcf5de9baf52e025a8d9e947cfe6d561 GIT binary patch literal 18801 zcmcIsdu$uYc_+oENQx_odXSQA%X(O(B+C!kKIiP{o7sxpIo) z&=&o^S(3|Lt|xE(_WM5pYSGs*m4)E zH!LR8n`BywYZBhDH^GD%N@I)HChEdb~vkcqW_(Zo79$EEsw1>S~o-+@y(!ahpn z1gh#XR1K8M1yt@bRE?C%15`C-sG2C17pRyrRLzvC7O3jVQ28lUJy7||Pz5Me15h=V zp=zO2O+eLLhN_iP`GG1>hN_KHwE$IX8LADGstu?%l%d*4sWt-DrZQBUC{;U9Z7xIA zPN_P8sKou%O)kUd#fvT?zRX3&T2db@QsJ2k5 z0ifDehN_1(Pnts8Kfqxy5wgmb$=QT#IdElKwvD7_lWEy}GGvzBJV#>Dce<( zoJh^a)8wkmN1x+$fcvPxa=$t)fW@xa;wK< z@%Z7?EYHb~12dP8Brl|(+`99#u{axRrm%yxL6g|!y4=f67T#U< zOmpeT#oWtks*-22+5)`Ps&JODbsDPhZFAVhRsmbfhfO7H2VQ^{3VGz}u^8dg6VU`G zJC8+kSN0cD=VNh5Ig^Yjd3B>RF_ufjQt{MuY-%LMa=jo?IGJBlZ(st3o$Ov^0!T^ z*x(-q4nBMC)Z~$K(V3ZZMICHl=BjMPCLs+#<%N^)0k~24m#uA{v#nH_>#vwsOe)UV z@gE5SErIFAG?kYLT$^ydL2bX91$fhx2FxFq3SDEq_=$YBDPz8)>q6J7(vCv5DO1H( zrSUa$#~q7yZnwEwZgkc?ALY6HsH3Af zWRab(&T`}`&!uJeR4P83NKz5X-sto+;ijQOL@vxGr(|aIN_1+L_6S7}IFE4`(#NlG z1bDd9sdO}cAVC#`J)Yuujwd_e^+PsN4S!@u>ii{cD$S$B<7ti%22u&OKa49Y&&4mu z&RCL9N1>CEc6`D^Sw^CiC)t7I$dI=Kw9|uxFcIhPYa2_4Q1QU@;e%HIZkQhWIwW83 zvTw(dZ^yl$;M*bkMkL?JobzFGa4{$xKKrwHN@$)Dn`flvnK{qHmcGT8h4FJgOUwu@ zuZk_NN-eL>F%NxR3m5Mn{aNI^;F}VCQ<86L&beYYwFR?H-C2M8io;s#S}`e5?V>$! zBIG0;Sm92DE(Gi{a-*tEpo?Ejv12$SXdBQ@OJ9&+e^)v(ed#*9MR3E(a{xtyf!RLy z8Hw4xxKU(=C1&`>;T5aJh9komAJO#3#knq*4XR%XN)51FjjFRk0v;ca)(zxjoA0-3 zd&v$Ia&(&0)FwZ8SDTgUQ1PVy|UCodpSv0}~i z^4^bW2-q3;Ujb0%{l2Sju1|9HEgTVDdnDJM8zU>$DqHJ{sT3Yz+G91NzRKo9Iz1>u z5X+l_vv3rKAWn8_r>BOE84Q~$ond2PadxoEzI^}Z)nTP!obPAlN0Z-x4IM{h80up% zhEQ*$F7RdKCUmCA+6N-vy(m=tLs zJ58e%q;UaqilxC>So57Ko%v}6^VD|94y5z|BNQ6F$UJpWDOy2_Hk}lmxQY!|vks7@ zQ|>IbqBW+rD%;by&2ly2qHH9UjDxw3W9c#&+F%`iL`52`pwyzS5Gqlppi$QA3g>|2 zc{q8!It>|i1&y7Dss+#0F9Ey>w%aB6s~nXmQJ^o_fJLe@KP>XB=-;;iRrR~Jsw4-2 z5cH&*a6B095!8?5Fr+E7{t>)7iZBkK)s10Dxi(lylj|fqhODs9-!OsN`_0#vna(Aq zQ)Id&rhCD1$0G$lu^b#)3J!_EVJSF_rh|9vL7nJ5s@0P&{UF03q|_VD8LBa5cTty8 zG$+Jz-lk6?f8Ksy$kbITf`@sg35rcPVe9 zO#{g(I7{Z24nw74+>B^?69k;CikcCVo=P)r$ajVj)#b59Yv%RT`W}alvP@~ihOEk( zYZJcLMudKViM4xQ0z>ybB-HJ{T5iA=0M*^G_yI5YYUvKen8#g$PDT9FkZ-H%+&URCRQDM zxOACEekDg5S9!TZZ;{=xYArO@hHa}HGiKI)-BJ-(hnCB_T&)#xbv_|iTiTVcJ1p(i zYr`sN!)mP+dflF}SI~y8C#;tvV`1%=tynkGl&(?h2;MErHMa>OF4t^;9&K%s*#6En zp9SyOI?q0XFJhBcBD%1ho!zuE{Rd z$rq}UJr{G1?FeWp@)@9#U58RBR`K(Fz(T?Y_-x26d#BL#SMY?(Ud4NtXOO>-gUc`l zE$0_MY&l?L5c{HL}oZL#X-EmuO}_!G%7iHV>ACijV4)kO+^VGq4kqpN*1Qb z&Z+23bPCi~$VH$#naFO0Jpgib!S_jBlmxYoY$NcBtZa#MN!c0)Z@las$#EFt645vp za#ObkIYwFJU!5nvhJ3$-@MX+#fkc#u2v2?kQ|AzV9pNhgJl2K!Hx*EPA~TR!@N#OW z66y~@jg1Bke-}nDI7AxSq=v5LhQ6hSzQvJyvqD3k*f1(JjLubO10BnO{-r?w-ND7z z#lb_;;2|NOO1Q( z9}&)kg~mN%<5{Wk?3^p>?^yQtFZr=n8FBESG7~v!~As+=Zpn7lii2cWm?57e6cZj6U#* zTaG=5itQ()_7ej9;t9dI;TLw(rjGg0Tgh9=?8bilwQtY%3}u7E+3shv8+sqMY`A&p zt!=lqWm|f(``|^!Z&rWH`%SOt4@&rZM({uLVDn0|2c5(U4d&cZc!X(>)eLVlx`InVv8AxQ zDL4xU)z@&h`h=^6j+{9&mLhrEREYzsCX=R|$_=HS^*Jk6lZ{-3ijz+xsHPLzNM-Dr zZ$kFx;ViLwAt05lJ1Wqh-l8$KdT(OE2%kfKrB?4awR(*Zt=@5J^%~_Wl0wFs7A#2W z0_13YRK*Tn?aYLsQqIm+K|~Am%t!E16&!_n=@RVIr^(CuYE~}j!b(ZcS`lvzLB9$_ zvZo z0B?I^6gnKlJ0g5MIy-$4yng6(mEG|aIApJ2@RgH2$=Sqt$iOsS_UDY6f@Kwn$G|G$ zIWSsimqgP)Pp8$Y|G1M=G_6fe{-x!p9-GZH6fgWYuYKPfeygxSBnce#Dn zQv0qyoxI=pqwtTzLi;YU{jk)2_(4EwpA_0(7G8Q8Cf;mQ`*Kt7Qd93;-{LuO$Me#T z=Y^(Tv1vqVLZhVVn9xLx5_h(%e}R{_4U1jF_eaFeLomNXcy`OaZ0nYXZJXv@ZympN z{9$mbFfaz8px{v{cyy)OhO@B(`Pmp6xdUEE7qTsyjj7H?U9k4Nd<%0Cz6>XiTJA>S zU+KJ@^==ou+wbiXyu+dwT(HA84y{D_VbzWg*v6vlj%m&J5SYWy%%D$Oox2SbJE$;vl=p?UmtjivIvEBoWpwW! zLiX>&NhT4{Dxsp9D2+o<14@-;Pk}y!S9kI-4;TD#fFdz^I|Xm&0xNh2Mem^G9Ymph zv``WjV=Sd7G^jdrW{-X{1mP6ishWcFlg0Yp!(auhl{wc=a9fS+IuXU$l}@Ukh6KgX z^5YeHrplOCKY;Apa2lIelR_Q-^mC@Md9{eeA)ux+Ft1Ki^U4U(ygE(IE2CVcPa$JX zb6Oz*kJVv-r!cy@@&loqKn;djhM=0#?m25Ww_=Ly^A$Lz%kFi0#H0ecL?4c_YMl)1ETkUpkY0Y;w@lF2P+L5(Js`E#ZmscGO;Lv@W*iKI~X%4FoXA4ff*5* z5s4YWZC6$s*1#BX_MV0gW}K^ZFf7ZsgMBQa3Lh?u=$2b`=BDd1O&uzmxcvsaiYDyR zv5m(6IuX0S0+PSPrpKwHXl&O83?p`$wUY-PvB0_d70}GEb~0Up8|5(G2B6<1jG=;} zRaCwe@=WMo*k%Li>arMu0VWIvtoxj9MM9smrtK?=HBHwYa9^w5!?>t};EtWG z*QHfMnopPJg0u!T?YbN88;kBe83$XJ3ova>Z!Q#S%D6KQ>OW|r0j6ecFTP%*p#?5w zXuU}*)VKytF9da*z_~h8lkq?R$jka~Il-?Gn2;SraXQI1Tr}-a{_I3g!=FK=6i>tF z@aoS2t~tA3+1j1h+RZ|MhQSFrLiZ0vBGa(FQj-AttV3q{5d6Wo#%Z}K#)9TWzl7|L zC1+;S5gHJYJ*nBWdY8*mLMHhv|>jInc@^e~0k*2m*qL@Ogw$0N9^q zJ&$1*pAv$>Yy2u8nZ}O@TuNmqK|mo;Q&h5CD5xkaAMiPf_ATL#l3T63@@F0n!x81xYZS|lucaJ2ZM7B z!H!K(Un}kxrpW#B08{@4;cpRs3Lv}lVJG+;Lup(I^Zo(hACaK8=*<;*)D^!7O(M%k zE(7okK+cns|5N1AX)~Ik^ScuM8lN8pv4S(FzUgcI%k>>g^&Rt{5bL)}^;_p05V-%E z`%UJn%)CRa4NA2^p?3SiL70ZuNdGyrSz% zVO(r@L27tmZnSdBtgrdaeP7+TFngbSW1r|dCi#xd9els3<;~<*lMm|~--wI#ol<@0 zLx1bdV|VKoXBXSvZF{dx@DGXpA;~}VFwl1M+}+Lhtc!i`_Py691ct=GkQ5kt=-+UY z{r--{#)bX2_utts`1gwby^??L!@$Oy>F*y{>{=MVJ$`3g2<#ODd!@i$O8=JomV2ef z)ZG2Zpm-Ex#GaR=o|gnq7kb6E4d34AlfagsNz9I!*5j@@S zd%q_LRM}t%uEC|&*q-g&lWpnEhMvdpS8IQ^_aI!a)K#N5O@X{OjeG-prp~7R38o?3 zhqHpPRfTR9XCL~)Nb6!UgB2_d!Gi2cWiWs;&;!a~0A--hP-KAYo{9`KJ8DmH_;v0<*d=s66(y{ufXW9( zd$CH=vCNGOWF+1i5{1BRvU#ZI3 ziCtI^*wuGpSJ!7Kf4tg@&F5SvVPT;$@gD&y%_!ZPy$ek-m@lz#Y1 zKe?kHa?wvn=ywZrBR<_YPB%i)%``OhszmP=u_Wr@{SjXM1c6#KIJZ$4F zR$w1G_bZ>Y4-xneNKEiE@n46xU$L0Y=B$aiLI1sP+9s^`%bKrWrv zH+2iz--^B7490OO+;mI+!AF?!Sk2wTn0+fSUiC2VmfH6{!i>jiZkNRjhFmG!?2}q{ z!-vLZ_{6c0>v18|QdsDddPg5&#$z?NrSO=_0IzPgN`YM^oYx{gD{a_oK#U&?SjY%$}`EMr_~l|l!x2;9O|MB-_}B1+-r zXQWNfKEjO0YVJ-OHhd|}_emX}ggt%O@P*u3iy0%C#+Yk;%*5&x2t774M#7A7VV~4D zhQ(mWtcax6Va5oEG0yLkI)`A{3nZ}aRS6q*;)|C;t`kAVV>S1Zx$s)*3*yznxYU2h z;LX9jwV3rV-zsh1k1_xYxRC3yn86M!g+iYIQ>~B-#9&2~LQVjXfy6lyXiGzBEu59M Y9yX{m=w^#q54q6_8OT|mOV#)P1Kv;msQ>@~ literal 0 HcmV?d00001 diff --git a/app/__pycache__/serializers.cpython-312.pyc b/app/__pycache__/serializers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcd9487e523ab20aeb544bcae7dea4fe0367ca0e GIT binary patch literal 28252 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 Wa~nE1*$9G$U7`m59xIeYwEizY1(J*a literal 0 HcmV?d00001 diff --git a/app/__pycache__/serializers.cpython-39.pyc b/app/__pycache__/serializers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..342c9ac5bc1a23f5c0765b5150e6533c67910930 GIT binary patch literal 21610 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 literal 0 HcmV?d00001 diff --git a/app/__pycache__/urls.cpython-310.pyc b/app/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90b8f2514436857482e07ea98ed7768c6e084dfe GIT binary patch literal 1627 zcmb`HJ8#=C5XU81mSxNG+s?C1R->>pbSsLYK#U?mfgniI4uS!JF=<g)Stg2kL2Cao~~B}cwT=0HT$Xx!jHIm1PV%(SPf+HJpq6>D>QH)ZeWm|R1Mmf<%yW(hu=2VTUqZ_&?5P2mS zHB!5&V}+D%8d$-l&jsKyQGqnEnj>W(EnLo#3XnFg{kUiYWkv5Qh+|H2>kY~7)5(#&S25m_(o8lE@Xn>s-~Acqq%TD!%bnN@Od{Dw!Mra<`iM-?!VWIHML;Nk z;+;kA8HoLbk5NEO-vcvUniDHnnm+aJzy;|SqV9|YW=zG#VjLz$T7o`>8!gZ> zG?DV)E>bC(SqzSE)XpCY<0I6|B?*kJv_Ik*SZI^Q~9YLA0s zULl^F9jlePJB32w6M9#1y}XBVIf*Y29~;SWz9S7wzMp}&mO*N%r5HhBYo!UFpOO+%=P@!Jswtmu*B}=mP!?OG{vLh)?vWrbobl0`}3kzh6q}u{a0D%$57GqKp zNGe(L6zpZaz#e)i&>VZpVzK+jNDCbZo(e2bpf?xosi(dfamG@_RwcGHHJEwx{mi@> zzIinNDF{&xuCEurXurF{asR^&dZpaTcW;L{?h8)l zsEgW?7$S9E4QmlGqD951787GyT#RdiD3HEIby-V@2`womNqb3M(NbcH)I(}oTNPKe zjF{1~VphwEIc-f`)7HgxEidK+T#!TjD{$-I)JIM%pu(3$)|{xwVHA2=q6RtqpUA5P zAmKN@0^CoMQ6M*{PLBE@V?dS}8S_ELf!t(d+y^NDSz)B$gIor3i;>Gd$OMqvj7<0- zlR)k;GUAvAosoGTWC6$qBMUyrB9ONjS@c1cfP90IB_HGl zkhdAR;e#v#d54kZSrRg7P~L!)yx~WSY zqu13w>@f1u-{!diNQu z2~|T*2BXaBrr9M9I?IwQlUkGb>LlD@sAEo)OsOLz8%|!9jP{eRq|3n5HM(GG)@^5R z*4BKknC+&jv=F$}?DVxKNOwZ6)3A*26A2(mL)MCGtg%U*F!jnx)0#2S9brZ*$*Q$h z-!QwHm7$he56Q|IEC|oy#Mzd>ld-ast?QAk^t7EkZ7c6#q_d^iY|MM>+IFg_5Kef) zRi^?&}j%lkj zwHh7a(4N?V@>Dm&+3K9E)Kfe{*9uF$^BM_P&dNe8)!0Bavr87$uoBZj*szkXMPb8= zU58=A5=aBi1s=CC{UD~!VgsHi3)G3j2vgF%7@w_%m7YD04XeP`Hxuv;E6R=^(6f== zuu4C7nj6;sEaP=L8uzQebz<^UsdLt?_jT3K@qfuW4~3J}aRxZmA(EeW_4B$;@|2-3 z;?4!B*VC79EdsSB$z0AVRO=)G;pEUlh5-Sm!#4z{hj9_X1^(>NV^BCzEN>&VhjcxT ztpc{ju+?bkO3yU(Wo*GS)X5Bb0?U%PfNvH~#~&(s8W*d$$UxyNjs0}OIyzGfI10}4 zN8_~h354Q9WI8#weL@os?Z~HTA%8j0?V^q(~g#3b983#1YIHZr9chG zG|hB7Y(G-&a38{HqCoazd~W^-@30T>JB(?|bf6Y@2OS`N)Keb98}x*}K;MxdypDS3ldI$LIdWo9!iyf_uVeg+`wk+L z`yqAm=HmwsKYR@F{1}Vsy^9~hZ)sh*ucEj0W02tgz>NRG3A?Q z+_QzPIl?3nZrH-w9AS=5U7jN>65%~t*qI|t6JgyJ3Uh=dB0R8#-8sVXs`uxwx* z*+O;Bi0f2X`9;E#EzA=Z$cR;2*q$@uczZVIZ%>wt2tlziXT)E;>ah?ueBSnK(d{{y zGxZJ;-m-<8bA)?zd+MIT>!UCZipu<;7@rw9h2Cc-$t^}+oLr_ZKfV0)vrj&MG!!Z$ zp)%yRMm(%8{NiK~sSLJ%H{|b)_u#m_E= vd}YMLgCic#05=8)?+y9)NBsM);`ZRKIOHFV_(xaeR3i8yhX3><$n8G@REB<> literal 0 HcmV?d00001 diff --git a/app/__pycache__/urls.cpython-312.pyc b/app/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..928ccf6fa67d6ef82b10048bd04989c76e64a29f GIT binary patch literal 6827 zcmb7I&2JmW6<_232BnbK%LTpQcw#?AuTM0wP|Tu6D3iLND(b6MJeWtI-|`>vsz4wQGG(4)8?gl zDo?5lT3m{2i_)UDBrR#n(z2G25?WG9YAGqDrKPl%kuq9V%4#dpik6dd+N!jwtx0Rz zy0jh;#smbO_LnbhppCmfVnOj9PNB)W2V7?oocc@f>A0;0gb~~j=3ZkA-oua&ZWwc~ za}JYW*avqSb8j*R@8Pr$u86s}IEP74^udi_?q`g_dl>P-jbg6EIZT34AKV$tz0DZB zhciC7vzYri=P(J*`ryVe_ZN)8dl>VPAKV<~{)%&$1am&PtC;%*WAGlX`rxi%?yotANpQ^vcO7$o!x+4W>rO7NPGfKb zw*g#Te#=ozdK$2$r((X~n(50V4A(vi2VV7P+ z(=NS)5-xog#a#LuDCyGABhjT_Kq;4g5v5)Fn<(Sbzk_!nd-pNhBi^$*??S(Y(JQ{u zZ=;-xeF;Te`a3A<(!YyVUHZFd&82@2tuy^-S^D7Qz5Mt8O%|LVvnG{VMQuT3fri{X z&Ic@UA64a++Pq$GHIa@DXC5f%p^=}omYcdSe&3?Y@uG-NBzIj>aq^Ye5?Az*l_gL=CG~& zP-z~QRi%RPvdXoVb_eNJlI$K^E8CiCT`y~L!^-hVM?umz*_rOy+q=)!c?+Mqwe}(1 z-q(ZX*#7Bt*s3(kWHYTD8UWw5Q>RCksLO^7Ph?rQG7zZA$%OL*Tt!wZEmbD((41zW zlZ$Oe>Fp{E9-^5TkmQ=Io*0TTh{j>i9qsXdZ31%F>T?eUIr(0SwqwYsvGG|V``jQ#u&%R`eRKe+ttheO82JE@g z+*rc*$t#EADOuolN-UXk!&$UsCI`Dalwe9`XprtOdpNU{%=GJ$aLL>n=6GeJl1Y>K zh+I=LSNR%8Vp1L_#ZpqqTpN9y95nBdk4h%Ll&9`Wp}+r|qkYpi%y8%akIaUreSK=f z*M;Y{(n0=;6^3`^+EKmO(p5tz|Mu$uH&$FH6|1V_JoK=x-z)00JRABMGB_?b8u|p0 zf>J$92_YwKn8(_1{(dB-r zVSB@fsUbkW+z@~@ME`NW-Z1*AGxqDW>I_AfbYj>#n1i{?4dn*@)ZAxZn(yO}kF1CB z3NAQotybi6l(!-`qdw)T(;pMA#`Pt*uhYbOe0jx>cpzqlVV-`{X!c$FYtJ4j=rU+BeyL4bGd)ePpSRoetRPiCYdI93fIfq5~2=alsQ|$71_% z#=_Sz;*PzH31@1s5n}vwimcF4!YZQeT~PL5^CT zh_mhOD_!s*wV!Wal)B)M%3JOHeiwW|<8`qm1p^bPX3^qAJ~iS-NW|o zjc2=uo!!Ik?$5j6bBfQla~HedO)77<&wbnlpHTUY_Jz;7;Ad2Rt9=P}0Xl{0Z@`NS Osp#03Vf_Zqs{aKBUlF+g literal 0 HcmV?d00001 diff --git a/app/__pycache__/urls.cpython-39.pyc b/app/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8a2656156e93bcded7135151bc0164e636abb43 GIT binary patch literal 5570 zcmdT|OLH5!5hf{FPl|d_q8_9~y(L;2&Az-3uh(l?vMsM2uVXtopj|yhdt#nJn`avcl`6&R5AQUn6ULoviZ>vcWgWCf_1ke4A|Z9kRoB$u4h@ z2ER>i^F6Z1_sKpth`|rYK|aR@KjnzY%y*yB5jOnpb2>st|2zOVB4dDjLB}*?9FQ;R zxP}w~`HB`bWCD;obV5T)fP76$8ZrsUH*``%rU3btPHD(AAm7nx4VeMtE}hYkG9cg6 zvWCn8a*xhx$Q&R)&^ZmM0CJyJG-Mu-AL+b?ECBL=E@;RiAcu5OLzVz}NS8FE3dj+y zYDf)`V_MUYWk4R$Wer&Ywx@3*EM7VkY{v5 zLpA|2{!@V!XoJm5ew!^wzQ-0N z-)Bpb8*Ezg12!tT$;KrAjEzhFIV(#31*=N_C7Y4_D^`>I4x5ntYql);H*7`nZ&_XP z@7U^Je*f2;Y~N*TY5RM&p0@9?jkNs(+my2RSxNFA*`(wT*p}pnY+Le&Y)A4Vwk!ED zYe@cxl_h`7ZcF}z?MZ&Z_9cJH49S0D2cHV(8{`#z_Bz*i{x6IyjY2%^w3=?4vUt$9 z!;3~fo;YS_cH0eKdF_x10B(J7*vFtT9505#ZUw$4LZ@|ZQ5M>cYq4LO%#G(lFSK3j zz2mwUUOQk3T)MEs<^@W3#Aa;QwXR?_!~)i$7In_fm|(5YI<-YIVkKSEYTBY{2SNA3 zTjy=ZrGa&`SYseAp0m!pPV3BzM?)5bR?`VDa**W|n9Z1xjTW1c%fC|4`1gXm0V;i<%X(h`~Z zuQ&P~1@VeDmtc5_tnkujR?z0$7MJllPLv#%w3X&lFc~^yynlmCc9=?f z?*?f&@XjJi_@=3qcgS5yMTV2h0M}#W)P^IlIg6$f&`4E@N0hfmWz`C@ZZevJ(Nx+r zn(ZL;cr>RF!)MevhaR&Ms22P&A!fabeiLFSUwuQ3c#T z8)k%_JP<-LkG<791o6$JloKqQ^&1gb?KtjUZn%z#MqJqqBCU|4NEC@>~vvrc1 z8I|#(Uj?h_+4Lj(%n4EAzmzH>V!(xh(gX(Kh;SkDnW-mqwC&3=G3&wA)uMxGET+d-#rt(#q=~0%4Vt zOjOqvOF{`|CnL#Dcx*8C8k2)s9d(Qwgi^;rb zng`N7u$XGHAb_ARhH%DVBqK;hk>CSfj3X%mA!9i3g1KO8F@b0a$s~4-V^`1=jvoeM z3K3lJKrSezQEUcD8Obb?IV2S%^GFtuEFxJ#QbkfjvW#Q}3H%QsCsvWHAz4SVfn*a2 z{x?BvBiTW+3nU)u*diVg>>SE2CP?XJr|iWF>@^F?eDZy)F01OOBpoM7#jo%M1@w%V zQayo^t)$42tN|3hcV+I!p7?_-%3mgx!3#J`CA|7Z)vRzxM;A`>J!>7yo2w*hx~%)7|J$kV68_WDKk)j^bG$wsWa5@b$#!zWC7c=yQ(gu^iUI&4}Iq~JoAp#EAOE# zNWBmE7zz!gD=8iN@Ad8XzDT-GsCbMehgx#E|NBIBFFx&*9YsH#z ju>YS{rhV4Rw9l}9txWFb)@Ug|@;`pj%J_SO+&}&cx*9NB literal 0 HcmV?d00001 diff --git a/app/__pycache__/views.cpython-310.pyc b/app/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee5fd88b55d8e2ab1970b4066a82f3b1ccfb54f9 GIT binary patch literal 22610 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 ap31hHj#uK=!$>m*d0Jz^aSM+X<9`EQVUbe+ literal 0 HcmV?d00001 diff --git a/app/__pycache__/views.cpython-311.pyc b/app/__pycache__/views.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0681f8702d1fefaf884f905412cb50267ad0e9a2 GIT binary patch literal 108562 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 z%0A0>ge@Q(1>vh*&dutp3_i|M?qW|Q#M!UyNPq=b^d!F88L-I6M0_ifTQb|A`O&*n zxG)vgt^DF(yX~ZMrjjUhQty!NuMnvmTpUq2!teCSb@Y;T`wlFNgPkq zN)-PP6}|vKq8Ue*wBOHLxLZHt34vec6AKC*!PB%G&==hS1*G8D@~#&dyu`qN-G789 z5a&g3)ptFLY{x}C1#q5F5X?c5-HTMtIjqmm@vAxK`UZ+ziF($TD%Nf12;V@K--Oe8 zu*{XhM}%d?u^gN!PmE6-uHf6;%klpWpXqMIMmGd7E5Q{6<$Cp)l_30rl?k2X6Z(J4 z{)X5e5$u3h=n#`(26+9BasUwr&G`B*WA9?{ZU*BF1cT{etdqe>1f%QQDya&lCM4H~ zSd$Cc?w~YSdjzR#N>h$ba&mn2Ring-TQ4_e${ybbM>4`s6g-)L!~}=S%yK4q>~iN+ z6cN4}qH%R;84M*Iy-cE=GCf?%7Cv-ZH5&BIbYnzjnlNkOtwf&+&+0bi-F1C3VKak^ z#}eYChQRnlHjcV-$a_}c8BEoZxL|+h`Cao(-=O-=rEz00yLR_5S$N|moil%UWTLSsLAX>Fs6s^0_ zbmChq^8!yebak>4$<~@YyO7f9Tx2Bd{UHbXiWmnR`?ELy?nr>ihS-Q?dOWF!LlKkw2Ln5 zqO27Pjc&K5iv=E&soNu!f|S8^R&p-a1JEVTI$XK6-&CZ z>!vb&zJXf?-Wbqwnh#KxP1HRBIXPw4lyN6PdsFUB8Fw5qZpyXkO%~oRAXoo0RX`ew zXwyXa!GUun+Hlwj=tsaE0Pli66}%QRGD`mm$XRHuqo2gD(=8*q0PiS* zcce?k#j6bO9;u2g-askm%O~iC!%^D+4)etX1;dtF1L^ z>uIf15IvfKOIe#gxPK5+>y#hOs_I&&X#@>hkj*SEE$^!bqc0wPgtGy|G4BLRVs3l`%zxjIzfkS>7 zm*)$c+^t1Jo!^i$@Q7&&s#(0x=QagWkjbTW65QbDGfolW<{7z_XZ{>)lzDC+m`&jIw1h5IlQ?$zi*4BZD(<_1DUJiBug+^-;pW^*o2mptnE z{H9=X$+nHnP@~vnO{nl8943C6EVrl@#6saREoeX6vJ(g34Nlbq@V5mLzko(YfJ$j3 z`>I#i(p#}@=lo{#LO#|-2*A7|- zMYR}rG-|RT-F#F?uE1$1cu1;5OQ}31s{a5jYtl^c#+E1kE4=eHQ%je54bVeFv@|g!Cu=^G|_;cNq^qxv8+CKB@U_RSzPF2!dsut zpP#Zrv^;@O4rs<$=k*l0!Fw}7<<-%?0A1LQdh=;TpN_*Pbh!205VRYY`xxUMVNy>) zd!6|zliy{~Ld>meOUwx!Ctq9`G9TiNE#N55wl{NTT*6=rgG(7)#^7=WQ3h8qxDtWk zS!dPD2abFC3r4|x(VEmU|2I36jqfVndNqS1c|31p=Pf(k1IYV6>4ASiWT{p`lSYA~O#ps4z0mwc4G0w@)Gm-eSdD?EdMOoy6UzkYHNSl? zhC}D6MXbX?&|R&_u*!E?aH-$E|lOesxlZZOAYjyk}kuc!kI zVagX9MfwE<7QY^N{RZImUDGkOYM~2W0y|KXmK8trf~^l=)|iiCrkEc?unQ>5hI1n|z~hCS*WTPW;dWRAW)A`B zDUS=*1B^J3(teCrv6s~h&akUBjICuLUcA;bb^!yQ0x$=e9%A6*)Qh+oQ~ndUK(kS_ zCIs291E+QsO2~3BU&s4cEr2dWWW+{Sn;jX}hoA z;TpYOZOQg92EPNz4`K%Eyj$9g&2{IjS+w0h1t=B({C&O*ZdTe5OF;2=nG{gm0(*Ow zhrLf=F9|?g0k+rkZNHwuHU>Ot)ZEH|aMs9sPbVD5?JV%V4?XLe6BYRFUJk%bVH>NT z#7KPrr+sh$SWsaNU1_UbyiB9 zRZtHsL9*Wo8LA%RUto-QPjHC}(-{Du0$55}FqTq_U2xmlsYYO22t5F+Bn%~hLCmc+ z0TXpQH8nFaE@ud|z@%U0ocbjOpJO24L4d%cOk%DP2oPMEk4xOhLdSlxMos~aa?aMq z@AVRW-j-e7PM*1K#sFJ^DpG zZjQhkx1L?pyf=^Vv^(@GIPT@(pl#P^0Fpw-u+r{#2j@2HZtEH_oj;A3=3DzJ0|7_e zCQKU02GlD>5-1Q$;8caBUt`b$r@EGhQ$E6TBR|kKey=w$_C^M`GPs$+ZWi3a*d7LB z4Bo_GIe7HD+=oebdhiHv!zHz}zGVqU|J^tp8$=OK1Rwzwc_{+bt^g?&CG?RT4{njn z!nxQlksOM^%cl?1BGClkTJZi<3@2*`{s61~6^G6?IaX`GaXT<7e{OAT=)&Wmory-- ztW3dwgwhn!PJV*(g;_iC5})>A79Gd~W-)hpnDtXpNJBwrP)-~x?o=xRpkOaZpoQ2x?@(Zcay;N1hHu#SQ?c2g~JM+E?v#xH{( zT%Te~SKQjkxP$B_M@wyN&;YQw7Qul}9Shg*$CjD0V3&O)X8xj%17H=gnbNim7K*6z zB=XZz2SyM&E_Jf3bM$s-i9%8ZozigIk#%4+@Li74+|V={JqkUl5_;-921f@bj%0&O zfPEu`)Fh6vlvGAj8%Mtf>ZJ?r3lrk4{F8X9PB@0eQF4$+(6%saJ_JzOO}*BWAvwvr z2l}bqkP5kJNNngH0TP=Yc^{C_NO}NQzMsKqs+>WJv(S(00Iq{p7e@7?t3J@;FPOS&qWHr^Y*jfkc z2oJzHpG6zzHy-nL@69bYn2qjW%-dL(j|Pi)?#RX}z^F2G6+9qVu1}569XgD&eB|^O zqu^H1q$+NhoPLEHoC^8|+tJl;g@Ja5obH}e!_P&_mmU*@PG7Vqz zdJFa$tU}c(Jhf18cI-&ycwJ6Ng2mzZz1ncA1zfhZva%yMP3I20Nu#8n!F@K)HDh?m z(kOF?(~57+d<#E-!F!1v_(KlVK?!c~9yCy*xv>0hkOvCqKt8CEqLzy2t7PT2shOE0 zbF+F$5hxpJeqk2Xjg;FhVooU=+Qi^BMAPO}E?~pEHP-`TqdA{CC2!c|<~h zVN^yDh9@Ap{u8j|?*!`lE(Z21=9EDp{f#KyoU6YeyuyoMu+?N1VX>(}q~6 z@#9>6e&m(5i8d~Oea$PGD8lC4il;blAifXZ_QyUDcL-1BHZ5n)MQWRD$FEMDoG?|x zQ|yvDP75cfRI3=2s&Ue;Ig7J+XFXC5bqFf~cjFG15l)Th#S7XSEYoD3TZR*S;arF0 z9bM7U63X`;pk2Ym0DAx#Np3+AG!A#<(9@uO6XBU0D(aaV}nqVtNZiYFQu-*Z_!S3g8hgpS z8!g(gJ-6=L-}L>d$%7X3_b1IJ-wfY#F$|KCUsAMi@OA0pGXkG(@r5Yxi5T2(MnODd zR-A$xE8r;&$cp2@w4h>tBvii!o*Y7RI3D9DW5im(U#9;X5bALDjVqigEBL+v5e|QB zxMmw5g5k7NENo6i>erCG2bPtg=LRU(GvtBmapFUq4{#lR4UUeAoq&ok+;-YAxJao$ z#-HMql+%7BvSQR(FVEm~N747xLdWAzwJPH}pHyZ7PB6#wXM zDe~`7(My_h7+ljN;s(NvL^hE}5CQV)ZXPt1#I%vK#MUSt)D8cW(^nxU4yCIr-~vhK ztV0gno9u$PLFbg<{|w$V;k<}WmSoX4a0afUm=*pQjsmB3#Oa9GWJEDt;KPefj;d+8 zX0l?qPyD}PdUTEnnqfx{kN=2d>$4BQ$Z@B#NA#Jf?v>pAk*Tq)1T5Z7Lp;q1{j zf|6Z<8-iWBY5)E`>HPnf~zK={RM*^oOZPX5Q0Yp#BfAF zjMAk;_|T_74dCkmD-^*LRj+mXS&rR?&*!h$`*j0_p zmqyIW#Ehxxn@9E?nVf}~e#8!M9*v2jv*COJ10FV%s zG2e<0V*V{-G9KA9WCm@;pj>G38yp~c`|gpVRCWgEOgO!Ee#V?U1f%#VO>MM5m<%C| zR!jO2r^of^D-`#!nn3JFi30Y6a0ZatIvdalUQ}pdQ0bP>#d}Dw^(&) z>n*kcf)dtVDe$Oi)ddw$aTlUbJ`}4i@YW%u1XzlgpT}O5hiwPb?a@bY|euJSxx>%$|77jD( zgH=`*?uU3N8Ow00J1n2X$WXhoCeFkCAE>P_AwO>Zq5C3Gd~` zpt1<>hCruyycR@_PAU%3W)$sZ7kkLbuHwXX)r0$R=oVQX$c1vM-C4Oz6{krCp~&#MjUf|H>}KWYvD zm4hV`SPf7KJr$J}OJEyx;Rl{Gth-KwdC`e>dvLuNSF#_vu_g2}JQM+=VIxPQzaW%G zan?EBRRM@A6VuxDDYuuvNTUhH}?sUaL$O zm78{3ZB93pJFN~|L+Wx-N!_nHVY8*G&^8 z8I)SpRZ{l2lmp5<%+JdZ@KSW6k z(gw}B+N@mXgRtg-<#6CF_|B7j^RlG_js^!z+)b2QOF`w<(~f7N(J%()4_5%>yZDxx zL8bXu$je}aj(TR|<@xg)rRUD5>5cNO@U1Rk@{PiW6R{25{c?P@ocF3Wp4Y2#b%S3- z%g?=xe@%noKuE{PV5m^F{IPgXVc_nEj2t=K`jYq=``odCTU%(hsKlLrhZ^SF(4(+I zwdv#weBFP{;7OJ)Yr@CdMpv05tmLEAo0*(opcs6g!B-fFhXK$1wAK$3OE*EGgx?~# z6{YXzW9b&<2oJKd5R6}C4A1IlX$VTTR-@=-KecX0KHC0amge~i3Ji)2#3He`$>z%= z{0)%~YWl4#9&|-V*;v61swq2ozmd^Z$r>~tKp#fZu{ARS7InJ4CEF4$4~^FSM>12~ ztJtyuk?=h_))g3t(?>nniDUi-_b9<_&L}i*WkyH9Zcaa8e=sNbaC)LN+rkBGJ)4)V zJ-GZD`47Z;zlRT^i6Zj)92fb{wI5tQveMwDDe5UYIuvpcJ5CjcwJ97OJvnA>Vho3S zrQVB)lxVxeB#ak;JEy{HB8f=%O9^lpsl$StXh(PiuAkud1^q(XCGK8X?l?mZQ$@2i zJskG_fQ=JV_y3@x$-f_&4`CW`r8NB`Ex#4NpPT8~t+2Q_28~BguGhnE@$>#|Kn$Ep zE!W$F%^K_jvHWuQkgg*KqTR3FYwG_!i?VOI7G)q!T((6_m=!#XCP`1JKwML_CKIcv zjDmkpdPIfRA=N^Fpi3=US*1V{xU~jQYfx&zb0_V~+SVFItrb!WZV}+cG}jO>rnnY> zB6m1xc!-uXESsdf%Sm^Oa?36{R-iJBpx|A&QUbUNs9hM&3`T%x7p>l)H5L>}dciv^ zQtmeia!zD;58|w>qE)PlMkUVj1-am*21!!fwF^k`km^VKL}PV7Luw8BiOhDOpB0d6 z4og2PwAB}MEr*?cR(SpV0R6!F&FN<)`teiH_LP1`tP!W55vQLKIcGRBdoTJ~4ZAAc z&uXWiZm*x!PCt>Occ7mxtIO$U4f^p@@M?;u8vwD=!BDL`9fg%v(E^!-9E8kK>rY33 z{B~Nv$8e_d*B_(x|l-InY2w4npRz9&||IHUSPC z)`3V~-zZt@8(r0I|Lo#(Yu>l0@py({W3;}ies7?2-iroM7`%|)x+7aydKWEXAD_P zMz;^@!D4rw!C2)zv;LOuXYwkn4!nY8ssxb|sbUQJeK}-+_n`v5<81KI)(GR_18ij)BI6M>CCe98yZe5K4&o+9Go{0S07*N^ZhAZU-y zUp5WaB*YRg!VE=UpN|#JBj@iD7jkS%El^r86|HY&zJ~9{McDJ&uT)fNRAMn6NM>mP4KG2A4GdV z35a6x@J(`Ed3N*;@I@owdg3Y`t#(*&h6gbpPS~qLG#7AGm%&|8@o0rpe9Z&kgeJtJ zRj!;z>oB87i#*5z+NS2ixW9-vPqm3a_(zlOR28STh@-j^c#}>EIGV_Z_o*J9QUjSy z(&6EJ6ayE(9>HTPd(BT^(wo1-z$gB`!m2{|{k;9jrQ7b4+t~d_-0_K<*=3z-e1}tI z1a;k$sU0^O@b8FaMJ)qN{2ZqJ{JK~8(vBkF5}$GHbOyF@a3>g$lGmnDw=?z*2CEqe zc`Bfy-7NnwX8E@{bV`1j+_JKyiE%(x&?J7_@v9%ktD$TN*oer8aE&-=vh}HBAZ&fO zQoEm%0HVJe6fk}22H*-|AjE{2f^yW{oeGZBqy+4FDY*zG8QgPBWu20&Q-XsWot&J` zae9M(nJQp<|7DYQ0<`6TCl?*f1z$m(nhUVw50pW&4G9zv7~)|;I7En=3ph0(Eq)>( zj(ixWtVmo0lA@HJ)Mp<^F0>o44B&$8w3Oonun@!t#P;)o?NfohprGna2WpE&F!iav zo`TYLpbjukQUZeza^@B?z&yc7#Znm>)9zcfY4tID81o(k_6iqbl-oIQ_2H3s{GE9( z?>)|7p26D@h`{vh8$${C?;d+N#VLQC^FwgupTYool3GM)+zd@F5j$DAcVcQzK{(GW!I^{+BrcD3F^?=E2x_MoC#S~f(8sUT zJ@qs@>*j#Ht6#g%Yo5V&IQh{s=oI#=QU^E&&*7cNiqpZ$b^uD5D<9=!XqF? zgy3VYI!v-B$qd8H$v!7QrYDMkfC}E!QfoDO2Wu6m^?_(xYyBvC(c5c#wY4@mS|3y` zT3fvqY(>QT{r%V8XYX_7Oh~ZU-p{AW=lo~wwbovHz1RQ$U;l@;i89oAiS->>pybRo zsF;=Y16<14$(t6b&t2{;pM73VrS1!JhM%28pQcBHt-zco z*{zbsWO_`A;PMf$J!~qlcd|p3`yN$)&OiUJm7AZW2d0fpGlAkTiwn!O?;YN;ozgHoG zyx5$Xyb5O}Y!4RK#0G?M*a_Ks?8Z%rSS0$koQDk935~iUIg29j3pY3(h?zgH8y#xCOj zwi0ZOyiFmaI4idf|96z|c7b;YRIhqFX!kLTstnE!Ejh8Bz|P6T`a-P@;1PY`Iie5I z=FwFXUofukyY%I^>MNByhW~CQ{11Vsr8g?y8wBnUsIh$*mA4$Bmb}jOI@=#io+H>N zB-b%_kLaq}Bb-=cV29pJP75WGCyN$-GyOG|xkE!9I4(5AI%ZxpWSN?FY&7IPx@D0X zIR_0<%KTf~xfDG|mkv?3+Irhw#&qeNFW*)V7imLHrM3%m*Iyo)o(^_5_OS9lg{g%@ zd?a4PYBDVQ8t%`wbMD`T&_*^toE{^Ui0r6ZN*H&UNDrkY%28j3m{@uuZC>+?%y^(7X#Wn_J!&0# ztr+3MQ3MxO?f&R^eryDMVayN|$DV1PzmKed?09|zu|q`g_EKII$Hjku!L1s9|1X$9 zuU406@~BIs8Jn%2Sy0t2PKIkc?&$7P$!`>RlR(v=*?hZ92~}(E{rb4!`ub$78a75o z*8Uz@u2NlEct1e+6F8(u`%0PV+gm8)@@H?@kUxFBKbjx)4vhNiamg{94WEWPW-dE@ z?56zASLS!@+j_(PoANX3uD*Qg+81B+g0p5OUpkySbL;lqXPuJ2dit8Zn|5u#c-yYa zUb^=c{*_ZZt~l+&{grOvA_yyn7-UwPrxBbRKy_^Ov&zI{ijyBu}l)~%OZbIr($E_r1v@|sJw zUVX_9MGm*^&zXR!L|P>Z+Eae>qHDLlh)mlreDNhi$x?d!1{5eA7xP1NCs+yDGb;z7 z;mL6@((5(Ai|AAFbb_m)r!$!_oFVN0G3Cs^v0lu(&wXPxC+P_6FeWXf-m8OobYU*{ zoHttky=wOF3%qY`2l$%!x2Vzl)z-Sa_BW4fi#?kXYHUBL{GejRJFyKH?A1102*-&A z2{*e9*T0`CAmMi=rBv^;OZ?Hi+v6jAt~;fa6HJ$o`2A-u#ySQl@OB8`)dv z!u?lirlZh3+ap|-+zVb_x9?l2I<7r>4}7(rt)5LE>R@ESD~aD&HLIyY47wna-*e;M8C07(LS2rH9kJFA8}EC*JysMl!5zFGkMP8@t5!@qlC}Q8csc z1fNjFTWX!){)1F}I7yYAG`)$TH)<0y5v5X_1@WFWHkF5N4>GZpBI_q#I5WhD%JQ=* z{S1NQn$q$a&jjZV65UbZ2u!;x^cTTU7P52~n6ep>r~Y2Ap#bmazPgD+0P}qv;9L-)$?BOmy z*nH(n9bOBg7n{}#=bhH>togJ}@csM8y;53mb1AuZ?B?p3x|1=8rmO!MUh*Fiu=Vp< zg=)>u+j$KxObrav=BEUlHRZ>=5lu(`QOZHcdTJaa%obypHJ?}MUl6D@AB6?IPxEmN z--_mAQ~lEVwaiP+%@df5A$rzcjh1hEnV{foBez%2Nl#_CdmQ2}EQHaPa6QS%WY zFC`2|$k!m%ORMK{`bKUVFYE;=i`V`U4ecOb68CQ|?cS3ZFuQN?_5Mzkm1(hHsQ_?zqma%BDlkAp!2iFtewi|a7(y#RL2wS+QR7gWLcP}z;`M( zUv2Ci{MuE4ffi_C$H~$yQz+CEVhQ0TK*;gihy*xFVtV67L_csh?A{HXGbw+Xadc0iKS1# z&Fhw?0aEu|GMK|*E*g;N$HV~N>Y|6lGhAdmL&RBV!=vyFG08?hM-GQE7Xa2oZd7gLvj(qE9BTCMW=<}|k#)j<3LJK!x14=&#lb~|lQb{w0%)PQ#6{=wpMxj04uY+3Mx8Fs7T!0eE>0WFoag;VfFQ!j|h za25@VdbB4J!E;;rd7ZbSBHcY#q|=_$(a%^>T>89~eG;a?hdj)XTfH$pPCd`CdSQe- zsJEWmWR%>V!+KXfSEL8^UWwW8ArCX=&qJTA3JjyK&~EX@y5dRZ^=SLS)y3898jQoi zlZz)GO6PxaD827U@#MR-e>eC`@2V@FELCC*sh@LS;!p-*zH{u2@OjWXr?1ZC^3Fat z2$BEXApe#ifB1Y=EdRN&{O1Mvb3y*_`IcDz^J4kW5Ax3j`NQWA$MT;a%YQ+T|4Tvs z@cCP@{1?RXQ*YYakgE&whtD0c{9Cxk$`)6v_2@{^Z{CGwZhoch$ZLwLtdAcG`dH@a z)yEC_mmO-@cW&|I;u`um>)%>jQ_;r_xkB(w*T)UH+x1PCOMP6<@A|YM_ue3X`227z zKYd)z@A|YM_mv=j`23w%e)_na-}PxWmkRQS&pomH^l>@A>(gv*bC5rLzBrbjJ}&2X zeVWaALH_W$5X-MVo}{ldOI?3tbN2@MU3;_T_Ph3Ea}QV5_j6VC`AXIIzT=(aU39oX z^3Mh$sM&ZzYV*A_OE z�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 highest_score and score > 70: + highest_score = score + best_match = item['name'] + + return best_match if highest_score > 0 else None + + +def get_province_id(province_name): + for i in iranprovince: + if i['name'] == province_name: + return i['id'] + return 0 + + +def find_best_match_for_city(input_text, province_name): + input_norm = normalize_text(input_text) + best_match = None + highest_score = 0 + province_id = get_province_id(province_name) + + city = [city for city in irancity if int(city['province_id']) == int(province_id)] + + for item in city: + score = fuzz.ratio(input_norm, normalize_text(item['name'])) + if score > highest_score and score > 70: + highest_score = score + best_match = item['name'] + + return best_match if highest_score > 0 else None + + +def correct_province(input_text): + province_match = find_best_match_for_province(input_text) + if province_match: + return province_match + + return input_text + + +def correct_city(input_text, province_name): + province_match = find_best_match_for_city(input_text, province_name) + if province_match: + return province_match + + return input_text + +# امل درمیان خرمبید دشتستان قائنات گناوه اسلام آباد +# corrupted_text = "کهگیلویه و بویراحمد" +# corrected = correct_province(corrupted_text) +# print(f"ورودی: {corrupted_text} -> خروجی: {corrected}") + + +# #تست شهر +# province_name = "کهگیلویه و بویراحمد" +# corrupted_text = "دنا" +# corrected = correct_city(corrupted_text,province_name) +# print(f"ورودی: {corrupted_text} -> خروجی: {corrected}") diff --git a/app/excel_processing.py b/app/excel_processing.py new file mode 100644 index 0000000..7502e76 --- /dev/null +++ b/app/excel_processing.py @@ -0,0 +1,2574 @@ +# import datetime +import datetime +from io import BytesIO + +import openpyxl +import requests +from django.db.models import Sum, Count, Q, F +from django.http import HttpResponse +from django.views.decorators.csrf import csrf_exempt +from openpyxl import Workbook +from openpyxl.styles import Alignment +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import AllowAny + +from app.filtersets import TransportingDetailFilterSet, KillHouseFilterSet, HatchingsFilterSet, GuildsFilterSet, \ + TransportCarcassDetailFilterSet, AllProductsTransportFilterSet +from app.helper_excel import create_header, create_header_freez, shamsi_date, excel_description, create_value +from app.models import TransportingDetail, KillHouse, Hatching, TransportCarcassDetail, Guilds, AllProductsTransport +from app.serializers import TransportingDetailSerializer, HatchingDetailSerializer, \ + StewardForTransportCarcassSerializer, KillHouseForTransportCarcassSerializer, TransportCarcassDetailSerializer, \ + GuildsForTransportCarcassSerializer, AllProductsTransportSerializer +from helpers import build_query +from app.helper import get_hatching_permit_code + +def transporting_detail_excel(request): + filterset_class = TransportingDetailFilterSet + filters = {} + PartIdCode = request.GET['PartIdCode'] + RequestCode = request.GET.get('RequestCode') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + city = request.GET.get('city') + province = request.GET.get('province') + if province == 'undefined': + province = None + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + if city: + filters['City__icontains'] = city + + if province: + filters['Province__icontains'] = province + + if RequestCode: + filters['hatching__RequestCode'] = RequestCode + + search = request.GET.get('search') + value = request.GET.get('value') + transports = TransportingDetail.objects.filter(**filters, DesPartIdCode=PartIdCode).order_by("-Date") + + if search: + if search != 'undefined' and search.strip(): + transports = transports.filter( + build_query(filterset_class.Meta.fields, value) + ) + + serializer = TransportingDetailSerializer(transports, many=True).data + + excel_options = [ + 'ردیف', + 'کد رهگیری قرنطینه', + 'تاریخ کشتار', + 'نام کشتارگاه', + 'شناسه یکتا کشتارگاه', + 'استان کشتارگاه', + 'شهر کشتارگاه', + 'تعداد', + 'وضعیت', + 'مقصد کشتار', + 'نام مرغدار', + 'شناسه یکتا مرغداری', + 'شناسه جوجه ریزی', + 'استان مرغدار', + 'شهرستان مرغدار', + 'سن کشتار', + 'نژاد', + + ] + + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + from_date_1 = shamsi_date(date1) + to_date_1 = shamsi_date(date2) + worksheet['A3'] = f'از تاریخ:({from_date_1}) تا تاریخ:({to_date_1})' + if serializer: + name = serializer[1]['DesUnitName'] + else: + name = '' + excel_description(worksheet, 'A5', f'گزارش اطلاعات بار استان کشتارگاه {name}', color='red', row2='C5') + + header_list2 = [ + 'تعداد بار', + 'حجم بار', + 'میانگین سن کشتار', + 'میانگین سن کشتار', + 'تعداد بار داخل استان', + 'حجم بار داخل استان', + 'درصد داخل استان', + 'تعداد بار خارج استان', + 'حجم بار خارج استان', + 'درصد خارج استان', + + ] + create_header(worksheet, header_list2, 5, 2, height=20.8, border_style='thin') + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + l = 5 + m = 1 + if serializer: + for data in serializer: + date = datetime.datetime.strptime(str(data['Date']), '%Y-%m-%dT%H:%M:%SZ') + destination = 'داخل استان' if data['Out'] == False else 'خارج استان' + list1 = [ + m, + data.get('TrackingCode', '-'), + str(shamsi_date(date, in_value=True)), + data.get('DesUnitName', '-'), + data.get('DesPartIdCode', '-'), + data.get('Province', '-'), + data.get('City', '-'), + data.get('GoodAmount', '-'), + data.get('TrackingStatusDescription', '-'), + destination, + data.get('SourceUnitName', '-'), + (data['hatching'] or {}).get('hatching', {}).get('PartIdCode', '-'), + (data['hatching'] or {}).get('hatching', {}).get('RequestCode', '-'), + (data['hatching'] or {}).get('hatching', {}).get('poultry', {}).get('Province', '-'), + (data['hatching'] or {}).get('hatching', {}).get('poultry', {}).get('City', '-'), + (data['hatching'] or {}).get('Age', '-'), + (data['hatching'] or {}).get('hatching', {}).get('PedigreeName', '-'), + + ] + m += 1 + + l += 1 + create_value(worksheet, list1, l + 1, 1) + header_data = requests.get( + f'https://rsibackend.rasadyar.com/app/transporting-dashboard/?search=&value={value}&province={province}&PartIdCode={PartIdCode}').json() + if header_data: + value_header_list2 = [ + header_data['bar_count'], + header_data['bar_quantity'], + header_data['input_bar_count'], + int(header_data['total_bar_killing_age']), + header_data['input_bar_count'], + header_data['input_bar_quantity'], + str(header_data['input_bar_percent']), + header_data['output_bar'], + header_data['output_bar_quantity'], + str(header_data['output_bar_percent']), + + ] + + create_value(worksheet, value_header_list2, 3, 5, border_style='thin') + total_quantity = sum( + item['GoodAmount'] for item in serializer) + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + '', + total_quantity, + '', + '', + '', + '', + '', + '', + '', + '', + '', + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + + response[ + 'Content-Disposition'] = f'attachment; filename="گزارش اطلاعات بار کشتارگاه.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def total_killhouse_excel(request): + filterset_class = KillHouseFilterSet + search = request.GET.get('search') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + filters = {"trash": False} + if province := request.GET.get('province'): + filters['Province'] = province + + if city := request.GET.get('city'): + filters['City'] = city + + if kill_houses_name := request.GET.get('name'): + filters['UnitName'] = kill_houses_name + + kill_houses = KillHouse.objects.filter(**filters).order_by('id') + + if search: + if search != 'undefined' and search.strip(): + kill_houses = kill_houses.filter( + build_query(filterset_class.Meta.fields, search) + ) + + excel_options = [ + 'ردیف', + 'نام کشتارگاه', + 'شناسه یکتا کشتارگاه', + 'استان', + 'شهرستان', + 'تعداد بار', + 'حجم بار', + 'تعداد بار داخل استان', + 'حجم بار داخل استان', + 'درصد بار داخل استان', + 'تعداد بار خارج استان', + 'حجم بار خارج استان', + 'درصد بار خارج استان', + + ] + + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + from_date_1 = shamsi_date(date1) + to_date_1 = shamsi_date(date2) + worksheet['A3'] = f'از تاریخ:({from_date_1}) تا تاریخ:({to_date_1})' + excel_description(worksheet, 'A5', f'پایش کشتارگاه ها', color='red', row2='C5') + + header_list2 = [ + 'تعداد کشتارگاه ها', + 'تعداد بار', + 'حجم بار', + 'تعداد بار داخل استان', + 'حجم بار داخل استان', + 'درصد بار داخل استان', + 'تعداد بار خارج استان', + 'حجم بار خارج استان', + 'درصد بار خارج استان', + + ] + create_header(worksheet, header_list2, 5, 2, height=20.8, border_style='thin') + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + l = 5 + m = 1 + if kill_houses: + part_id_codes = kill_houses.values_list('PartIdCode', flat=True) + all_bars = TransportingDetail.objects.filter(DesPartIdCode__in=part_id_codes,trash=False).only('Out', "GoodAmount") + + all_products_transport = AllProductsTransport.objects.filter( + jihadi_destination__in=part_id_codes, + trash=False, + product='مرغ زنده -جهت كشتار' + ).only('out', 'quantity') + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + all_bars = all_bars.filter(Date__date__gte=date1, Date__date__lte=date2) + all_products_transport = all_products_transport.filter( + Q( + date__gte=date1, + date__lte=date2, + date__isnull=False + ) | + Q( + unloading_date__gte=date1, + unloading_date__lte=date2, + date__isnull=True + ) + ) + + for kill_house in kill_houses: + bars = all_bars.filter(DesPartIdCode=kill_house.PartIdCode, trash=False).only('GoodAmount', + 'Out') + + aggregation_bars = bars.aggregate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id') + ) + + all_products_for_killhouse = all_products_transport.filter(jihadi_destination=kill_house.PartIdCode) + aggregation_all_products = all_products_for_killhouse.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id') + ) + + total_count = (aggregation_bars['total_count'] or 0) + (aggregation_all_products['total_count'] or 0) + total_bars_quantity = (aggregation_bars['total'] or 0) + (aggregation_all_products['total'] or 0) + total_input_bars_quantity = (aggregation_bars['input_total'] or 0) + (aggregation_all_products['input_total'] or 0) + total_output_bars_quantity = (aggregation_bars['output_total'] or 0) + (aggregation_all_products['output_total'] or 0) + input_bars_count = (aggregation_bars['input_count'] or 0) + (aggregation_all_products['input_count'] or 0) + output_bars_count = (aggregation_bars['output_count'] or 0) + (aggregation_all_products['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 + + list1 = [ + m, + kill_house.UnitName, + kill_house.PartIdCode, + kill_house.Province, + kill_house.City, + total_count, + total_bars_quantity, + input_bars_count, + total_input_bars_quantity, + total_input_bars_percent, + output_bars_count, + total_output_bars_quantity, + total_output_bars_percent, + + ] + m += 1 + + l += 1 + create_value(worksheet, list1, l + 1, 1) + + aggregation1_bars = all_bars.aggregate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id') + ) + + aggregation1_all_products = all_products_transport.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id') + ) + + total_count = (aggregation1_bars['total_count'] or 0) + (aggregation1_all_products['total_count'] or 0) + total_bars_quantity = (aggregation1_bars['total'] or 0) + (aggregation1_all_products['total'] or 0) + total_input_bars_quantity = (aggregation1_bars['input_total'] or 0) + (aggregation1_all_products['input_total'] or 0) + total_output_bars_quantity = (aggregation1_bars['output_total'] or 0) + (aggregation1_all_products['output_total'] or 0) + input_bars_count = (aggregation1_bars['input_count'] or 0) + (aggregation1_all_products['input_count'] or 0) + output_bars_count = (aggregation1_bars['output_count'] or 0) + (aggregation1_all_products['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 + value_header_list2 = [ + kill_houses.count(), + total_count, + total_bars_quantity, + input_bars_count, + total_input_bars_quantity, + total_input_bars_percent, + output_bars_count, + total_output_bars_quantity, + total_output_bars_percent, + + ] + + create_value(worksheet, value_header_list2, 3, 5, border_style='thin') + + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + total_count, + total_bars_quantity, + input_bars_count, + total_input_bars_quantity, + total_input_bars_percent, + output_bars_count, + total_output_bars_quantity, + total_output_bars_percent, + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + + response[ + 'Content-Disposition'] = f'attachment; filename="پایش کشتارگاه ها.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def hatching_excel(request): + filterset_class = HatchingsFilterSet + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'فعال', + 'بایگانی' + ] + header_list = [ + 'تعداد دوره جوجه ریزی', + 'حجم کل جوجه ریزی', + 'تلفات', + 'کشتار شده', + 'میانگین سن کشتار', + 'تعداد بار ها', + 'تعداد جوجه ریزی فعال', + 'حجم جوجه ریزی فعال', + 'کمترین سن', + 'بیشترین سن', + 'مانده در سالن', + ] + + excel_options = [ + 'ردیف', + 'استان', + 'شهرستان', + 'نام واحد', + + 'نام مالک', + 'شماره مجوز', + 'شماره گواهی بهداشتی', + 'ظرفیت', + 'تاریخ جوجه ریزی', + 'سن گله', + 'تعداد جوجه ریزی', + 'دوره جوجه ریزی', + 'مجموع تلفات', + 'درصد جوجه ریزی به مجوز', + 'مانده در سالن', + 'میانگین سن کشتار', + 'تعداد بارها', + 'حجم بارها', + + ] + filters = {} + system_code = request.GET.get('system_code') + city = request.GET.get('city') + province = request.GET.get('province') + age = request.GET.get('age') + killing_age = request.GET.get('killing_age') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + + if killing_age: + filters['KillingAve'] = int(killing_age) + + if age: + filters['Age__exact'] = age + if city: + filters['CityName__icontains'] = city + if province: + filters['ProvinceName__icontains'] = province + hatchings = Hatching.objects.filter(**filters, SystemCode=system_code) + + # hatchings = hatchings.filter(Age__gt=70) + + header = requests.get(f'https://rsibackend.rasadyar.com/app/hatchings-dashboard/?system_code={system_code}').json() + value_header_list = [ + header.get('total_hatching_count', ""), # تعداد دوره جوجه ریزی + header.get('total_hatching_quantity', ""), # حجم کل جوجه ریزی + header.get('total_hatching_evacuation', ""), # تلفات + header.get('total_hatching_killing_quantity', ""), # کشتار شده + header.get('total_hatching_killing_age', ""), # میانگین سن کشتار + header.get('total_hatching_bars', ""), # تعداد بار ها + header.get('total_active_hatching_count', ""), # تعداد جوجه ریزی فعال + header.get('total_active_hatching_quantity', ""), # حجم جوجه ریزی فعال + header.get('least_age', ""), # کمترین سن + header.get('most_age', ""), # بیشترین سن + header.get('total_hatching_left_over', "") # مانده در سالن + ] + + for sheet_name in sheet_list: + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'فعال': + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + hatchings_active = hatchings.filter(Age__lte=70) + serializer = HatchingDetailSerializer(hatchings_active, many=True).data + if serializer: + name = serializer[0]['poultry']['UnitName'] + else: + name = '' + excel_description(worksheet, 'A1', f'پایش فارم فعال {name}', size=11, color='red', row2='C1') + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + + l = 7 + + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + + for data in serializer: + poultry = data.get('poultry', {}) + info = data.get('info', {}) + date = datetime.datetime.strptime(str(data['Date']), '%Y-%m-%dT%H:%M:%SZ') + list1 = [ + m, # ردیف + poultry.get('Province', ''), # استان + poultry.get('City', ''), # شهرستان + poultry.get('UnitName', ''), # نام واحد + f"{poultry.get('FirstName', '')} {poultry.get('LastName', '')}".strip(), # نام مالک + data.get('RequestCode', ''), # شماره مجوز + data.get('CertId', ''), # شماره گواهی بهداشتی + data.get('CapacityFemale', ''), # ظرفیت + str(shamsi_date(date, in_value=True)), + data.get('Age', ''), # سن گله + data.get('ChickCountSum', ''), # تعداد جوجه ریزی + data.get('Period', ''), # دوره جوجه ریزی + data.get('Evacuation', ''), # مجموع تلفات + info.get('percent_hatching_license', ''), # درصد جوجه ریزی به مجوز + data.get('LeftOver', ''), # مانده در سالن + info.get('average_slaughter_age', ''), # میانگین سن کشتار + info.get('number_loads', ''), # تعداد بارها + info.get('load_volume', ''), # حجم بارها + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + if serializer: + total_capacity = sum(item.get('CapacityFemale', 0) for item in serializer) + + total_chick_count = sum(item.get('ChickCountSum', 0) for item in serializer) + + total_evacuation = sum(item.get('Evacuation', 0) for item in serializer) + + total_left_over = sum(item.get('LeftOver', 0) for item in serializer) + + total_load_volume = sum(item.get('info', {}).get('load_volume', 0) for item in serializer) + + total_number_loads = sum(item.get('info', {}).get('number_loads', 0) for item in serializer) + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + '', + total_capacity, + '', + '', + total_chick_count, + '', + total_evacuation, + '', + total_left_over, + '', + total_number_loads, + total_load_volume, + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + else: + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + hatchings1 = hatchings.filter(Age__gte=70) + serializer1 = HatchingDetailSerializer(hatchings1, many=True).data + if serializer1: + name = serializer1[0]['poultry']['UnitName'] + else: + name = '' + excel_description(worksheet, 'A1', f'پایش فارم بایگانی {name}', size=11, color='red', row2='C1') + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + + l = 7 + + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + + for data in serializer1: + poultry = data.get('poultry', {}) + info = data.get('info', {}) + + date = datetime.datetime.strptime(str(data['Date']), '%Y-%m-%dT%H:%M:%SZ') + list1 = [ + m, # ردیف + poultry.get('Province', ''), # استان + poultry.get('City', ''), # شهرستان + poultry.get('UnitName', ''), # نام واحد + f"{poultry.get('FirstName', '')} {poultry.get('LastName', '')}".strip(), # نام مالک + data.get('RequestCode', ''), # شماره مجوز + data.get('CertId', ''), # شماره گواهی بهداشتی + data.get('CapacityFemale', ''), # ظرفیت + str(shamsi_date(date, in_value=True)), + data.get('Age', ''), # سن گله + data.get('ChickCountSum', ''), # تعداد جوجه ریزی + data.get('Period', ''), # دوره جوجه ریزی + data.get('Evacuation', ''), # مجموع تلفات + info.get('percent_hatching_license', ''), # درصد جوجه ریزی به مجوز + data.get('LeftOver', ''), # مانده در سالن + info.get('average_slaughter_age', ''), # میانگین سن کشتار + info.get('number_loads', ''), # تعداد بارها + info.get('load_volume', ''), # حجم بارها + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + if serializer1: + total_capacity = sum(item.get('CapacityFemale', 0) for item in serializer1) + + total_chick_count = sum(item.get('ChickCountSum', 0) for item in serializer1) + + total_evacuation = sum(item.get('Evacuation', 0) for item in serializer1) + + total_left_over = sum(item.get('LeftOver', 0) for item in serializer1) + + total_load_volume = sum(item.get('info', {}).get('load_volume', 0) for item in serializer1) + + total_number_loads = sum(item.get('info', {}).get('number_loads', 0) for item in serializer1) + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + '', + total_capacity, + '', + '', + total_chick_count, + '', + total_evacuation, + '', + total_left_over, + '', + total_number_loads, + total_load_volume, + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="پایش جوجه ریزی.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def all_hatching_excel(request): + filterset_class = HatchingsFilterSet + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'فعال', + 'بایگانی' + ] + header_list = [ + "تعداد دوره جوجه ریزی", + "حجم کل جوجه ریزی", + "تلفات", + "درصد تلفات", + "کشتار شده", + "درصد کشتار شده", + "میانگین سن کشتار", + "تعداد بارها", + "کمترین سن", + "بیشترین سن", + "مانده در سالن", + "درصد مانده در سالن نسبت به جوجه ریزی" + ] + + header_list2 = [ + "تعداد دوره جوجه ریزی", + "حجم کل جوجه ریزی", + "تلفات", + "درصد تلفات", + "کشتار شده", + "درصد کشتار شده", + "میانگین سن کشتار", + "تعداد بارها", + "حجم جوجه ریزی فعال", + "کمترین سن", + "بیشترین سن", + "مانده در سالن", + "درصد مانده در سالن", + "مانده در سالن آماده به کشتار", + "درصد مانده در سالن آماده به کشتار", + ] + + excel_options = [ + 'ردیف', + 'استان', + 'شهرستان', + 'نام واحد', + + 'نام مالک', + 'شماره مجوز', + 'شماره گواهی بهداشتی', + 'ظرفیت', + 'تاریخ جوجه ریزی', + 'سن گله', + 'تعداد جوجه ریزی', + 'دوره جوجه ریزی', + 'مجموع تلفات', + 'درصد جوجه ریزی به مجوز', + 'مانده در سالن', + 'میانگین سن کشتار', + 'تعداد بارها', + 'حجم بارها', + + ] + filters = {} + city = request.GET.get('city') + province = request.GET.get('province') + age = request.GET.get('age') + killing_age = request.GET.get('killing_age') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + filter_and_search='?' + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + filter_and_search+=f'date1={date1}&date2={date2}' + + if killing_age: + filters['KillingAve'] = int(killing_age) + + if age: + filters['Age__exact'] = age + if city: + filters['CityName__icontains'] = city + if province: + filters['ProvinceName__icontains'] = province + filter_and_search+=f'&province={province}' + hatchings = Hatching.objects.filter(**filters) + + # hatchings = hatchings.filter(Age__gt=70) + + header = requests.get(f'https://rsibackend.rasadyar.com/app/hatchings-dashboard/{filter_and_search}').json() + value_header_list = [ + header.get('total_hatching_count', 0), + header.get('total_hatching_quantity', 0), + header.get('total_hatching_evacuation', 0), + header.get('total_hatching_evacuation', 0), + header.get('total_hatching_killing_quantity', 0), + header.get('total_hatching_evacuation_percent', 0), + header.get('total_hatching_killing_age', 0), + header.get('total_hatching_bars', 0), + header.get('least_age', 0), + header.get('most_age', 0), + header.get('total_hatching_left_over', 0), + header.get('total_hatching_left_over_percent', 0), + ] + + value_header_list2 = [ + header.get('total_active_hatching_count', 0), + header.get('total_hatching_quantity', 0), + header.get('total_active_hatching_evacuation', 0), + header.get('total_active_hatching_evacuation_percent', 0), + header.get('total_active_hatching_killing_quantity', 0), + header.get('total_active_hatching_killing_quantity_percent', 0), + header.get('total_active_hatching_killing_age', 0), + header.get('total_active_hatching_bars', 0), + header.get('total_active_hatching_quantity', 0), + header.get('least_age', 0), + header.get('most_age', 0), + header.get('total_active_hatching_left_over', 0), + header.get('total_active_hatching_left_over_percent', 0), + header.get('total_ready_active_hatching_left_over', 0), + header.get('total_ready_hatching_left_over_percent', 0), + ] + + for sheet_name in sheet_list: + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'فعال': + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + + create_header(worksheet, header_list2, 4, 5, height=25, width=25, border_style='thin', color='C00000') + + hatchings_active = hatchings.filter(Age__lte=70) + serializer = HatchingDetailSerializer(hatchings_active, many=True).data + if date1: + info = 'از تاریخ {0} تا تاریخ {1}'.format(shamsi_date(date1), shamsi_date(date2)) + else: + info = '' + excel_description(worksheet, 'A1', f'پایش فارم فعال {info}', size=11, color='red', row2='C2') + excel_description(worksheet, 'E1', f'خلاصه اطلاعات کل جوجه ریزی ها', size=11, color='red', row2='G1') + excel_description(worksheet, 'E4', f'خلاصه اطلاعات جوجه ریزی های فعال', size=11, color='red', row2='G4') + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 8, 9, 20) + + l = 9 + + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + create_value(worksheet, value_header_list2, 6, 4, border_style='thin') + + for data in serializer: + poultry = data.get('poultry') or {} + info = data.get('info') or {} + date = datetime.datetime.strptime(str(data['Date']), '%Y-%m-%dT%H:%M:%SZ') + list1 = [ + m, + poultry.get('Province') or '', + poultry.get('City') or '', + poultry.get('UnitName') or '', + f"{poultry.get('FirstName') or ''} {poultry.get('LastName') or ''}".strip(), + data.get('RequestCode') or '', + data.get('CertId') or '', + data.get('CapacityFemale') or '', + str(shamsi_date(date, in_value=True)), + data.get('Age') or '', + data.get('ChickCountSum') or '', + data.get('Period') or '', + data.get('Evacuation') or '', + info.get('percent_hatching_license') or '', + data.get('LeftOver') or '', + info.get('average_slaughter_age') or '', + info.get('number_loads') or '', + info.get('load_volume') or '', + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + if serializer: + total_capacity = sum(item.get('CapacityFemale', 0) for item in serializer) + + total_chick_count = sum(item.get('ChickCountSum', 0) for item in serializer) + + total_evacuation = sum(item.get('Evacuation', 0) for item in serializer) + + total_left_over = sum(item.get('LeftOver', 0) for item in serializer) + + total_load_volume = sum(item.get('info', {}).get('load_volume', 0) for item in serializer) + + total_number_loads = sum(item.get('info', {}).get('number_loads', 0) for item in serializer) + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + '', + total_capacity, + '', + '', + total_chick_count, + '', + total_evacuation, + '', + total_left_over, + '', + total_number_loads, + total_load_volume, + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + else: + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + + hatchings1 = hatchings.filter(Age__gte=70) + serializer1 = HatchingDetailSerializer(hatchings1, many=True).data + if date1: + info = 'از تاریخ {0} تا تاریخ {1}'.format(shamsi_date(date1), shamsi_date(date2)) + else: + info = '' + excel_description(worksheet, 'A1', f'پایش فارم بایگانی {info}', size=11, color='red', row2='C2') + excel_description(worksheet, 'E1', f'خلاصه اطلاعات کل جوجه ریزی ها', size=11, color='red', row2='G1') + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + + l = 7 + + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + + for data in serializer1: + poultry = data.get('poultry') or {} + info = data.get('info') or {} + + date = datetime.datetime.strptime(str(data['Date']), '%Y-%m-%dT%H:%M:%SZ') + list1 = [ + m, + poultry.get('Province') or '', + poultry.get('City') or '', + poultry.get('UnitName') or '', + f"{poultry.get('FirstName') or ''} {poultry.get('LastName') or ''}".strip(), + data.get('RequestCode') or '', + data.get('CertId') or '', + data.get('CapacityFemale') or '', + str(shamsi_date(date, in_value=True)), + data.get('Age') or '', + data.get('ChickCountSum') or '', + data.get('Period') or '', + data.get('Evacuation') or '', + info.get('percent_hatching_license') or '', + data.get('LeftOver') or '', + info.get('average_slaughter_age') or '', + info.get('number_loads') or '', + info.get('load_volume') or '', + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + if serializer1: + total_capacity = sum(item.get('CapacityFemale', 0) for item in serializer1) + + total_chick_count = sum(item.get('ChickCountSum', 0) for item in serializer1) + + total_evacuation = sum(item.get('Evacuation', 0) for item in serializer1) + + total_left_over = sum(item.get('LeftOver', 0) for item in serializer1) + + total_load_volume = sum(item.get('info', {}).get('load_volume', 0) for item in serializer1) + + total_number_loads = sum(item.get('info', {}).get('number_loads', 0) for item in serializer1) + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + '', + total_capacity, + '', + '', + total_chick_count, + '', + total_evacuation, + '', + total_left_over, + '', + total_number_loads, + total_load_volume, + + ] + create_value(worksheet, list2, l + 3, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="پایش جوجه ریزی ها.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def all_send_different_bar_excel(request): + filterset_class = TransportingDetailFilterSet + filters = {} + PartIdCode = request.GET.get('PartIdCode') + RequestCode = request.GET.get('RequestCode') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + city = request.GET.get('city') + province = request.GET.get('province') + if province == 'undefined': + province = None + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + if city: + filters['City__icontains'] = city + + if province: + filters['hatching__poultry__Province__icontains'] = province + + if PartIdCode: + filters['DesPartIdCode'] = PartIdCode + + if RequestCode: + filters['hatching__RequestCode'] = RequestCode + + search = request.GET.get('search') + transports = TransportingDetail.objects.filter(**filters, trash=False).order_by("-Date") + + query_all_products = AllProductsTransport.objects.filter( + trash=False, + product='مرغ زنده -جهت كشتار' + ) + + + 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( + build_query(filterset_class.Meta.fields, search) + ) + query_all_products = query_all_products.filter( + build_query(AllProductsTransportFilterSet.Meta.fields, search) + ) + + ser_data_transports = TransportingDetailSerializer(transports, many=True).data + + all_products_list = list(query_all_products) + ser_data_all_products = [] + for obj in all_products_list: + serializer = AllProductsTransportSerializer(obj) + data = serializer.data + date_value = obj.date if obj.date else obj.unloading_date + if date_value: + data['Date'] = datetime.datetime.combine(date_value, datetime.time.min) if isinstance(date_value, datetime.date) else date_value + else: + data['Date'] = None + data['DesPartIdCode'] = obj.jihadi_destination + data['TrackingCode'] = obj.tracking + data['GoodAmount'] = obj.quantity + data['DesUnitName'] = obj.destination + data['Province'] = obj.destination_province + data['City'] = obj.destination_city + data['Out'] = obj.out + if hasattr(obj, 'hatching') and obj.hatching: + data['hatching'] = { + 'poultry': { + 'UnitName': getattr(obj.hatching.poultry, 'UnitName', '') if hasattr(obj.hatching, 'poultry') and obj.hatching.poultry else '', + 'PartIdCode': getattr(obj.hatching.poultry, 'PartIdCode', '') if hasattr(obj.hatching, 'poultry') and obj.hatching.poultry else '', + 'Mobile': getattr(obj.hatching.poultry, 'Mobile', '') if hasattr(obj.hatching, 'poultry') and obj.hatching.poultry else '', + 'City': getattr(obj.hatching.poultry, 'City', '') if hasattr(obj.hatching, 'poultry') and obj.hatching.poultry else '', + }, + 'RequestCode': getattr(obj.hatching, 'RequestCode', '') if obj.hatching else '', + } + else: + data['hatching'] = { + 'poultry': { + 'UnitName': '', + 'PartIdCode': '', + 'Mobile': '', + 'City': '', + }, + 'RequestCode': '', + } + data['TrackingStatusDescription'] = '' + data['Age'] = '' + ser_data_all_products.append(data) + + def get_sort_date(data): + if data.get('Date'): + if isinstance(data['Date'], datetime.datetime): + return data['Date'].date() + elif isinstance(data['Date'], datetime.date): + return data['Date'] + return datetime.date.min + + combined_data = [] + for data in ser_data_transports: + combined_data.append((get_sort_date(data), data)) + for data in ser_data_all_products: + combined_data.append((get_sort_date(data), data)) + + combined_data.sort(key=lambda x: x[0], reverse=True) + ser_data = [data for _, data in combined_data] + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'بار های داخل استان', + 'بار های خارج استان' + ] + + for sheet_name in sheet_list: + + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'بار های داخل استان': + + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + header_list = [ + 'تعداد مرغداران', + 'تعداد کشتارگاه ها', + 'حجم کشتار', + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + + value_header_list = [ + + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + + excel_options = [ + 'ردیف', + 'تاریخ کشتار', + 'مرغدار', + 'شناسه یکتا مرغدار', + 'شماره مجوز جوجه ریزی', + 'شماره موبایل مرغدار', + 'شهر مرغدار', + 'دامپزشک فارم', + 'تلفن دامپزشک فارم', + 'کد قرنطینه', + 'وضعیت بار', + 'کشتارگاه', + 'شناسه یکتا کشتارگاه', + 'استان', + 'شهر', + 'حجم کشتار', + 'سن کشتار', + + ] + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + + l = 7 + unique_poultry_out_false = set() + unique_slaughterhouses_out_false = set() + total_slaughter_out_false = 0 + excel_description(worksheet, 'A1', f'بارهای داخل استان', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in ser_data: + if data['Out'] == False: + vet_farm_mobile = '' + vet_farm_name = '' + + unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) + unique_slaughterhouses_out_false.add(data['DesUnitName']) + total_slaughter_out_false += data['GoodAmount'] + if data['Date']: + date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ + date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() + else: + date = datetime.date.today() + list1 = [ + m, + str(shamsi_date(date, in_value=True)), + data['hatching']['poultry']['UnitName'], + data['hatching']['poultry']['PartIdCode'], + data['hatching']['RequestCode'], + data['hatching']['poultry']['Mobile'], + data['hatching']['poultry']['City'], + vet_farm_name, + vet_farm_mobile, + data['TrackingCode'], + data['TrackingStatusDescription'], + data['DesUnitName'], + data['DesPartIdCode'], + data['Province'], + data['City'], + data['GoodAmount'], + data['Age'], + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + value_header_list = [ + len(unique_poultry_out_false), + len(unique_slaughterhouses_out_false), + total_slaughter_out_false + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + quantity = sum( + data['GoodAmount'] for data in ser_data if data['Out'] == False) or 0 + list2 = [ + 'مجموع==>', + '', + '', + '', + + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + quantity, + '', + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + else: + unique_poultry_out_false = set() + unique_slaughterhouses_out_false = set() + total_slaughter_out_false = 0 + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + header_list = [ + 'تعداد مرغداران', + 'تعداد کشتارگاه ها', + 'حجم کشتار', + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + + excel_options = [ + 'ردیف', + 'تاریخ کشتار', + 'مرغدار', + 'شناسه یکتا مرغدار', + 'شماره مجوز جوجه ریزی', + 'شماره موبایل مرغدار', + 'شهر مرغدار', + 'دامپزشک فارم', + 'تلفن دامپزشک فارم', + 'کد قرنطینه', + 'وضعیت بار', + 'کشتارگاه', + 'شناسه یکتا کشتارگاه', + 'استان', + 'شهر', + 'حجم کشتار', + 'سن کشتار', + + ] + + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + + l = 7 + unique_poultry = set() + unique_slaughterhouses = set() + total_slaughter = 0 + excel_description(worksheet, 'A1', f'بارهای خارج استان', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in ser_data: + if data['Out'] == True: + vet_farm_mobile = '' + vet_farm_name = '' + + + unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) + unique_slaughterhouses_out_false.add(data['DesUnitName']) + total_slaughter_out_false += data['GoodAmount'] + if data['Date']: + date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ + date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() + else: + date = datetime.date.today() + list1 = [ + m, + str(shamsi_date(date, in_value=True)), + data['hatching']['poultry']['UnitName'], + data['hatching']['poultry']['PartIdCode'], + data['hatching']['RequestCode'], + data['hatching']['poultry']['Mobile'], + data['hatching']['poultry']['City'], + vet_farm_mobile, + vet_farm_name, + data['TrackingCode'], + data['TrackingStatusDescription'], + data['DesUnitName'], + data['DesPartIdCode'], + data['Province'], + data['City'], + data['GoodAmount'], + data['Age'], + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + value_header_list = [ + len(unique_poultry_out_false), + len(unique_slaughterhouses_out_false), + total_slaughter_out_false + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + quantity = sum( + data['GoodAmount'] for data in ser_data if data['Out'] == True) or 0 + list2 = [ + 'مجموع==>', + '', + '', + '', + + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + quantity, + '', + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="اطلاعات کلی بار ها.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def transport_carcass_detail_excel(request): + search = request.GET.get('search') + + type_role = request.GET.get('role') + province = request.GET.get('province') + + if province == 'undefined': + province = None + len_kill_house = 0 + if type_role == 'KillHouse': + filters_kill_house = {} + if province: + filters_kill_house['Province'] = province + + kill_house_filterset_class = KillHouseFilterSet + kill_house = KillHouse.objects.filter(**filters_kill_house).order_by('id') + len_kill_house = len(kill_house) + if search and search != 'undefined' and search.strip(): + kill_house = kill_house.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + bars = TransportCarcassDetail.objects.filter(trash=False).order_by('-product_date') + buy_bars = TransportingDetail.objects.filter(trash=False, Date__date__gte='2025-03-21') + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + date_1_for_buy_bars = date1 - datetime.timedelta(days=1) + date_2_for_buy_bars = date2 - datetime.timedelta(days=1) + buy_bars = buy_bars.filter(Date__date__gte=date_1_for_buy_bars, Date__date__lte=date_2_for_buy_bars) + + bars_summary = bars.values('jihadi_origin').annotate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + buy_summary = buy_bars.values('DesPartIdCode').annotate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id'), + ) + + bars_dict = {row['jihadi_origin']: row for row in bars_summary} + buy_dict = {row['DesPartIdCode']: row for row in buy_summary} + kill_house = list(kill_house) + kill_house.sort( + key=lambda kh: (bars_dict.get(kh.PartIdCode, {}) or {}).get('total', 0) or 0, + reverse=True + ) + + serializer = KillHouseForTransportCarcassSerializer( + kill_house, many=True, context={'request': request, 'bars_dict': bars_dict, 'buy_dict': buy_dict} + ).data + + if 'code' in request.GET: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.insert_rows(1) + worksheet.sheet_view.rightToLeft = True + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + excel_options = [ + 'ردیف', + "تاریخ توزیع", + "تاریخ ثبت", + "نوع بار", + "محصول", + "وزن", + "کد قرنطینه", + "خریدار", + "استان خریدار", + "شهر خریدار", + "راننده", + "مالک", + "رهگیری خودرو", + "پلاک خودرو", + "وضعیت", + + ] + date1 = request.GET.get('date1') + filters = {} + 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() + filters['product_date__gte'] = date1 + filters['product_date__lte'] = date2 + query = TransportCarcassDetail.objects.filter(**filters, jihadi_origin=request.GET.get('code'), + trash=False).order_by('-product_date') + if search: + if search != 'undefined' and search.strip(): + query = query.filter( + build_query(TransportCarcassDetailFilterSet.Meta.fields, search) + ) + + serializer = TransportCarcassDetailSerializer(query, many=True).data + + header_list = [ + "تعداد بار ها", + "مجموع وزن ها", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + name = '-' + if query: + name = query.first().origin + l = 7 + + excel_description(worksheet, 'A1', f'توزیع / فروش گوشت {name}', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in serializer: + date = datetime.datetime.strptime(str(data.get('date')), + '%Y-%m-%d').date() + list1 = [ + m, + str(shamsi_date(data.get('product_date', '-') or '-', in_value=True) if data.get('product_date', + '-') else '-'), + str(shamsi_date(date, in_value=True)), + "داخل استان" if data.get('out', '-') == False else "خارج استان", + data.get('product', '-') or '-', + data.get('quantity', 0) or 0, + data.get('tracking', '-') or '-', + data.get('destination', '-') or '-', + data.get('destination_province', '-') or '-', + data.get('destination_city', '-') or '-', + data.get('driver_name', '-') or '-', + data.get('owner', '-') or '-', + data.get('car_tracking_code', '-') or '-', + data.get('plate', '-') or '-', + data.get('unloading', '-') if data.get('unloading', '-') else "در انتظار تخلیه", + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + quantity = sum(item.get('quantity', 0) for item in serializer) + + value_header_list = [ + query.count(), + quantity + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + quantity, + "", + "", + "", + "", + "", + "", + "", + "", + "", + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="توزیع / فروش گوشت مرغ.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + else: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'توزیع و فروش گوشت مرغ' + ] + excel_options = [ + 'ردیف', + "نقش", + "نام واحد", + "شناسه یکتا", + "استان", + "شهرستان", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل انبار", + "وزن کل توزیع", + "درصد توزیع نسبت به انبار", + "تعداد توزیع داخل استان", + "وزن توزیع داخل استان", + "درصد توزیع داخل استان", + "وزن توزیع خارج استان", + "درصد توزیع خارج استان", + + ] + + for sheet_name in sheet_list: + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'توزیع و فروش گوشت مرغ': + + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + header_list = [ + "نقش", + "تعداد", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل انبار", + "وزن کل توزیع", + "درصد توزیع نسبت به انبار", + "تعداد توزیع داخل استان", + "وزن توزیع داخل استان", + "درصد توزیع داخل استان", + "وزن توزیع خارج استان", + "درصد توزیع خارج استان", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', + color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + l = 7 + excel_description(worksheet, 'A1', f'توزیع / فروش گوشت مرغ', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', + row2='C3') + for data in serializer: + weight = 0 + if (data.get('info', {}).get('total_ware_house', 0) or 0) > 0: + weight = round(((data.get('info', {}).get('total_bars_wight', 0) or 0) / + (data.get('info', {}).get('total_ware_house', 0) or 0)) * 100, 1) or 0 + list1 = [ + m, + data.get('info', {}).get('role', '-') or '-', + data.get('UnitName', '-') or '-', + data.get('PartIdCode', '-') or '-', + data.get('Province', '-') or '-', + data.get('City', '-') or '-', + "گوشت مرغ زنده", + data.get('info', {}).get('total_input_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_input_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_ware_house', 0) or 0, + data.get('info', {}).get('total_bars_wight', 0) or 0, + weight, + data.get('info', {}).get('input_bars', 0) or 0, + data.get('info', {}).get('total_input_bars_wight', 0) or 0, + data.get('info', {}).get('total_input_bars_percent', 0) or 0, + data.get('info', {}).get('total_output_bars_wight', 0) or 0, + data.get('info', {}).get('total_output_bars_percent', 0) or 0, + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + total_input_buy_count = sum(item.get('total_input_buy_bars_count', 0) for item in serializer) + total_input_buy_weight = sum(item.get('total_input_buy_bars_wight', 0) for item in serializer) + total_output_buy_count = sum(item.get('total_output_buy_bars_count', 0) for item in serializer) + total_output_buy_weight = sum(item.get('total_output_buy_bars_wight', 0) for item in serializer) + total_warehouse = sum(item.get('total_ware_house', 0) for item in serializer) + total_bars_weight = sum(item.get('total_bars_wight', 0) for item in serializer) + total_input_count = sum(item.get('input_bars', 0) for item in serializer) + total_input_weight = sum(item.get('total_input_bars_wight', 0) for item in serializer) + total_input_percent = sum(item.get('total_input_bars_percent', 0) for item in serializer) + total_output_weight = sum(item.get('total_output_bars_wight', 0) for item in serializer) + total_output_percent = sum(item.get('total_output_bars_percent', 0) for item in serializer) + + percent_distributed = round( + (total_bars_weight / total_warehouse) * 100, + 1 + ) if total_warehouse else 0 + + value_header_list = [ + "کشتارگاه" if type_role == "KillHouse" else "مباشر", + "گوشت مرغ زنده", + len_kill_house, + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + total_bars_weight, + percent_distributed, + total_input_count, + total_input_weight, + total_input_percent, + total_output_weight, + total_output_percent, + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + total_bars_weight, + percent_distributed, + total_input_count, + total_input_weight, + total_input_percent, + total_output_weight, + total_output_percent, + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="توزیع / فروش گوشت مرغ.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + else: + filters_steward = {} + if province: + filters_steward['province'] = province + + steward_filterset_class = GuildsFilterSet + steward = Guilds.objects.filter(**filters_steward, trash=False, is_steward=True).order_by('id') + len_kill_house = len(steward) + if search and search != 'undefined' and search.strip(): + steward = steward.filter( + build_query(steward_filterset_class.Meta.fields, search) + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + bars = TransportCarcassDetail.objects.filter(trash=False).order_by('-product_date') + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + + bars_summary = bars.values('jihadi_origin', 'jihadi_destination').annotate( + total=Sum('quantity', filter=Q(jihadi_origin=F('jihadi_origin'))), + input_total=Sum('quantity', filter=Q(out=False, jihadi_origin=F('jihadi_origin'))), + output_total=Sum('quantity', filter=Q(out=True, jihadi_origin=F('jihadi_origin'))), + input_count=Count('id', filter=Q(out=False, jihadi_origin=F('jihadi_origin'))), + output_count=Count('id', filter=Q(out=True, jihadi_origin=F('jihadi_origin'))), + total_count=Count('id', filter=Q(jihadi_origin=F('jihadi_origin'))), + + total_input_buy_bars_wight=Sum('quantity', + filter=Q(out=False, jihadi_destination=F('jihadi_destination'))), + total_input_buy_bars_count=Count('id', + filter=Q(out=False, jihadi_destination=F('jihadi_destination'))), + total_output_buy_bars_wight=Sum('quantity', + filter=Q(out=True, jihadi_destination=F('jihadi_destination'))), + total_output_buy_bars_count=Count('id', + filter=Q(out=True, jihadi_destination=F('jihadi_destination'))), + ) + + bars_dict = {} + for row in bars_summary: + code = row['jihadi_origin'] or row['jihadi_destination'] + if code: + bars_dict[code] = row + + steward = list(steward) + steward.sort( + key=lambda s: (bars_dict.get(s.jihadi_code, {}) or {}).get('total', 0) or 0, + reverse=True + ) + + serializer = StewardForTransportCarcassSerializer( + steward, many=True, context={'request': request, 'bars_dict': bars_dict} + ).data + if 'code' in request.GET: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.insert_rows(1) + worksheet.sheet_view.rightToLeft = True + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + excel_options = [ + 'ردیف', + "تاریخ توزیع", + "تاریخ ثبت", + "نوع بار", + "محصول", + "وزن", + "کد قرنطینه", + "خریدار", + "استان خریدار", + "شهر خریدار", + "راننده", + "مالک", + "رهگیری خودرو", + "پلاک خودرو", + "وضعیت", + + ] + date1 = request.GET.get('date1') + filters = {} + 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() + filters['product_date__gte'] = date1 + filters['product_date__lte'] = date2 + query = TransportCarcassDetail.objects.filter(**filters, jihadi_origin=request.GET.get('code'), + trash=False).order_by('-product_date') + if search: + if search != 'undefined' and search.strip(): + query = query.filter( + build_query(TransportCarcassDetailFilterSet.Meta.fields, search) + ) + + serializer = TransportCarcassDetailSerializer(query, many=True).data + + header_list = [ + "تعداد بار ها", + "مجموع وزن ها", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + name = '-' + if query: + name = query.first().destination + l = 7 + + excel_description(worksheet, 'A1', f'توزیع / فروش گوشت {name}', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in serializer: + if data.get('product_date', '-'): + if type(data.get('product_date', '-')) == str: + product_date1 = datetime.datetime.strptime(str(data.get('product_date')), + '%Y-%m-%d').date() + product_date = str(shamsi_date(product_date1)) + else: + product_date = str(shamsi_date(data.get('product_date', '-'))) + else: + product_date = '-' + date = datetime.datetime.strptime(str(data.get('date')), + '%Y-%m-%d').date() + list1 = [ + m, + str(product_date), + str(shamsi_date(date, in_value=True)), + "داخل استان" if data.get('out', '-') == False else "خارج استان", + data.get('product', '-') or '-', + data.get('quantity', 0) or 0, + data.get('tracking', '-') or '-', + data.get('destination', '-') or '-', + data.get('destination_province', '-') or '-', + data.get('destination_city', '-') or '-', + data.get('driver_name', '-') or '-', + data.get('owner', '-') or '-', + data.get('car_tracking_code', '-') or '-', + data.get('plate', '-') or '-', + data.get('unloading', '-') if data.get('unloading', '-') else "در انتظار تخلیه", + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + quantity = sum(item.get('quantity', 0) for item in serializer) + + value_header_list = [ + query.count(), + quantity + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + quantity, + "", + "", + "", + "", + "", + "", + "", + "", + "", + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="توزیع / فروش گوشت مرغ.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + else: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'توزیع و فروش گوشت مرغ' + ] + excel_options = [ + 'ردیف', + "نقش", + "نام واحد", + "شناسه یکتا", + "استان", + "شهرستان", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل انبار", + "وزن کل توزیع", + "درصد توزیع نسبت به انبار", + "تعداد توزیع داخل استان", + "وزن توزیع داخل استان", + "درصد توزیع داخل استان", + "وزن توزیع خارج استان", + "درصد توزیع خارج استان", + + ] + + for sheet_name in sheet_list: + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'توزیع و فروش گوشت مرغ': + + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + header_list = [ + "نقش", + "تعداد", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل انبار", + "وزن کل توزیع", + "درصد توزیع نسبت به انبار", + "تعداد توزیع داخل استان", + "وزن توزیع داخل استان", + "درصد توزیع داخل استان", + "وزن توزیع خارج استان", + "درصد توزیع خارج استان", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', + color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + l = 7 + excel_description(worksheet, 'A1', f'توزیع / فروش گوشت مرغ', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', + row2='C3') + for data in serializer: + weight = 0 + if (data.get('info', {}).get('total_ware_house', 0) or 0) > 0: + weight = round(((data.get('info', {}).get('total_bars_wight', 0) or 0) / + (data.get('info', {}).get('total_ware_house', 0) or 0)) * 100, 1) or 0 + list1 = [ + m, + "مباشر", + data.get('name', '-') or '-', + data.get('jihadi_code', '-') or '-', + data.get('province', '-') or '-', + data.get('city', '-') or '-', + "گوشت مرغ زنده", + data.get('info', {}).get('total_input_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_input_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_ware_house', 0) or 0, + data.get('info', {}).get('total_bars_wight', 0) or 0, + weight, + data.get('info', {}).get('input_bars', 0) or 0, + data.get('info', {}).get('total_input_bars_wight', 0) or 0, + data.get('info', {}).get('total_input_bars_percent', 0) or 0, + data.get('info', {}).get('total_output_bars_wight', 0) or 0, + data.get('info', {}).get('total_output_bars_percent', 0) or 0, + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + total_input_buy_count = sum(item.get('total_input_buy_bars_count', 0) for item in serializer) + total_input_buy_weight = sum(item.get('total_input_buy_bars_wight', 0) for item in serializer) + total_output_buy_count = sum(item.get('total_output_buy_bars_count', 0) for item in serializer) + total_output_buy_weight = sum(item.get('total_output_buy_bars_wight', 0) for item in serializer) + total_warehouse = sum(item.get('total_ware_house', 0) for item in serializer) + total_bars_weight = sum(item.get('total_bars_wight', 0) for item in serializer) + total_input_count = sum(item.get('input_bars', 0) for item in serializer) + total_input_weight = sum(item.get('total_input_bars_wight', 0) for item in serializer) + total_input_percent = sum(item.get('total_input_bars_percent', 0) for item in serializer) + total_output_weight = sum(item.get('total_output_bars_wight', 0) for item in serializer) + total_output_percent = sum(item.get('total_output_bars_percent', 0) for item in serializer) + + percent_distributed = round( + (total_bars_weight / total_warehouse) * 100, + 1 + ) if total_warehouse else 0 + + value_header_list = [ + "کشتارگاه" if type_role == "KillHouse" else "مباشر", + "گوشت مرغ زنده", + len_kill_house, + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + total_bars_weight, + percent_distributed, + total_input_count, + total_input_weight, + total_input_percent, + total_output_weight, + total_output_percent, + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + total_bars_weight, + percent_distributed, + total_input_count, + total_input_weight, + total_input_percent, + total_output_weight, + total_output_percent, + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="توزیع / فروش گوشت مرغ.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +def guilds_transport_carcass_detail_excel(request): + search = request.GET.get('search') + province = request.GET.get('province') + if province == 'undefined': + province = None + + + if 'code' in request.GET: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.insert_rows(1) + worksheet.sheet_view.rightToLeft = True + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + excel_options = [ + "ردیف", + "تاریخ توزیع", + "تاریخ ثبت", + "نوع بار", + "محصول", + "وزن", + "کد قرنطینه", + "فروشنده", + "استان فروشنده", + "شهر فروشنده", + "راننده", + "مالک", + "رهگیری خودرو", + "پلاک خودرو", + "وضعیت", + ] + date1 = request.GET.get('date1') + filters = {} + 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() + filters['product_date__gte'] = date1 + filters['product_date__lte'] = date2 + + query = TransportCarcassDetail.objects.filter( + **filters, + jihadi_destination=request.GET.get('code'), + trash=False + ).order_by('-product_date') + if search and search != 'undefined' and search.strip(): + query = query.filter(build_query(TransportCarcassDetailFilterSet.Meta.fields, search)) + + serializer = TransportCarcassDetailSerializer(query, many=True).data + + header_list = [ + "تعداد بار ها", + "مجموع وزن ها", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + name = '-' + if query: + name = query.first().origin + l = 7 + + excel_description(worksheet, 'A1', f'توزیع / فروش گوشت {name}', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in serializer: + if data.get('product_date', '-'): + if type(data.get('product_date', '-')) == str: + product_date1 = datetime.datetime.strptime(str(data.get('product_date')), + '%Y-%m-%d').date() + product_date= str(shamsi_date(product_date1)) + else : + product_date= str(shamsi_date(data.get('product_date', '-'))) + else: + product_date='-' + date=datetime.datetime.strptime(str(data.get('date')), + '%Y-%m-%d').date() + list1 = [ + m, + str(product_date), + str(shamsi_date(date, in_value=True)), + "داخل استان" if data.get('out', '-') == False else "خارج استان", + data.get('product', '-') or '-', + data.get('quantity', 0) or 0, + data.get('tracking', '-') or '-', + data.get('origin', '-') or '-', + data.get('origin_province', '-') or '-', + data.get('origin_city', '-') or '-', + data.get('driver_name', '-') or '-', + data.get('owner', '-') or '-', + data.get('car_tracking_code', '-') or '-', + data.get('plate', '-') or '-', + data.get('unloading', '-') if data.get('unloading', '-') else "در انتظار تخلیه", + + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + quantity = sum(item.get('quantity', 0) for item in serializer) + + value_header_list = [ + query.count(), + quantity + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + quantity, + "", + "", + "", + "", + "", + "", + "", + "", + "", + + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="توزیع / فروش گوشت مرغ.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + else: + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + workbook.remove(worksheet) + sheet_list = [ + 'خرید صنوف' + ] + excel_options = [ + "ردیف", + "نقش", + "نام واحد", + "شناسه یکتا", + "استان", + "شهرستان", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل خرید", + "درصد خرید داخل استان", + "درصد خرید خارج استان", + ] + + for sheet_name in sheet_list: + worksheet = workbook.create_sheet(sheet_name) + if sheet_name == 'خرید صنوف': + filters_steward = {} + if province: + filters_steward['province'] = province + + steward = Guilds.objects.filter(**filters_steward, trash=False, is_steward=False).order_by('id') + steward_filterset_class = GuildsFilterSet + if search and search != 'undefined' and search.strip(): + steward = steward.filter(build_query(steward_filterset_class.Meta.fields, search)) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + bars = TransportCarcassDetail.objects.filter(trash=False).order_by('-product_date') + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + + bars_summary = bars.values('jihadi_destination').annotate( + total_input_buy_bars_wight=Sum('quantity', filter=Q(out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(out=True)), + total_ware_house=Sum('quantity'), + total_count=Count('id'), + total_count_input_buy=Count('id', filter=Q(out=False)), + total_count_output_buy=Count('id', filter=Q(out=True)), + ) + + bars_dict = {row['jihadi_destination']: row for row in bars_summary} + steward = list(steward) + steward.sort( + key=lambda st: (bars_dict.get(st.jihadi_code, {}) or {}).get('total_ware_house', 0) or 0, + reverse=True + ) + + serializer = GuildsForTransportCarcassSerializer(steward, many=True, + context={'request': request, 'bars_dict': bars_dict}) + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + cell = worksheet.cell(row=1, column=1) + cell.alignment = Alignment(horizontal='center', vertical='center') + + header_list = [ + "نقش", + "تعداد", + "محصول", + "تعداد خرید داخل استان", + "وزن خرید داخل استان", + "تعداد خرید خارج استان", + "وزن خرید خارج استان", + "وزن کل خرید", + + ] + create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') + m = 1 + + create_header_freez(worksheet, excel_options, 1, 6, 7, 20) + l = 7 + excel_description(worksheet, 'A1', f'خرید صنوف', color='red', + row2='B1') + + if 'date1' in request.GET: + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + from_date1 = shamsi_date(date1) + from_date2 = shamsi_date(date2) + excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') + for data in serializer: + + list1 = [ + m, + "صنف", + data.get('name', '-') or '-', + data.get('jihadi_code', '-') or '-', + data.get('province', '-') or '-', + data.get('city', '-') or '-', + "گوشت مرغ تازه", + data.get('info', {}).get('total_input_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_input_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_count', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_wight', 0) or 0, + data.get('info', {}).get('total_ware_house', 0) or 0, + data.get('info', {}).get('total_input_buy_bars_percent', 0) or 0, + data.get('info', {}).get('total_output_buy_bars_percent', 0) or 0, + + + ] + create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) + + l += 1 + m += 1 + total_input_buy_count = sum(item.get('total_input_buy_bars_count', 0) for item in serializer) + total_input_buy_weight = sum(item.get('total_input_buy_bars_wight', 0) for item in serializer) + total_output_buy_count = sum(item.get('total_output_buy_bars_count', 0) for item in serializer) + total_output_buy_weight = sum(item.get('total_output_buy_bars_wight', 0) for item in serializer) + total_warehouse = sum(item.get('total_ware_house', 0) for item in serializer) + + + + + value_header_list = [ + "صنف", + "گوشت مرغ تازه", + len(steward), + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + + ] + create_value(worksheet, value_header_list, 3, 4, border_style='thin') + list2 = [ + 'مجموع==>', + '', + '', + '', + '', + '', + total_input_buy_count, + total_input_buy_weight, + total_output_buy_count, + total_output_buy_weight, + total_warehouse, + "", + "", + + + ] + + create_value(worksheet, list2, l + 1, 1, color='green') + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="خرید صنوف.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def import_transporting_detail(request): + file = request.FILES['file'].read() + wb_obj = openpyxl.load_workbook(filename=BytesIO(file)) + sheet = wb_obj.active + created_count = 0 + + for i, row in enumerate(sheet.iter_rows(values_only=True)): + # ردیف اول هدر است، رد می‌کنیم + if i < 1 or row is None: + continue + + # ستون‌ها بر اساس ترتیب در فایل اکسل + tracking_code = row[4] + issue_date = row[5] + product_name = row[7] + good_code = row[8] + good_amount = row[9] + province = row[14] + city = row[15] + des_unit_name = row[16] + source_cert_id = row[17] + des_cert_id = row[18] + takhlie_date = row[28] + + if not tracking_code: + continue # اگر کد رهگیری ندارد، رد شود + + exists = TransportingDetail.objects.filter(TrackingCode=tracking_code).exists() + if not exists: + new_obj = TransportingDetail( + TrackingCode=tracking_code, + IssueDatePersian=issue_date, + GoodName=product_name, + GoodCode=good_code, + GoodAmount=good_amount, + Province=province, + City=city, + DesUnitName=des_unit_name, + SourceCertId=source_cert_id, + DesPartIdCode=des_cert_id, + TakhlieDatePersian=takhlie_date, + ) + + new_obj.save() + kill_house = KillHouse.objects.filter(PartIdCode=new_obj.DesPartIdCode, trash=False).first() + # Resolve hatching by fetching permit code from quarantine page via tracking code + try: + permit_map = get_hatching_permit_code(tracking_code) + permit_code = permit_map.get(str(tracking_code)) + if permit_code: + hatching = Hatching.objects.filter(RequestCode=permit_code, trash=False).first() + if hatching: + new_obj.hatching = hatching + except Exception: + pass + if kill_house: + new_obj.Province = kill_house.Province + new_obj.City = kill_house.City + try: + if new_obj.hatching and new_obj.hatching.poultry and \ + new_obj.hatching.poultry.LocationIdProvince != kill_house.ProvinceId: + new_obj.Out = True + except Exception: + pass + new_obj.save() + created_count += 1 + + return HttpResponse(f"{created_count} رکورد جدید اضافه شد ✅") \ No newline at end of file diff --git a/app/filtersets.py b/app/filtersets.py new file mode 100644 index 0000000..22fcf12 --- /dev/null +++ b/app/filtersets.py @@ -0,0 +1,332 @@ +import datetime + +from django_filters import rest_framework as filters + +from app.models import Poultry, PoultryHatching, TransportingChickenDetail, Hatching, TransportingDetail, KillHouse, \ + TransportCarcassDetail, Driver, Guilds, AllProductsTransport + + +class PoultryFilterSet(filters.FilterSet): + class Meta: + model = Poultry + fields = [ + 'UserName', + 'FirstName', + 'LastName', + 'UnitName', + 'PartIdCode', + 'UnitId', + 'LocationIdProvince', + 'LocationIdCity' + ] + + +class PoultryHatchingFilterSet(filters.FilterSet): + class Meta: + model = PoultryHatching + fields = [ + 'DesCertId', + 'RequestCode', + 'Mobile', + 'PartIdCode', + 'EpidemiologicCode', + 'LocationNameProvince', + 'LocationNameCity', + 'poultry__UserName', + 'poultry__FirstName', + 'poultry__LastName', + 'poultry__UnitName', + 'poultry__PartIdCode', + 'poultry__UnitId', + 'LocationIdProvince', + 'LocationIdCity', + 'LocationNameCity', + ] + + +class HatchingsFilterSet(filters.FilterSet): + class Meta: + model = Hatching + fields = [ + 'UnitName', + 'ProvinceName', + 'CityName', + 'PartIdCode', + 'RequestCode', + 'poultry__UserName', + 'poultry__FirstName', + 'poultry__LastName', + 'poultry__UnitName', + 'poultry__PartIdCode', + 'poultry__UnitId', + ] + + +class TransportingChickenDetailFilterSet(filters.FilterSet): + class Meta: + model = TransportingChickenDetail + fields = [ + 'DesUnitName', + 'DesPartIdCode', + 'SourceUnitPartIdCode', + 'SourceUnitName', + 'SourceCertId', + 'hatching__DesCertId', + 'hatching__LocationNameProvince', + 'hatching__LocationNameCity', + 'hatching__poultry__UserName', + 'hatching__poultry__FirstName', + 'hatching__poultry__LastName', + 'hatching__poultry__UnitName', + 'hatching__poultry__PartIdCode', + 'hatching__poultry__UnitId', + 'hatching__poultry__LocationIdProvince', + 'hatching__poultry__LocationIdCity' + ] + + +class HatchingFilterSet(filters.FilterSet): + class Meta: + model = PoultryHatching + fields = [ + 'LocationNameCity', + 'LocationNameProvince', + 'HatchingAge', + ] + + +class PoultryInfoFilterSet(filters.FilterSet): + class Meta: + model = Poultry + fields = [ + 'LocationNameProvince', + 'Province', + 'LocationNameCity', + 'City', + 'FirstName', + 'LastName', + 'Mobile', + 'SystemCode', + 'EpidemiologicCode', + 'PartIdCode', + 'UnitName', + ] + + +class HatchingCalculationsFilterSet(filters.FilterSet): + class Meta: + model = PoultryHatching + fields = [ + + 'LocationNameProvince', + 'LocationNameCity', + ] + + +class TransportingDetailFilterSet(filters.FilterSet): + class Meta: + model = TransportingDetail + fields = [ + + 'TrackingCode', + 'Province', + 'City', + 'DesPartIdCode', + 'Age', + 'hatching__poultry__FirstName', + 'hatching__poultry__PartIdCode', + 'hatching__RequestCode', + 'hatching__CityName', + 'hatching__ProvinceName', + ] + + +class KillHouseFilterSet(filters.FilterSet): + class Meta: + model = KillHouse + fields = [ + 'PartIdCode', + 'UnitName', + 'Province', + 'City', + 'ProvinceId' + ] + + +class CustomHatchingsFilterSet(filters.FilterSet): + city = filters.CharFilter(field_name='CityName', lookup_expr='icontains') + province = filters.CharFilter(field_name='ProvinceName', lookup_expr='icontains') + system_code = filters.CharFilter(field_name='SystemCode', lookup_expr='exact') + + age = filters.NumberFilter(field_name='Age', lookup_expr='exact') + age__gt = filters.NumberFilter(field_name='Age', lookup_expr='gt') + age__gte = filters.NumberFilter(field_name='Age', lookup_expr='gte') + age__lt = filters.NumberFilter(field_name='Age', lookup_expr='lt') + age__lte = filters.NumberFilter(field_name='Age', lookup_expr='lte') + + killing_age = filters.NumberFilter(field_name='KillingAve', lookup_expr='exact') + killing_age__gt = filters.NumberFilter(field_name='KillingAve', lookup_expr='gt') + killing_age__gte = filters.NumberFilter(field_name='KillingAve', lookup_expr='gte') + killing_age__lt = filters.NumberFilter(field_name='KillingAve', lookup_expr='lt') + killing_age__lte = filters.NumberFilter(field_name='KillingAve', lookup_expr='lte') + + leftover__gt = filters.NumberFilter(field_name='LeftOver', lookup_expr='gt') + leftover__gte = filters.NumberFilter(field_name='LeftOver', lookup_expr='gte') + leftover__lt = filters.NumberFilter(field_name='LeftOver', lookup_expr='lt') + leftover__lte = filters.NumberFilter(field_name='LeftOver', lookup_expr='lte') + leftover__exact = filters.NumberFilter(field_name='LeftOver', lookup_expr='exact') + + date1__date__gte = filters.DateFilter(method='filter_date_range') + date2__date__lte = filters.DateFilter(method='filter_date_range') + state = filters.CharFilter(method='filter_state') + + class Meta: + model = Hatching + fields = [ + 'city', 'province', 'system_code', + 'age', 'age__gt', 'age__gte', 'age__lt', 'age__lte', + 'killing_age', 'killing_age__gt', 'killing_age__gte', 'killing_age__lt', 'killing_age__lte', + 'leftover__gt', 'leftover__gte', 'leftover__lt', 'leftover__lte', 'leftover__exact', + 'date1__date__gte', 'date2__date__lte', 'state' + ] + + def filter_date_range(self, queryset, name, value): + date1 = self.data.get('date1__date__gte') + date2 = self.data.get('date2__date__lte') + if date1 and date2: + try: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + return queryset.filter(Date__date__gte=date1, Date__date__lte=date2) + except ValueError: + return queryset + return queryset + + def filter_state(self, queryset, name, value): + state = self.data.get('state') + if state: + if state == 'pending': + queryset = queryset.filter(Age__lte=70) + else: + queryset = queryset.filter(Age__gt=70) + return queryset + + +class TransportingDetailCustomFilterSet(filters.FilterSet): + unitname = filters.CharFilter(field_name='DesUnitName', lookup_expr='icontains') + province = filters.CharFilter(field_name='Province', lookup_expr='icontains') + city = filters.CharFilter(field_name='City', lookup_expr='icontains') + + code = filters.CharFilter(field_name='DesPartIdCode', lookup_expr='exact') + trackingstatus = filters.CharFilter(field_name='TrackingStatusDescription', lookup_expr='exact') + + quantity__gt = filters.NumberFilter(field_name='GoodAmount', lookup_expr='gt') + quantity__gte = filters.NumberFilter(field_name='GoodAmount', lookup_expr='gte') + quantity__lt = filters.NumberFilter(field_name='GoodAmount', lookup_expr='lt') + quantity__lte = filters.NumberFilter(field_name='GoodAmount', lookup_expr='lte') + + age = filters.NumberFilter(field_name='Age', lookup_expr='exact') + age__gt = filters.NumberFilter(field_name='Age', lookup_expr='gt') + age__gte = filters.NumberFilter(field_name='Age', lookup_expr='gte') + age__lt = filters.NumberFilter(field_name='Age', lookup_expr='lt') + age__lte = filters.NumberFilter(field_name='Age', lookup_expr='lte') + + date1__date__gte = filters.DateFilter(method='filter_date_range') + date2__date__lte = filters.DateFilter(method='filter_date_range') + poultry_unitname = filters.DateFilter(method='filter_poultry_unit_name') + + class Meta: + model = TransportingDetail + fields = [ + 'unitname', + 'province', + 'city', + 'code', + 'trackingstatus', + 'quantity__gt', + 'quantity__gte', + 'quantity__lt', + 'quantity__lte', + 'age', + 'age__gt', + 'age__gte', + 'age__lt', + 'age__lte', + 'date1__date__gte', + 'date2__date__lte', + 'poultry_unitname', + ] + + def filter_date_range(self, queryset, name, value): + date1 = self.data.get('date1__date__gte') + date2 = self.data.get('date2__date__lte') + if date1 and date2: + try: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + return queryset.filter(Date__date__gte=date1, Date__date__lte=date2) + except ValueError: + return queryset + return queryset + + def filter_poultry_unit_name(self, queryset, name, value): + return queryset.filter(poultry__UnitName__icontains=value) + + +class TransportCarcassDetailFilterSet(filters.FilterSet): + class Meta: + model = TransportCarcassDetail + fields = [ + 'tracking', + 'origin_province', + 'origin_city', + 'destination_province', + 'destination_city', + 'product', + 'owner'] + + +class DriverFilterSet(filters.FilterSet): + class Meta: + model = Driver + fields = [ + 'owner_name', + 'driver_name', + 'city', + 'province', + ] + + +class GuildsFilterSet(filters.FilterSet): + class Meta: + model = Guilds + fields = [ + 'name', + 'province', + 'city', + 'jihadi_code' + ] + + +class AllProductsTransportFilterSet(filters.FilterSet): + + class Meta: + model = AllProductsTransport + fields = [ + 'record_id', + 'tracking', + 'product', + 'items', + 'origin_province', + 'origin_city', + 'destination_province', + 'destination_city', + 'owner', + 'driver_name', + 'car_tracking_code', + 'out', + 'quantity', + 'jihadi_destination', + 'jihadi_origin', + + ] diff --git a/app/helper.py b/app/helper.py new file mode 100644 index 0000000..c9021bf --- /dev/null +++ b/app/helper.py @@ -0,0 +1,157 @@ +import re +import requests +from bs4 import BeautifulSoup +from requests.adapters import HTTPAdapter +from requests.packages.urllib3.util.ssl_ import create_urllib3_context + +from django.db.models import Q +from django.views.decorators.csrf import csrf_exempt +from rest_framework import status +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import AllowAny +from rest_framework.response import Response + +from app.cityandprovince import correct_province, correct_city, search_city_list, \ + search_province_list +from app.models import TransportingDetail, Guilds, AllProductsTransport +from app.serializers import TransportingDetailForUpdateSerializer, AllProductsTransportSerializer + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def get_bar_info(request): + kill_houses = request.data + kill_houses = dict(kill_houses)['kill_house'] + bars = AllProductsTransport.objects.filter(trash=False, out=True, jihadi_destination__in=kill_houses, + unloading='تخلیه شده.',product='مرغ زنده -جهت كشتار',hatching__isnull=False, + date__gte='2025-12-25').order_by('-date') + ser_data = AllProductsTransportSerializer(bars, many=True).data + return Response(ser_data, status=status.HTTP_200_OK) + + +@api_view(["GET"]) +@permission_classes([AllowAny]) +@csrf_exempt +def test_city(request): + excluded_provinces = search_province_list + excluded_city = search_city_list + # hatchings = Hatching.objects.filter( + # ~Q(ProvinceName__in=excluded_provinces) | ~Q(CityName__in=excluded_city) + # ) + transport = TransportingDetail.objects.filter( + ~Q(Province__in=excluded_provinces) | ~Q(City__in=excluded_city)).only('Province', 'City') + # hatchings = Hatching.objects.filter( + # Q(ProvinceName__contains='�') | Q( CityName__contains='�') + # ) + l = 1 + for t in transport: + print(l) + if t.Province not in excluded_provinces: + t.Province = correct_province(t.Province) + t.save() + if t.City not in excluded_city: + t.CityName = correct_city(t.City, t.Province) + t.save() + l += 1 + # if hatching: + + return Response('lo') + + +class SSLAdapter(HTTPAdapter): + def __init__(self, *args, **kwargs): + self.context = create_urllib3_context() + self.context.options |= 0x4 # OP_LEGACY_SERVER_CONNECT + super().__init__(*args, **kwargs) + + def init_poolmanager(self, *args, **kwargs): + kwargs['ssl_context'] = self.context + return super().init_poolmanager(*args, **kwargs) + + def build_response(self, req, resp): + resp = super().build_response(req, resp) + return resp + + +def check_quarantine_code(lst): + result_code = [] + for code in lst: + session = requests.Session() + session.mount('https://', SSLAdapter()) + data = {'gid': str(code)} + m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, + headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + ' (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) + context = BeautifulSoup(m.text, 'html.parser') + table = context.find_all('table') + if table[5:6]: + row = context.find('div', align="right") + if row: + content = row.get_text(separator=" ", strip=True) + date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) + if date_match: + for i in table[5:6]: + row = i.find_all('tr') + for r in row[1:2]: + quantity = r.find('td') + match = re.search(r'\d+', quantity.text) + if match: + result_code.append(code) + return result_code + + +def get_hatching_permit_code(code): + result = {} + + session = requests.Session() + session.mount('https://', SSLAdapter()) + data = {'gid': str(code)} + m = session.post( + 'https://e.ivo.ir/Rahgiri/Gidprnt.aspx', + data=data, + verify=False, + headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' + ' (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36' + }, + timeout=20, + ) + text = m.text + permit = None + match = re.search(r'کد\s*مجوز\s*جوجه\s*ریزی\s*[::]\s*([0-9۰-۹]+)', text) + if match: + raw_permit = match.group(1) + trans = str.maketrans('۰۱۲۳۴۵۶۷۸۹', '0123456789') + permit = raw_permit.translate(trans) + if permit: + result[str(code)] = permit + return result + + +@api_view(["GET"]) +@permission_classes([AllowAny]) +@csrf_exempt +def api_get_hatching_permit_code(request): + code = request.GET.get('code') + if not code: + return Response({'detail': 'code query param is required'}, status=status.HTTP_400_BAD_REQUEST) + try: + data = get_hatching_permit_code(code) + return Response(data, status=status.HTTP_200_OK) + except Exception as e: + return Response({'detail': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + + +def create_guild(**info): + + Guilds( + ) + + +class SSLAdapter(HTTPAdapter): + def __init__(self, *args, **kwargs): + self.context = create_urllib3_context() + self.context.options |= 0x4 # OP_LEGACY_SERVER_CONNECT + super().__init__(*args, **kwargs) diff --git a/app/helper_excel.py b/app/helper_excel.py new file mode 100644 index 0000000..4ddaf21 --- /dev/null +++ b/app/helper_excel.py @@ -0,0 +1,327 @@ +from io import BytesIO + +import jdatetime +import openpyxl +from django.http import HttpResponse +from openpyxl import Workbook +from openpyxl.chart import LineChart, Reference, BarChart +from openpyxl.styles import PatternFill, Alignment, Font +from openpyxl.utils import get_column_letter + +correction_dict = { + '��ربراکرز (آپلاس)': 'آربراکرز (آپلاس)', + 'آ��براکرز (آپلاس)': 'آربراکرز (آپلاس)', + 'آر��راکرز (آپلاس)': 'آربراکرز (آپلاس)', + 'آرب��اکرز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربر��کرز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربرا��رز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربراک��ز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربراکر�� (آپلاس)': 'آربراکرز (آپلاس)', + 'آربراکرز�� آپلاس)': 'آربراکرز (آپلاس)', + 'آربراکرز (��پلاس)': 'آربراکرز (آپلاس)', + 'آربراکرز (آ��لاس)': 'آربراکرز (آپلاس)', + 'آربراکرز (آپ��اس)': 'آربراکرز (آپلاس)', + 'آربراکرز (آپل��س)': 'آربراکرز (آپلاس)', + 'آربراکرز (آپلا��)': 'آربراکرز (آپلاس)', + 'آربراکرز (آپلاس��': 'آربراکرز (آپلاس)', + 'آربراکرز��(آپلاس)': 'آربراکرز (آپلاس)', + + '��اس': 'راس', + 'ر��س': 'راس', + 'را��': 'راس', + + '��رین': 'آرین', + 'آ��ین': 'آرین', + 'آر��ن': 'آرین', + 'آری��': 'آرین', + + '��ندین ریور': 'ایندین ریور', + 'ای��دین ریور': 'ایندین ریور', + 'این��ین ریور': 'ایندین ریور', + 'ایند��ن ریور': 'ایندین ریور', + 'ایندی�� ریور': 'ایندین ریور', + 'ایندین��ریور': 'ایندین ریور', + 'ایندین ��یور': 'ایندین ریور', + 'ایندین ر��ور': 'ایندین ریور', + 'ایندین ری��ر': 'ایندین ریور', + 'ایندین ریو��': 'ایندین ریور', + + '��اب': 'کاب', + 'ک��ب': 'کاب', + 'کا��': 'کاب' +} + +blue_fill = PatternFill(start_color="277358", fill_type="solid") +Alignment_CELL = Alignment(horizontal='center', vertical='center', wrap_text=True) +red_font = Font(color="C00000", bold=True) +GREEN_CELL = PatternFill(start_color="00B050", fill_type="solid") +RED_CELL = PatternFill(start_color="FCDFDC", fill_type="solid") +YELLOW_CELL = PatternFill(start_color="FFFF00", fill_type="solid") +ORANGE_CELL = PatternFill(start_color="FFC000", fill_type="solid") +BLUE_CELL = PatternFill(start_color="538DD5", fill_type="solid") +LIGHT_GREEN_CELL = PatternFill(start_color="92D050", fill_type="solid") +VERY_LIGHT_GREEN_CELL = PatternFill(start_color="5AFC56", fill_type="solid") + + + + +def shamsi_date(date,in_value=None): + if in_value: + sh_date=jdatetime.date.fromgregorian( + year=date.year, + month=date.month, + day=date.day + ) + else: + gh_date = jdatetime.date.fromgregorian( + year=date.year, + month=date.month, + day=date.day + ).strftime('%Y-%m-%d') + reversed_date = reversed(gh_date.split("-")) + separate = "-" + sh_date = separate.join(reversed_date) + return sh_date + + +def create_header(worksheet, list, num, row, height=None, width=None,color=None,text_color=None,border_style=None): + for col_num, option in enumerate(list, num): + cell = worksheet.cell(row=row, column=col_num, value=option) + col_letter = get_column_letter(col_num) + cell.alignment = Alignment_CELL + if color is not None: + if color == 'green': + cell.fill=GREEN_CELL + elif color == 'orange': + cell.fill=ORANGE_CELL + elif color == 'blue': + cell.fill=BLUE_CELL + else: + cell.fill = PatternFill(start_color=color, fill_type="solid") + else: + cell.fill = blue_fill + if text_color is not None: + cell.font = Font(size=9, bold=True, color=text_color) + else: + cell.font = Font(size=9, bold=True, color='D9FFFFFF') + if height is not None: + worksheet.row_dimensions[row].height = height + if width is not None: + worksheet.column_dimensions[col_letter].width = width + if border_style is not None: + cell.border = openpyxl.styles.Border( + left=openpyxl.styles.Side(style=border_style), + right=openpyxl.styles.Side(style=border_style), + top=openpyxl.styles.Side(style=border_style), + bottom=openpyxl.styles.Side(style=border_style) + ) + + +def create_header_freez(worksheet, list, num, row, header_row, height=None, width=None,len_with=None,different_cell=None): + for col_num, option in enumerate(list, num): + col_letter = get_column_letter(col_num) + cell = worksheet.cell(row=row, column=col_num, value=option) + cell.alignment = Alignment_CELL + cell.fill = blue_fill + cell.font = Font(size=10, bold=True, color='D9FFFFFF') + + if height is not None: + worksheet.row_dimensions[row].height = height + if len(option) > worksheet.column_dimensions[col_letter].width: + worksheet.column_dimensions[col_letter].width = len(option) + 2 + if width is not None: + worksheet.column_dimensions[col_letter].width = width + if len_with is not None: + if len(option) > worksheet.column_dimensions[col_letter].width: + worksheet.column_dimensions[col_letter].width = len(option) + 3 + if different_cell is not None: + if option == different_cell: + cell.fill = PatternFill(start_color="C00000", fill_type="solid") + worksheet.freeze_panes = worksheet[f'A{header_row}'] + max_col = worksheet.max_column + range_str = f'A{header_row - 1}:{get_column_letter(max_col)}{worksheet.max_row}' + worksheet.auto_filter.ref = range_str + + +def excel_description(worksheet, row1, description, size=None, color=None,my_color=None, row2=None): + worksheet[row1] = description + worksheet[row1].alignment = Alignment_CELL + if size is not None: + worksheet[row1].font = Font(size=size) + if color is not None: + worksheet[row1].font = red_font + if my_color is not None: + worksheet[row1].font = PatternFill(start_color=my_color, fill_type="solid") + + if row2 is not None: + merge_range = f'{row1}:{row2}' + worksheet.merge_cells(merge_range) + + +def create_value(worksheet, list, l, num, border_style=None, m=None, height=None, color=None, width=None, + different_cell=None, different_value=None, item_num=None, item_color=None): + + color_dict = { + 'green': GREEN_CELL, + 'yellow': YELLOW_CELL, + 'blue': BLUE_CELL, + 'red': RED_CELL, + 'light_green': LIGHT_GREEN_CELL, + 'very_light_green': VERY_LIGHT_GREEN_CELL + } + + for item in range(len(list)): + cell = worksheet.cell(row=l, column=item + num, value=list[item]) + cell.alignment = Alignment_CELL + + if border_style: + cell.border = openpyxl.styles.Border( + left=openpyxl.styles.Side(style=border_style), + right=openpyxl.styles.Side(style=border_style), + top=openpyxl.styles.Side(style=border_style), + bottom=openpyxl.styles.Side(style=border_style) + ) + + value = list[item] + if isinstance(value, (int, float)) and value != 0: + cell.number_format = '#,###' + else: + cell.value = value + + cell.font = Font(size=10, bold=True) + + if m is not None and m % 2 != 0: + cell.fill = PatternFill(start_color="D6F6FE", fill_type="solid") + + if height is not None: + worksheet.row_dimensions[l + 1].height = height + + if item_num is not None and item == item_num: + if item_color: + cell.fill = item_color + elif color in color_dict: + cell.fill = color_dict[color] + + if different_cell is not None and list[different_cell] == different_value: + cell.fill = RED_CELL + + if width is not None: + worksheet.column_dimensions[openpyxl.utils.get_column_letter(item + num)].width = width + +def merge_cells(worksheet, l, s, cell1=None, cell2=None, lst=None): + if lst is not None: + for col in lst: + rng = f'{col}{l}:{col}{l + s}' + worksheet.merge_cells(rng) + worksheet[col + f'{l}'].alignment = Alignment_CELL + else: + for col in range(ord(f'{cell1}'), ord(f'{cell2}') + 1): + rng = f'{chr(col)}{l}:{chr(col)}{l + s}' + worksheet.merge_cells(rng) + worksheet[chr(col) + f'{l}'].alignment = Alignment_CELL + +def add_header(worksheet): + worksheet.oddHeader.center.text = "سامانه رصدیار" + worksheet.oddHeader.center.size = 14 # تنظیم اندازه فونت + worksheet.oddHeader.center.font = "Arial,Bold" # تنظیم فونت و ضخامت + + # همچنین می‌توانید از هدرهای چپ و راست هم استفاده کنید + # worksheet.oddHeader.right.text = f"تاریخ: {shamsi_now_date}" + +def cell_color_changer(worksheet, row, start_index, end_index, custom_color): + for item in range(start_index, end_index): + cell = worksheet.cell(row=row, column=item) + cell.fill = PatternFill(start_color=custom_color, fill_type="solid") + + +def start_excel(): + output = BytesIO() + workbook = Workbook() + worksheet = workbook.active + worksheet.sheet_view.rightToLeft = True + worksheet.insert_rows(1) + return workbook,worksheet,output + +def close_excel(name): + workbook,worksheet,output=start_excel() + workbook.save(output) + output.seek(0) + + response = HttpResponse( + content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') + response[ + 'Content-Disposition'] = f'attachment; filename="{name}.xlsx"'.encode( + 'utf-8') + response.write(output.getvalue()) + return response + + + +def add_chart( + worksheet, + chart_type, + data_columns, + category_column, + start_row, + end_row, + chart_position, + chart_title, + x_axis_title, + y_axis_title, + chart_width=25, # عرض نمودار پیش‌فرض (واحد: cm) + chart_height=15 + ): + """ + افزودن نمودار به صفحه اکسل. + + ورودی: + worksheet (openpyxl.Worksheet): صفحه اکسل. + chart_type (str): نوع نمودار ("line" یا "bar"). + data_columns (list): لیستی از ستون‌های داده. + category_column (int): ستون دسته‌بندی‌ها. + start_row (int): ردیف شروع داده‌ها. + end_row (int): ردیف پایان داده‌ها. + chart_position (str): محل قرار گرفتن نمودار. + chart_title (str): عنوان نمودار. + x_axis_title (str): عنوان محور X. + y_axis_title (str): عنوان محور Y. + chart_width (float): عرض نمودار (واحد: cm). + chart_height (float): ارتفاع نمودار (واحد: cm). + """ + + if chart_type == 'line': + chart = LineChart() + chart.style = 20 + elif chart_type == 'bar': + chart = BarChart() + else: + raise ValueError("chart_type باید 'line' یا 'bar' باشد.") + + chart.title = chart_title + chart.y_axis.title = y_axis_title + chart.x_axis.title = x_axis_title + chart.width = chart_width + chart.height = chart_height + + categories = Reference(worksheet, min_col=category_column, min_row=start_row, max_row=end_row) + data = Reference(worksheet, min_col=data_columns, min_row=start_row - 1, max_row=end_row) + chart.add_data(data, titles_from_data=True) + chart.set_categories(categories) + for series in chart.series: + series.graphicalProperties.line.solidFill = "277358" + series.graphicalProperties.line.width = 30000 + + worksheet.add_chart(chart, chart_position) + #example + # add_chart( + # worksheet=worksheet, + # chart_type='line', + # data_columns=7, # ستون وزن وارد شده + # category_column=2, # ستون نام سردخانه‌ها + # start_row=7, + # end_row=l + 1, + # chart_position="A12", + # chart_title="نمودار تغییرات وزن در سردخانه‌ها", + # x_axis_title="سردخانه‌ها", + # y_axis_title="وزن (کیلوگرم)" + # ) \ No newline at end of file diff --git a/app/migrations/0001_initial.py b/app/migrations/0001_initial.py new file mode 100644 index 0000000..7545864 --- /dev/null +++ b/app/migrations/0001_initial.py @@ -0,0 +1,138 @@ +# Generated by Django 4.2.19 on 2025-02-26 11:13 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Poultry', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('UserName', models.CharField(max_length=200, null=True)), + ('Password', models.CharField(max_length=200, null=True)), + ('FirstName', models.CharField(max_length=200, null=True)), + ('LastName', models.CharField(max_length=200, null=True)), + ('UserGroupName', models.CharField(max_length=200, null=True)), + ('UserRoleName', models.CharField(max_length=200, null=True)), + ('UserGroupId', models.CharField(max_length=200, null=True)), + ('UserRoleId', models.CharField(max_length=200, null=True)), + ('Mobile', models.CharField(max_length=200, null=True)), + ('Email', models.CharField(max_length=200, null=True)), + ('UserIsActive', models.BooleanField(null=True)), + ('UserIsActiveDescription', models.CharField(max_length=200, null=True)), + ('RegDate', models.CharField(max_length=200, null=True)), + ('RegDateShamsi', models.CharField(max_length=200, null=True)), + ('RegDateShamsiWithTime', models.CharField(max_length=200, null=True)), + ('RegDateShamsiOnlyTime', models.CharField(max_length=200, null=True)), + ('StringId', models.CharField(max_length=200, null=True)), + ('IsPersisted', models.CharField(max_length=200, null=True)), + ('AllowInsert', models.CharField(max_length=200, null=True)), + ('AllowUpdate', models.CharField(max_length=200, null=True)), + ('ModalCss', models.CharField(max_length=200, null=True)), + ('GridContainerParametersModel', models.CharField(max_length=200, null=True)), + ('MenuUserAccess', models.CharField(max_length=200, null=True)), + ('MenuUserAccessId', models.CharField(max_length=200, null=True)), + ('LogTableName', models.CharField(max_length=200, null=True)), + ('LogTableAlias', models.CharField(max_length=200, null=True)), + ('PageTitle', models.CharField(max_length=200, null=True)), + ('UnitName', models.CharField(max_length=200, null=True)), + ('SystemCode', models.CharField(max_length=200, null=True)), + ('TrackingCode', models.CharField(max_length=200, null=True)), + ('EpidemiologicCode', models.CharField(max_length=200, null=True)), + ('PartIdCode', models.CharField(max_length=200, null=True)), + ('PostalCode', models.CharField(max_length=200, null=True)), + ('UnitId', models.CharField(max_length=200, null=True)), + ('UnitTypeId', models.CharField(max_length=200, null=True)), + ('UnitTypeName', models.CharField(max_length=200, null=True)), + ('LocationIdProvince', models.CharField(max_length=200, null=True)), + ('LocationIdCity', models.CharField(max_length=200, null=True)), + ('UnitIsActive', models.CharField(max_length=200, null=True)), + ('UnitIsActiveDescription', models.CharField(max_length=200, null=True)), + ('PId', models.CharField(max_length=200, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='PoultryHatching', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('DesCertId', models.CharField(max_length=200, null=True)), + ('UnitId', models.CharField(max_length=200, null=True)), + ('BroilerFlockRequestId', models.CharField(max_length=200, null=True)), + ('RequestCode', models.CharField(max_length=200, null=True)), + ('StartDate', models.CharField(max_length=200, null=True)), + ('StartDatePersian', models.CharField(max_length=200, null=True)), + ('EndDate', models.CharField(max_length=200, null=True)), + ('EndDatePersian', models.CharField(max_length=200, null=True)), + ('HatchingDate', models.CharField(max_length=200, null=True)), + ('HatchingDatePersian', models.CharField(max_length=200, null=True)), + ('MaxHatchingDate', models.CharField(max_length=200, null=True)), + ('MaxHatchingDatePersian', models.CharField(max_length=200, null=True)), + ('HatchingCount', models.CharField(max_length=200, null=True)), + ('HatchingCountInBargiri', models.CharField(max_length=200, null=True)), + ('HatchingCountInTakhlie', models.CharField(max_length=200, null=True)), + ('TrackingCount', models.CharField(max_length=200, null=True)), + ('TrackingBargiriCount', models.CharField(max_length=200, null=True)), + ('PercentHamlToMojavez', models.CharField(max_length=200, null=True)), + ('PercentTakhlieToBargiri', models.CharField(max_length=200, null=True)), + ('FlockAgeDay', models.CharField(max_length=200, null=True)), + ('PartIdCode', models.CharField(max_length=200, null=True)), + ('UnitName', models.CharField(max_length=200, null=True)), + ('PostalCode', models.CharField(max_length=200, null=True)), + ('EpidemiologicCode', models.CharField(max_length=200, null=True)), + ('CapacityFemale', models.CharField(max_length=200, null=True)), + ('PersonFullName', models.CharField(max_length=200, null=True)), + ('LocationIdProvince', models.CharField(max_length=200, null=True)), + ('LocationNameProvince', models.CharField(max_length=200, null=True)), + ('LocationIdCity', models.CharField(max_length=200, null=True)), + ('LocationNameCity', models.CharField(max_length=200, null=True)), + ('Mobile', models.CharField(max_length=200, null=True)), + ('HamlMorghMinDate', models.CharField(max_length=200, null=True)), + ('HamlMorghTotalCount', models.CharField(max_length=200, null=True)), + ('HamlMorghTakhlieCount', models.CharField(max_length=200, null=True)), + ('EvacuationCount', models.CharField(max_length=200, null=True)), + ('EvacuationCount_1', models.CharField(max_length=200, null=True)), + ('EvacuationCount_2', models.CharField(max_length=200, null=True)), + ('EvacuationCount_3', models.CharField(max_length=200, null=True)), + ('BaseHatchingCount', models.CharField(max_length=200, null=True)), + ('PercentMorghToJoojeTotal', models.CharField(max_length=200, null=True)), + ('PercentMorghToJoojeTakhlie', models.CharField(max_length=200, null=True)), + ('PercentMorghToJoojeTakhlieWithEvacutaion', models.CharField(max_length=200, null=True)), + ('PercentNotDeliverd', models.CharField(max_length=200, null=True)), + ('PercentDeliveredForSP', models.CharField(max_length=200, null=True)), + ('PercentDeliveredForSPNoExclude', models.CharField(max_length=200, null=True)), + ('PercentDeliveredWithoutEvac', models.CharField(max_length=200, null=True)), + ('DiffHamlThanTakhlieCount', models.CharField(max_length=200, null=True)), + ('DiffTakhlieThanHamlCount', models.CharField(max_length=200, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ('poultry', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='hatching_poultry', to='app.poultry')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0002_remove_poultry_allowinsert_and_more.py b/app/migrations/0002_remove_poultry_allowinsert_and_more.py new file mode 100644 index 0000000..feff8ea --- /dev/null +++ b/app/migrations/0002_remove_poultry_allowinsert_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.19 on 2025-02-26 11:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='poultry', + name='AllowInsert', + ), + migrations.RemoveField( + model_name='poultry', + name='AllowUpdate', + ), + migrations.RemoveField( + model_name='poultry', + name='IsPersisted', + ), + migrations.RemoveField( + model_name='poultry', + name='UnitIsActive', + ), + ] diff --git a/app/migrations/0003_poultry_allowinsert_poultry_allowupdate_and_more.py b/app/migrations/0003_poultry_allowinsert_poultry_allowupdate_and_more.py new file mode 100644 index 0000000..7c772be --- /dev/null +++ b/app/migrations/0003_poultry_allowinsert_poultry_allowupdate_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.19 on 2025-02-26 11:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0002_remove_poultry_allowinsert_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='poultry', + name='AllowInsert', + field=models.BooleanField(null=True), + ), + migrations.AddField( + model_name='poultry', + name='AllowUpdate', + field=models.BooleanField(null=True), + ), + migrations.AddField( + model_name='poultry', + name='IsPersisted', + field=models.BooleanField(null=True), + ), + migrations.AddField( + model_name='poultry', + name='UnitIsActive', + field=models.BooleanField(null=True), + ), + ] diff --git a/app/migrations/0004_poultryhatching_date_poultryhatching_hatchingage.py b/app/migrations/0004_poultryhatching_date_poultryhatching_hatchingage.py new file mode 100644 index 0000000..afed89a --- /dev/null +++ b/app/migrations/0004_poultryhatching_date_poultryhatching_hatchingage.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.19 on 2025-02-27 08:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0003_poultry_allowinsert_poultry_allowupdate_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='poultryhatching', + name='Date', + field=models.DateTimeField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HatchingAge', + field=models.IntegerField(default=1), + ), + ] diff --git a/app/migrations/0005_remove_poultryhatching_basehatchingcount_and_more.py b/app/migrations/0005_remove_poultryhatching_basehatchingcount_and_more.py new file mode 100644 index 0000000..a4299c8 --- /dev/null +++ b/app/migrations/0005_remove_poultryhatching_basehatchingcount_and_more.py @@ -0,0 +1,117 @@ +# Generated by Django 4.2.19 on 2025-02-27 09:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0004_poultryhatching_date_poultryhatching_hatchingage'), + ] + + operations = [ + migrations.RemoveField( + model_name='poultryhatching', + name='BaseHatchingCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='BroilerFlockRequestId', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='CapacityFemale', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='DiffHamlThanTakhlieCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='DiffTakhlieThanHamlCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='EvacuationCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='EvacuationCount_1', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='EvacuationCount_2', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='EvacuationCount_3', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='FlockAgeDay', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='HamlMorghTakhlieCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='HamlMorghTotalCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='HatchingCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='HatchingCountInBargiri', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='HatchingCountInTakhlie', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentDeliveredForSP', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentDeliveredForSPNoExclude', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentDeliveredWithoutEvac', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentHamlToMojavez', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentMorghToJoojeTakhlie', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentMorghToJoojeTakhlieWithEvacutaion', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentMorghToJoojeTotal', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentNotDeliverd', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='PercentTakhlieToBargiri', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='TrackingBargiriCount', + ), + migrations.RemoveField( + model_name='poultryhatching', + name='TrackingCount', + ), + ] diff --git a/app/migrations/0006_poultryhatching_basehatchingcount_and_more.py b/app/migrations/0006_poultryhatching_basehatchingcount_and_more.py new file mode 100644 index 0000000..89a54d8 --- /dev/null +++ b/app/migrations/0006_poultryhatching_basehatchingcount_and_more.py @@ -0,0 +1,143 @@ +# Generated by Django 4.2.19 on 2025-02-27 09:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0005_remove_poultryhatching_basehatchingcount_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='poultryhatching', + name='BaseHatchingCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='BroilerFlockRequestId', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='CapacityFemale', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='DiffHamlThanTakhlieCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='DiffTakhlieThanHamlCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='EvacuationCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='EvacuationCount_1', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='EvacuationCount_2', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='EvacuationCount_3', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='FlockAgeDay', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HamlMorghTakhlieCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HamlMorghTotalCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HatchingCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HatchingCountInBargiri', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='HatchingCountInTakhlie', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentDeliveredForSP', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentDeliveredForSPNoExclude', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentDeliveredWithoutEvac', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentHamlToMojavez', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentMorghToJoojeTakhlie', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentMorghToJoojeTakhlieWithEvacutaion', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentMorghToJoojeTotal', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentNotDeliverd', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='PercentTakhlieToBargiri', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='TrackingBargiriCount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='poultryhatching', + name='TrackingCount', + field=models.IntegerField(null=True), + ), + ] diff --git a/app/migrations/0007_transportingchickendetail.py b/app/migrations/0007_transportingchickendetail.py new file mode 100644 index 0000000..4e27bf1 --- /dev/null +++ b/app/migrations/0007_transportingchickendetail.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.19 on 2025-02-27 11:07 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0006_poultryhatching_basehatchingcount_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='TransportingChickenDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('PedigreeName', models.CharField(max_length=200, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('hatching', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transporting_hatching', to='app.poultryhatching')), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0008_transportingchickendetail_certid_and_more.py b/app/migrations/0008_transportingchickendetail_certid_and_more.py new file mode 100644 index 0000000..b45ce9f --- /dev/null +++ b/app/migrations/0008_transportingchickendetail_certid_and_more.py @@ -0,0 +1,118 @@ +# Generated by Django 4.2.19 on 2025-02-27 11:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0007_transportingchickendetail'), + ] + + operations = [ + migrations.AddField( + model_name='transportingchickendetail', + name='CertId', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='DesCertId', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='GoodAmount', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='GoodCode', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='GoodName', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='IssueDate', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='IssueDatePersian', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='ParentPartIdCode', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='ParentUnitName', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='ResideDate', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='ResideDatePersian', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='SourceCertId', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='SourcePartIdCode', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='SourceUnitName', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='TakhlieDate', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='TakhlieDatePersian', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='TrackingCode', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='TrackingStatus', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='TrackingStatusDescription', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='issue_date', + field=models.DateTimeField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='reside_date', + field=models.DateTimeField(null=True), + ), + ] diff --git a/app/migrations/0009_transportingchickendetail_broilerflockrequestid_and_more.py b/app/migrations/0009_transportingchickendetail_broilerflockrequestid_and_more.py new file mode 100644 index 0000000..236d135 --- /dev/null +++ b/app/migrations/0009_transportingchickendetail_broilerflockrequestid_and_more.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.19 on 2025-02-27 12:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0008_transportingchickendetail_certid_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='transportingchickendetail', + name='BroilerFlockRequestId', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='DesPartIdCode', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='DesUnitName', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='HealthPermitId', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingchickendetail', + name='SourceUnitPartIdCode', + field=models.CharField(max_length=200, null=True), + ), + ] diff --git a/app/migrations/0010_transportingchickendetail_province_and_more.py b/app/migrations/0010_transportingchickendetail_province_and_more.py new file mode 100644 index 0000000..6691541 --- /dev/null +++ b/app/migrations/0010_transportingchickendetail_province_and_more.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.19 on 2025-02-28 10:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("app", "0009_transportingchickendetail_broilerflockrequestid_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="transportingchickendetail", + name="Province", + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name="transportingchickendetail", + name="ProvinceId", + field=models.CharField(max_length=200, null=True), + ), + ] diff --git a/app/migrations/0011_poultryhatching_pedigreename.py b/app/migrations/0011_poultryhatching_pedigreename.py new file mode 100644 index 0000000..c4217cc --- /dev/null +++ b/app/migrations/0011_poultryhatching_pedigreename.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-03-01 11:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0010_transportingchickendetail_province_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='poultryhatching', + name='PedigreeName', + field=models.CharField(max_length=200, null=True), + ), + ] diff --git a/app/migrations/0012_transportingchickendetail_age.py b/app/migrations/0012_transportingchickendetail_age.py new file mode 100644 index 0000000..fd915fd --- /dev/null +++ b/app/migrations/0012_transportingchickendetail_age.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-03-03 12:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0011_poultryhatching_pedigreename'), + ] + + operations = [ + migrations.AddField( + model_name='transportingchickendetail', + name='age', + field=models.IntegerField(default=1), + ), + ] diff --git a/app/migrations/0013_poultryhatching_leftover.py b/app/migrations/0013_poultryhatching_leftover.py new file mode 100644 index 0000000..7a67a11 --- /dev/null +++ b/app/migrations/0013_poultryhatching_leftover.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-03-09 11:52 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0012_transportingchickendetail_age'), + ] + + operations = [ + migrations.AddField( + model_name='poultryhatching', + name='LeftOver', + field=models.IntegerField(null=True), + ), + ] diff --git a/app/migrations/0014_poultry_locationnamecity_and_more.py b/app/migrations/0014_poultry_locationnamecity_and_more.py new file mode 100644 index 0000000..f6e810d --- /dev/null +++ b/app/migrations/0014_poultry_locationnamecity_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.19 on 2025-03-11 12:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0013_poultryhatching_leftover'), + ] + + operations = [ + migrations.AddField( + model_name='poultry', + name='LocationNameCity', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='poultry', + name='LocationNameProvince', + field=models.CharField(max_length=200, null=True), + ), + ] diff --git a/app/migrations/0015_hatching_transportingdetail.py b/app/migrations/0015_hatching_transportingdetail.py new file mode 100644 index 0000000..7e53fed --- /dev/null +++ b/app/migrations/0015_hatching_transportingdetail.py @@ -0,0 +1,155 @@ +# Generated by Django 4.2.19 on 2025-04-05 13:43 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0014_poultry_locationnamecity_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='Hatching', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('BroilerFlockRequestId', models.IntegerField(blank=True, null=True)), + ('InsertDate', models.CharField(blank=True, max_length=200, null=True)), + ('LastChangeStatusDate', models.CharField(blank=True, max_length=200, null=True)), + ('LastChangeStatusDateShamsi', models.CharField(blank=True, max_length=200, null=True)), + ('FlockRequestUnitName', models.CharField(blank=True, max_length=200, null=True)), + ('PedigreeName', models.CharField(blank=True, max_length=200, null=True)), + ('StatusId', models.IntegerField(blank=True, null=True)), + ('Status', models.IntegerField(blank=True, null=True)), + ('StatusName', models.CharField(blank=True, max_length=200, null=True)), + ('PedigreeType', models.IntegerField(blank=True, null=True)), + ('BroilerPedigreeTypeName', models.CharField(blank=True, max_length=200, null=True)), + ('StatusColor', models.CharField(blank=True, max_length=200, null=True)), + ('SystemRevocationDate', models.CharField(blank=True, max_length=200, null=True)), + ('RemindDays', models.IntegerField(blank=True, null=True)), + ('PartyCount', models.IntegerField(blank=True, null=True)), + ('GoodCount', models.IntegerField(blank=True, null=True)), + ('ShowButtons', models.BooleanField(blank=True, null=True)), + ('HasSync', models.BooleanField(blank=True, null=True)), + ('BroilerFlockRequestExpireStatus', models.IntegerField(blank=True, null=True)), + ('IdWithFormat', models.CharField(blank=True, max_length=200, null=True)), + ('ProvinceName', models.CharField(blank=True, max_length=200, null=True)), + ('CityName', models.CharField(blank=True, max_length=200, null=True)), + ('Address', models.CharField(blank=True, max_length=200, null=True)), + ('UnitTel', models.CharField(blank=True, max_length=200, null=True)), + ('UnitPostalCode', models.CharField(blank=True, max_length=200, null=True)), + ('UnitName', models.CharField(blank=True, max_length=200, null=True)), + ('SystemCode', models.CharField(blank=True, max_length=200, null=True)), + ('CapacityFemale', models.CharField(blank=True, max_length=200, null=True)), + ('EpidemiologicCode', models.CharField(blank=True, max_length=200, null=True)), + ('RequestCode', models.CharField(blank=True, max_length=200, null=True)), + ('RequestDate', models.CharField(blank=True, max_length=200, null=True)), + ('RequestDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('RequestCount', models.IntegerField(blank=True, null=True)), + ('DeliverDate', models.CharField(blank=True, max_length=200, null=True)), + ('DeliverDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('UnionName', models.CharField(blank=True, max_length=200, null=True)), + ('PersonTypeId', models.IntegerField(blank=True, null=True)), + ('PersonType', models.IntegerField(blank=True, null=True)), + ('PersonTypeName', models.CharField(blank=True, max_length=200, null=True)), + ('PersonFullName', models.CharField(blank=True, max_length=200, null=True)), + ('NationalCode', models.CharField(blank=True, max_length=200, null=True)), + ('InteractType', models.IntegerField(blank=True, null=True)), + ('InteractTypeName', models.CharField(blank=True, max_length=200, null=True)), + ('UnionTypeId', models.IntegerField(blank=True, null=True)), + ('UnionTypeName', models.CharField(blank=True, max_length=200, null=True)), + ('SendDate', models.CharField(blank=True, max_length=200, null=True)), + ('SendDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('ChickCountSum', models.IntegerField(blank=True, null=True)), + ('CalculatedDate', models.CharField(blank=True, max_length=200, null=True)), + ('CalculatedDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('PartIdCode', models.CharField(blank=True, max_length=200, null=True)), + ('CertId', models.CharField(blank=True, max_length=200, null=True)), + ('StartDate', models.CharField(blank=True, max_length=200, null=True)), + ('StartDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('EndDate', models.CharField(blank=True, max_length=200, null=True)), + ('EndDateFa', models.CharField(blank=True, max_length=200, null=True)), + ('RemainCredit', models.IntegerField(blank=True, null=True)), + ('StrRemainCredit', models.CharField(blank=True, max_length=200, null=True)), + ('ShowStatus', models.CharField(blank=True, max_length=200, null=True)), + ('ValidStatus', models.CharField(blank=True, max_length=200, null=True)), + ('ValidStatusName', models.CharField(blank=True, max_length=200, null=True)), + ('RegDate', models.CharField(blank=True, max_length=200, null=True)), + ('RegDateShamsi', models.CharField(blank=True, max_length=200, null=True)), + ('RegDateShamsiWithTime', models.CharField(blank=True, max_length=200, null=True)), + ('RegDateShamsiOnlyTime', models.CharField(blank=True, max_length=200, null=True)), + ('HatchingId', models.CharField(blank=True, max_length=200, null=True)), + ('StringId', models.CharField(blank=True, max_length=200, null=True)), + ('IsPersisted', models.BooleanField(blank=True, null=True)), + ('AllowInsert', models.BooleanField(blank=True, null=True)), + ('AllowUpdate', models.BooleanField(blank=True, null=True)), + ('ModalCss', models.CharField(blank=True, max_length=200, null=True)), + ('GridContainerParametersModel', models.CharField(blank=True, max_length=200, null=True)), + ('MenuUserAccess', models.CharField(blank=True, max_length=200, null=True)), + ('MenuUserAccessId', models.IntegerField(blank=True, null=True)), + ('LogTableName', models.CharField(blank=True, max_length=200, null=True)), + ('LogTableAlias', models.CharField(blank=True, max_length=200, null=True)), + ('PageTitle', models.CharField(blank=True, max_length=200, null=True)), + ('Evacuation', models.IntegerField(default=0)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ('poultry', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='poultry_hatching_poultry', to='app.poultry')), + ], + options={ + 'abstract': False, + }, + ), + migrations.CreateModel( + name='TransportingDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('BroilerFlockRequestId', models.IntegerField(blank=True, null=True)), + ('TrackingCode', models.CharField(max_length=200, null=True)), + ('DesCertId', models.CharField(max_length=200, null=True)), + ('IssueDate', models.CharField(max_length=200, null=True)), + ('IssueDatePersian', models.CharField(max_length=200, null=True)), + ('issue_date', models.DateTimeField(null=True)), + ('GoodCode', models.IntegerField(null=True)), + ('GoodName', models.CharField(max_length=200, null=True)), + ('GoodAmount', models.IntegerField(null=True)), + ('TrackingStatus', models.IntegerField(null=True)), + ('TrackingStatusDescription', models.CharField(max_length=200, null=True)), + ('TakhlieDate', models.CharField(max_length=200, null=True)), + ('TakhlieDatePersian', models.CharField(max_length=200, null=True)), + ('SourcePartIdCode', models.CharField(max_length=200, null=True)), + ('SourceUnitPartIdCode', models.CharField(max_length=200, null=True)), + ('SourceUnitName', models.CharField(max_length=200, null=True)), + ('SourceCertId', models.CharField(max_length=200, null=True)), + ('ParentPartIdCode', models.CharField(max_length=200, null=True)), + ('ParentUnitName', models.CharField(max_length=200, null=True)), + ('CertId', models.CharField(max_length=200, null=True)), + ('ResideDate', models.CharField(max_length=200, null=True)), + ('ResideDatePersian', models.CharField(max_length=200, null=True)), + ('PedigreeName', models.CharField(max_length=200, null=True)), + ('DesUnitName', models.CharField(max_length=200, null=True)), + ('DesPartIdCode', models.CharField(max_length=200, null=True)), + ('HealthPermitId', models.IntegerField(null=True)), + ('ProvinceId', models.CharField(max_length=200, null=True)), + ('Province', models.CharField(max_length=200, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('hatching', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transport_hatching', to='app.hatching')), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0016_remove_transportingdetail_certid_and_more.py b/app/migrations/0016_remove_transportingdetail_certid_and_more.py new file mode 100644 index 0000000..29e5400 --- /dev/null +++ b/app/migrations/0016_remove_transportingdetail_certid_and_more.py @@ -0,0 +1,68 @@ +# Generated by Django 4.2.19 on 2025-04-06 07:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0015_hatching_transportingdetail'), + ] + + operations = [ + migrations.RemoveField( + model_name='transportingdetail', + name='CertId', + ), + migrations.RemoveField( + model_name='transportingdetail', + name='ParentPartIdCode', + ), + migrations.RemoveField( + model_name='transportingdetail', + name='ParentUnitName', + ), + migrations.RemoveField( + model_name='transportingdetail', + name='ProvinceId', + ), + migrations.RemoveField( + model_name='transportingdetail', + name='issue_date', + ), + migrations.AddField( + model_name='hatching', + name='Age', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='hatching', + name='Date', + field=models.DateTimeField(null=True), + ), + migrations.AddField( + model_name='hatching', + name='LeftOver', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='hatching', + name='Period', + field=models.IntegerField(default=1), + ), + migrations.AddField( + model_name='transportingdetail', + name='Age', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingdetail', + name='City', + field=models.CharField(max_length=200, null=True), + ), + migrations.AddField( + model_name='transportingdetail', + name='Date', + field=models.DateTimeField(null=True), + ), + ] diff --git a/app/migrations/0017_hatching_archivedate.py b/app/migrations/0017_hatching_archivedate.py new file mode 100644 index 0000000..07e5f99 --- /dev/null +++ b/app/migrations/0017_hatching_archivedate.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-04-06 10:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0016_remove_transportingdetail_certid_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='hatching', + name='ArchiveDate', + field=models.DateTimeField(null=True), + ), + ] diff --git a/app/migrations/0018_remove_hatching_capacityfemale.py b/app/migrations/0018_remove_hatching_capacityfemale.py new file mode 100644 index 0000000..07d3e71 --- /dev/null +++ b/app/migrations/0018_remove_hatching_capacityfemale.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.19 on 2025-04-06 11:59 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0017_hatching_archivedate'), + ] + + operations = [ + migrations.RemoveField( + model_name='hatching', + name='CapacityFemale', + ), + ] diff --git a/app/migrations/0019_hatching_capacityfemale.py b/app/migrations/0019_hatching_capacityfemale.py new file mode 100644 index 0000000..df59fdb --- /dev/null +++ b/app/migrations/0019_hatching_capacityfemale.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-04-06 11:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0018_remove_hatching_capacityfemale'), + ] + + operations = [ + migrations.AddField( + model_name='hatching', + name='CapacityFemale', + field=models.IntegerField(blank=True, null=True), + ), + ] diff --git a/app/migrations/0020_killhouse.py b/app/migrations/0020_killhouse.py new file mode 100644 index 0000000..ee8e4c5 --- /dev/null +++ b/app/migrations/0020_killhouse.py @@ -0,0 +1,36 @@ +# Generated by Django 3.2.13 on 2025-04-07 05:00 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0019_hatching_capacityfemale'), + ] + + operations = [ + migrations.CreateModel( + name='KillHouse', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('PartIdCode', models.CharField(blank=True, max_length=250, null=True)), + ('UnitName', models.CharField(blank=True, max_length=250, null=True)), + ('Province', models.CharField(blank=True, max_length=250, null=True)), + ('City', models.CharField(blank=True, max_length=250, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='killhouse_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='killhouse_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0021_hatching_killingave_transportingdetail_out_and_more.py b/app/migrations/0021_hatching_killingave_transportingdetail_out_and_more.py new file mode 100644 index 0000000..6797856 --- /dev/null +++ b/app/migrations/0021_hatching_killingave_transportingdetail_out_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 4.2.19 on 2025-04-07 06:21 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0020_killhouse'), + ] + + operations = [ + migrations.AddField( + model_name='hatching', + name='KillingAve', + field=models.IntegerField(null=True), + ), + migrations.AddField( + model_name='transportingdetail', + name='Out', + field=models.BooleanField(default=False), + ), + migrations.AlterField( + model_name='killhouse', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='killhouse', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0022_alter_hatching_killingave.py b/app/migrations/0022_alter_hatching_killingave.py new file mode 100644 index 0000000..0e5c3ff --- /dev/null +++ b/app/migrations/0022_alter_hatching_killingave.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.19 on 2025-04-07 06:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0021_hatching_killingave_transportingdetail_out_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='hatching', + name='KillingAve', + field=models.IntegerField(default=0), + ), + ] diff --git a/app/migrations/0023_killhouse_cityid_killhouse_provinceid.py b/app/migrations/0023_killhouse_cityid_killhouse_provinceid.py new file mode 100644 index 0000000..badf7a1 --- /dev/null +++ b/app/migrations/0023_killhouse_cityid_killhouse_provinceid.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.19 on 2025-04-07 08:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0022_alter_hatching_killingave'), + ] + + operations = [ + migrations.AddField( + model_name='killhouse', + name='CityId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='killhouse', + name='ProvinceId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + ] diff --git a/app/migrations/0024_poultry_city_poultry_province.py b/app/migrations/0024_poultry_city_poultry_province.py new file mode 100644 index 0000000..31b3c12 --- /dev/null +++ b/app/migrations/0024_poultry_city_poultry_province.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.19 on 2025-04-07 09:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0023_killhouse_cityid_killhouse_provinceid'), + ] + + operations = [ + migrations.AddField( + model_name='poultry', + name='City', + field=models.CharField(blank=True, max_length=500, null=True), + ), + migrations.AddField( + model_name='poultry', + name='Province', + field=models.CharField(blank=True, max_length=500, null=True), + ), + ] diff --git a/app/migrations/0025_delete_transportingdetail.py b/app/migrations/0025_delete_transportingdetail.py new file mode 100644 index 0000000..105d46f --- /dev/null +++ b/app/migrations/0025_delete_transportingdetail.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.13 on 2025-04-29 12:52 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0024_poultry_city_poultry_province'), + ] + + operations = [ + migrations.DeleteModel( + name='TransportingDetail', + ), + ] diff --git a/app/migrations/0026_transportingdetail.py b/app/migrations/0026_transportingdetail.py new file mode 100644 index 0000000..0d40a39 --- /dev/null +++ b/app/migrations/0026_transportingdetail.py @@ -0,0 +1,60 @@ +# Generated by Django 3.2.13 on 2025-04-29 12:57 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0025_delete_transportingdetail'), + ] + + operations = [ + migrations.CreateModel( + name='TransportingDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('BroilerFlockRequestId', models.IntegerField(blank=True, null=True)), + ('TrackingCode', models.CharField(max_length=200, null=True)), + ('DesCertId', models.CharField(max_length=200, null=True)), + ('IssueDate', models.CharField(max_length=200, null=True)), + ('IssueDatePersian', models.CharField(max_length=200, null=True)), + ('GoodCode', models.IntegerField(null=True)), + ('GoodName', models.CharField(max_length=200, null=True)), + ('GoodAmount', models.IntegerField(null=True)), + ('TrackingStatus', models.IntegerField(null=True)), + ('TrackingStatusDescription', models.CharField(max_length=200, null=True)), + ('TakhlieDate', models.CharField(max_length=200, null=True)), + ('TakhlieDatePersian', models.CharField(max_length=200, null=True)), + ('SourcePartIdCode', models.CharField(max_length=200, null=True)), + ('SourceUnitPartIdCode', models.CharField(max_length=200, null=True)), + ('SourceUnitName', models.CharField(max_length=200, null=True)), + ('SourceCertId', models.CharField(max_length=200, null=True)), + ('ResideDate', models.CharField(max_length=200, null=True)), + ('ResideDatePersian', models.CharField(max_length=200, null=True)), + ('PedigreeName', models.CharField(max_length=200, null=True)), + ('DesUnitName', models.CharField(max_length=200, null=True)), + ('DesPartIdCode', models.CharField(max_length=200, null=True)), + ('HealthPermitId', models.IntegerField(null=True)), + ('Province', models.CharField(max_length=200, null=True)), + ('City', models.CharField(max_length=200, null=True)), + ('Age', models.IntegerField(null=True)), + ('Date', models.DateTimeField(null=True)), + ('Out', models.BooleanField(default=False)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportingdetail_createdby', to=settings.AUTH_USER_MODEL)), + ('hatching', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transport_hatching', to='app.hatching')), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportingdetail_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0027_hatching_samasat_discharge_percentage_and_more.py b/app/migrations/0027_hatching_samasat_discharge_percentage_and_more.py new file mode 100644 index 0000000..d71e494 --- /dev/null +++ b/app/migrations/0027_hatching_samasat_discharge_percentage_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.19 on 2025-05-06 08:21 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0026_transportingdetail'), + ] + + operations = [ + migrations.AddField( + model_name='hatching', + name='samasat_discharge_percentage', + field=models.IntegerField(default=0), + ), + migrations.AlterField( + model_name='transportingdetail', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='transportingdetail', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0028_hatching_goodsum.py b/app/migrations/0028_hatching_goodsum.py new file mode 100644 index 0000000..cd028de --- /dev/null +++ b/app/migrations/0028_hatching_goodsum.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-06-30 12:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0027_hatching_samasat_discharge_percentage_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='hatching', + name='GoodSum', + field=models.IntegerField(default=0), + ), + ] diff --git a/app/migrations/0029_apkinfo.py b/app/migrations/0029_apkinfo.py new file mode 100644 index 0000000..dbec003 --- /dev/null +++ b/app/migrations/0029_apkinfo.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.19 on 2025-07-20 05:32 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0028_hatching_goodsum'), + ] + + operations = [ + migrations.CreateModel( + name='ApkInfo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('info', models.JSONField(null=True)), + ('download_link', models.CharField(blank=True, max_length=700, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0030_transportcarcassdetail.py b/app/migrations/0030_transportcarcassdetail.py new file mode 100644 index 0000000..3c7e312 --- /dev/null +++ b/app/migrations/0030_transportcarcassdetail.py @@ -0,0 +1,52 @@ +# Generated by Django 3.2.13 on 2025-09-21 10:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0029_apkinfo'), + ] + + operations = [ + migrations.CreateModel( + name='TransportCarcassDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id_quarantineh', models.CharField(blank=True, max_length=255, null=True)), + ('destination_prev', models.CharField(blank=True, max_length=255, null=True)), + ('destination_changed', models.CharField(blank=True, max_length=255, null=True)), + ('payment', models.CharField(blank=True, max_length=255, null=True)), + ('tracking', models.CharField(blank=True, max_length=255, null=True)), + ('date', models.DateField(blank=True, null=True)), + ('time', models.TimeField(blank=True, null=True)), + ('product', models.CharField(blank=True, max_length=255, null=True)), + ('items', models.CharField(blank=True, max_length=255, null=True)), + ('quantity', models.FloatField(blank=True, null=True)), + ('unit', models.CharField(blank=True, max_length=50, null=True)), + ('origin_province', models.CharField(blank=True, max_length=255, null=True)), + ('origin_city', models.CharField(blank=True, max_length=255, null=True)), + ('origin', models.CharField(blank=True, max_length=255, null=True)), + ('destination_province', models.CharField(blank=True, max_length=255, null=True)), + ('destination_city', models.CharField(blank=True, max_length=255, null=True)), + ('destination', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_origin', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_destination', models.CharField(blank=True, max_length=255, null=True)), + ('owner', models.CharField(blank=True, max_length=255, null=True)), + ('car_tracking_code', models.CharField(blank=True, max_length=255, null=True)), + ('driver_name', models.CharField(blank=True, max_length=255, null=True)), + ('plate', models.CharField(blank=True, max_length=50, null=True)), + ('amount', models.DecimalField(blank=True, decimal_places=2, max_digits=20, null=True)), + ('unloading', models.CharField(blank=True, max_length=255, null=True)), + ('gross_weight', models.FloatField(blank=True, null=True)), + ('tare_weight', models.FloatField(blank=True, null=True)), + ('net_weight', models.FloatField(blank=True, null=True)), + ('scale_code', models.CharField(blank=True, max_length=255, null=True)), + ('scale_name', models.CharField(blank=True, max_length=255, null=True)), + ('scale_receipt', models.CharField(blank=True, max_length=255, null=True)), + ('unloading_date', models.DateField(blank=True, null=True)), + ('out', models.BooleanField(default=False)), + ], + ), + ] diff --git a/app/migrations/0031_auto_20250921_1447.py b/app/migrations/0031_auto_20250921_1447.py new file mode 100644 index 0000000..e532e43 --- /dev/null +++ b/app/migrations/0031_auto_20250921_1447.py @@ -0,0 +1,49 @@ +# Generated by Django 3.2.13 on 2025-09-21 11:17 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0030_transportcarcassdetail'), + ] + + operations = [ + migrations.AddField( + model_name='transportcarcassdetail', + name='create_date', + field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now), + preserve_default=False, + ), + migrations.AddField( + model_name='transportcarcassdetail', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportcarcassdetail_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='transportcarcassdetail', + name='key', + field=models.UUIDField(default=uuid.uuid4, editable=False, unique=True), + ), + migrations.AddField( + model_name='transportcarcassdetail', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportcarcassdetail_modifiedby', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='transportcarcassdetail', + name='modify_date', + field=models.DateTimeField(auto_now=True), + ), + migrations.AddField( + model_name='transportcarcassdetail', + name='trash', + field=models.BooleanField(default=False), + ), + ] diff --git a/app/migrations/0032_delete_transportcarcassdetail.py b/app/migrations/0032_delete_transportcarcassdetail.py new file mode 100644 index 0000000..9ca01c0 --- /dev/null +++ b/app/migrations/0032_delete_transportcarcassdetail.py @@ -0,0 +1,16 @@ +# Generated by Django 3.2.13 on 2025-09-21 11:18 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0031_auto_20250921_1447'), + ] + + operations = [ + migrations.DeleteModel( + name='TransportCarcassDetail', + ), + ] diff --git a/app/migrations/0033_transportcarcassdetail.py b/app/migrations/0033_transportcarcassdetail.py new file mode 100644 index 0000000..7684476 --- /dev/null +++ b/app/migrations/0033_transportcarcassdetail.py @@ -0,0 +1,65 @@ +# Generated by Django 3.2.13 on 2025-09-21 11:18 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0032_delete_transportcarcassdetail'), + ] + + operations = [ + migrations.CreateModel( + name='TransportCarcassDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('id_quarantineh', models.CharField(blank=True, max_length=255, null=True)), + ('destination_prev', models.CharField(blank=True, max_length=255, null=True)), + ('destination_changed', models.CharField(blank=True, max_length=255, null=True)), + ('payment', models.CharField(blank=True, max_length=255, null=True)), + ('tracking', models.CharField(blank=True, max_length=255, null=True)), + ('date', models.DateField(blank=True, null=True)), + ('time', models.TimeField(blank=True, null=True)), + ('product', models.CharField(blank=True, max_length=255, null=True)), + ('items', models.CharField(blank=True, max_length=255, null=True)), + ('quantity', models.FloatField(blank=True, null=True)), + ('unit', models.CharField(blank=True, max_length=50, null=True)), + ('origin_province', models.CharField(blank=True, max_length=255, null=True)), + ('origin_city', models.CharField(blank=True, max_length=255, null=True)), + ('origin', models.CharField(blank=True, max_length=255, null=True)), + ('destination_province', models.CharField(blank=True, max_length=255, null=True)), + ('destination_city', models.CharField(blank=True, max_length=255, null=True)), + ('destination', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_origin', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_destination', models.CharField(blank=True, max_length=255, null=True)), + ('owner', models.CharField(blank=True, max_length=255, null=True)), + ('car_tracking_code', models.CharField(blank=True, max_length=255, null=True)), + ('driver_name', models.CharField(blank=True, max_length=255, null=True)), + ('plate', models.CharField(blank=True, max_length=50, null=True)), + ('amount', models.DecimalField(blank=True, decimal_places=2, max_digits=20, null=True)), + ('unloading', models.CharField(blank=True, max_length=255, null=True)), + ('gross_weight', models.FloatField(blank=True, null=True)), + ('tare_weight', models.FloatField(blank=True, null=True)), + ('net_weight', models.FloatField(blank=True, null=True)), + ('scale_code', models.CharField(blank=True, max_length=255, null=True)), + ('scale_name', models.CharField(blank=True, max_length=255, null=True)), + ('scale_receipt', models.CharField(blank=True, max_length=255, null=True)), + ('unloading_date', models.DateField(blank=True, null=True)), + ('out', models.BooleanField(default=False)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportcarcassdetail_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='transportcarcassdetail_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0034_guilds.py b/app/migrations/0034_guilds.py new file mode 100644 index 0000000..f1ae914 --- /dev/null +++ b/app/migrations/0034_guilds.py @@ -0,0 +1,36 @@ +# Generated by Django 3.2.13 on 2025-09-22 10:08 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0033_transportcarcassdetail'), + ] + + operations = [ + migrations.CreateModel( + name='Guilds', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('name', models.CharField(blank=True, max_length=255, null=True)), + ('city', models.CharField(blank=True, max_length=255, null=True)), + ('province', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_code', models.CharField(blank=True, max_length=255, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='guilds_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='guilds_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0035_guilds_is_steward.py b/app/migrations/0035_guilds_is_steward.py new file mode 100644 index 0000000..183026e --- /dev/null +++ b/app/migrations/0035_guilds_is_steward.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-09-22 10:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0034_guilds'), + ] + + operations = [ + migrations.AddField( + model_name='guilds', + name='is_steward', + field=models.BooleanField(default=False), + ), + ] diff --git a/app/migrations/0036_driver.py b/app/migrations/0036_driver.py new file mode 100644 index 0000000..15191f0 --- /dev/null +++ b/app/migrations/0036_driver.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.13 on 2025-09-22 12:22 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0035_guilds_is_steward'), + ] + + operations = [ + migrations.CreateModel( + name='Driver', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('car_id', models.CharField(blank=True, max_length=255, null=True)), + ('driver_name', models.CharField(blank=True, max_length=255, null=True)), + ('owner_name', models.CharField(blank=True, max_length=255, null=True)), + ('city', models.CharField(blank=True, max_length=255, null=True)), + ('province', models.CharField(blank=True, max_length=255, null=True)), + ('pelak', models.CharField(blank=True, max_length=255, null=True)), + ('tracking_code', models.CharField(blank=True, max_length=255, null=True)), + ('weight', models.IntegerField(blank=True, null=True)), + ('car_type', models.CharField(blank=True, max_length=255, null=True)), + ('expire_licence_date', models.DateField(blank=True, null=True)), + ('health_permit', models.CharField(blank=True, max_length=255, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='driver_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='driver_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0037_driver_product.py b/app/migrations/0037_driver_product.py new file mode 100644 index 0000000..7ba9743 --- /dev/null +++ b/app/migrations/0037_driver_product.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-09-22 12:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0036_driver'), + ] + + operations = [ + migrations.AddField( + model_name='driver', + name='product', + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/app/migrations/0038_auto_20250927_0848.py b/app/migrations/0038_auto_20250927_0848.py new file mode 100644 index 0000000..cf35e63 --- /dev/null +++ b/app/migrations/0038_auto_20250927_0848.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.13 on 2025-09-27 05:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0037_driver_product'), + ] + + operations = [ + migrations.AddField( + model_name='driver', + name='kill_house_name', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='driver', + name='part_id_code', + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/app/migrations/0039_alter_transportcarcassdetail_tracking.py b/app/migrations/0039_alter_transportcarcassdetail_tracking.py new file mode 100644 index 0000000..aa47953 --- /dev/null +++ b/app/migrations/0039_alter_transportcarcassdetail_tracking.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-09-27 06:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0038_auto_20250927_0848'), + ] + + operations = [ + migrations.AlterField( + model_name='transportcarcassdetail', + name='tracking', + field=models.CharField(blank=True, max_length=255, null=True, unique=True), + ), + ] diff --git a/app/migrations/0040_transportcarcassdetail_product_date.py b/app/migrations/0040_transportcarcassdetail_product_date.py new file mode 100644 index 0000000..59b9270 --- /dev/null +++ b/app/migrations/0040_transportcarcassdetail_product_date.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-09-27 07:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0039_alter_transportcarcassdetail_tracking'), + ] + + operations = [ + migrations.AddField( + model_name='transportcarcassdetail', + name='product_date', + field=models.DateField(blank=True, null=True), + ), + ] diff --git a/app/migrations/0041_transportcarcassdetail_has_product_date.py b/app/migrations/0041_transportcarcassdetail_has_product_date.py new file mode 100644 index 0000000..896571a --- /dev/null +++ b/app/migrations/0041_transportcarcassdetail_has_product_date.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.13 on 2025-09-28 08:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('app', '0040_transportcarcassdetail_product_date'), + ] + + operations = [ + migrations.AddField( + model_name='transportcarcassdetail', + name='has_product_date', + field=models.BooleanField(default=False), + ), + ] diff --git a/app/migrations/0042_alter_driver_created_by_alter_driver_modified_by_and_more.py b/app/migrations/0042_alter_driver_created_by_alter_driver_modified_by_and_more.py new file mode 100644 index 0000000..896569c --- /dev/null +++ b/app/migrations/0042_alter_driver_created_by_alter_driver_modified_by_and_more.py @@ -0,0 +1,64 @@ +# Generated by Django 4.2.19 on 2025-11-04 07:13 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0041_transportcarcassdetail_has_product_date'), + ] + + operations = [ + migrations.AlterField( + model_name='driver', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='driver', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='guilds', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='guilds', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='transportcarcassdetail', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='transportcarcassdetail', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + migrations.CreateModel( + name='InquiryCredentials', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('data', models.JSONField(blank=True, null=True)), + ('numbers', models.JSONField(blank=True, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0043_allproductstransport.py b/app/migrations/0043_allproductstransport.py new file mode 100644 index 0000000..7c4036e --- /dev/null +++ b/app/migrations/0043_allproductstransport.py @@ -0,0 +1,62 @@ +# Generated by Django 4.2.19 on 2025-11-08 08:21 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0042_alter_driver_created_by_alter_driver_modified_by_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='AllProductsTransport', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('record_id', models.CharField(blank=True, max_length=255, null=True)), + ('destination_prev', models.CharField(blank=True, max_length=255, null=True)), + ('destination_changed', models.CharField(blank=True, max_length=255, null=True)), + ('tracking', models.CharField(blank=True, max_length=255, null=True, unique=True)), + ('date', models.DateField(blank=True, null=True)), + ('product', models.CharField(blank=True, max_length=255, null=True)), + ('items', models.CharField(blank=True, max_length=255, null=True)), + ('quantity', models.FloatField(blank=True, null=True)), + ('unit', models.CharField(blank=True, max_length=50, null=True)), + ('origin_province', models.CharField(blank=True, max_length=255, null=True)), + ('origin_city', models.CharField(blank=True, max_length=255, null=True)), + ('origin', models.CharField(blank=True, max_length=255, null=True)), + ('destination_province', models.CharField(blank=True, max_length=255, null=True)), + ('destination_city', models.CharField(blank=True, max_length=255, null=True)), + ('destination', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_origin', models.CharField(blank=True, max_length=255, null=True)), + ('jihadi_destination', models.CharField(blank=True, max_length=255, null=True)), + ('owner', models.CharField(blank=True, max_length=255, null=True)), + ('car_tracking_code', models.CharField(blank=True, max_length=255, null=True)), + ('driver_name', models.CharField(blank=True, max_length=255, null=True)), + ('gross_weight', models.FloatField(blank=True, null=True)), + ('tare_weight', models.FloatField(blank=True, null=True)), + ('net_weight', models.FloatField(blank=True, null=True)), + ('scale_code', models.CharField(blank=True, max_length=255, null=True)), + ('scale_name', models.CharField(blank=True, max_length=255, null=True)), + ('scale_receipt', models.CharField(blank=True, max_length=255, null=True)), + ('unloading_date', models.DateField(blank=True, null=True)), + ('unloading', models.CharField(blank=True, max_length=255, null=True)), + ('out', models.BooleanField(default=False)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('hatching', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='all_products_transports', to='app.hatching')), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0044_evacuationdetail.py b/app/migrations/0044_evacuationdetail.py new file mode 100644 index 0000000..ea0b737 --- /dev/null +++ b/app/migrations/0044_evacuationdetail.py @@ -0,0 +1,56 @@ +# Generated by Django 3.2.13 on 2025-11-08 17:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0043_allproductstransport'), + ] + + operations = [ + migrations.CreateModel( + name='EvacuationDetail', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('BroilerFlockRequestId', models.IntegerField(blank=True, null=True)), + ('TrackingCode', models.CharField(blank=True, max_length=200, null=True)), + ('IssueDate', models.CharField(blank=True, max_length=200, null=True)), + ('IssueDatePersian', models.CharField(blank=True, max_length=200, null=True)), + ('issue_date', models.DateTimeField(blank=True, null=True)), + ('GoodAmount', models.IntegerField(blank=True, null=True)), + ('GoodCode', models.IntegerField(blank=True, null=True)), + ('GoodName', models.CharField(blank=True, max_length=200, null=True)), + ('TrackingStatus', models.IntegerField(blank=True, null=True)), + ('TrackingStatusDescription', models.CharField(blank=True, max_length=200, null=True)), + ('TakhlieDate', models.CharField(blank=True, max_length=200, null=True)), + ('TakhlieDatePersian', models.CharField(blank=True, max_length=200, null=True)), + ('takhlie_date', models.DateTimeField(blank=True, null=True)), + ('SourceUnitPartIdCode', models.CharField(blank=True, max_length=200, null=True)), + ('SourceUnitName', models.CharField(blank=True, max_length=200, null=True)), + ('SourceCertId', models.CharField(blank=True, max_length=200, null=True)), + ('SourcePartIdCode', models.CharField(blank=True, max_length=200, null=True)), + ('DesUnitName', models.CharField(blank=True, max_length=200, null=True)), + ('DesPartIdCode', models.CharField(blank=True, max_length=200, null=True)), + ('HealthPermitId', models.IntegerField(blank=True, null=True)), + ('ResideDate', models.CharField(blank=True, max_length=200, null=True)), + ('ResideDatePersian', models.CharField(blank=True, max_length=200, null=True)), + ('reside_date', models.DateTimeField(blank=True, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='evacuationdetail_createdby', to=settings.AUTH_USER_MODEL)), + ('hatching', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='evacuation_details', to='app.hatching')), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='evacuationdetail_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/0045_remove_evacuationdetail_broilerflockrequestid_and_more.py b/app/migrations/0045_remove_evacuationdetail_broilerflockrequestid_and_more.py new file mode 100644 index 0000000..25bd81c --- /dev/null +++ b/app/migrations/0045_remove_evacuationdetail_broilerflockrequestid_and_more.py @@ -0,0 +1,288 @@ +# Generated by Django 4.2.19 on 2025-11-09 05:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0044_evacuationdetail'), + ] + + operations = [ + migrations.RemoveField( + model_name='evacuationdetail', + name='BroilerFlockRequestId', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='DesPartIdCode', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='DesUnitName', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='GoodAmount', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='GoodCode', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='GoodName', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='HealthPermitId', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='IssueDate', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='IssueDatePersian', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='ResideDate', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='ResideDatePersian', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='SourceCertId', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='SourcePartIdCode', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='SourceUnitName', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='SourceUnitPartIdCode', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='TakhlieDate', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='TakhlieDatePersian', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='TrackingCode', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='TrackingStatus', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='TrackingStatusDescription', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='issue_date', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='reside_date', + ), + migrations.RemoveField( + model_name='evacuationdetail', + name='takhlie_date', + ), + migrations.AddField( + model_name='evacuationdetail', + name='AllowInsert', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='evacuationdetail', + name='AllowUpdate', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ErrorCode', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ExternalId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='GoodCount', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='GridContainerParametersModel', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='IsDeleted', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='evacuationdetail', + name='IsPersisted', + field=models.BooleanField(default=False), + ), + migrations.AddField( + model_name='evacuationdetail', + name='LogTableAlias', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='LogTableName', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MenuUserAccess', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MenuUserAccessId', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='Message', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoDate', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoDateShamsi', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoEndDay', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoReason', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoReportId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoReportSubId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='MoStartDay', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ModalCss', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='PageTitle', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='PartIdCode', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='RegDate', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='RegDateShamsi', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='RegDateShamsiOnlyTime', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='RegDateShamsiWithTime', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ReportDate', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ReportDateShamsi', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ReportStatus', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ReportType', + field=models.IntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='ReportTypeString', + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='RequestId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AddField( + model_name='evacuationdetail', + name='StringId', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AlterField( + model_name='evacuationdetail', + name='created_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='evacuationdetail', + name='modified_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/app/migrations/0046_rasadyarappinfo.py b/app/migrations/0046_rasadyarappinfo.py new file mode 100644 index 0000000..7124388 --- /dev/null +++ b/app/migrations/0046_rasadyarappinfo.py @@ -0,0 +1,34 @@ +# Generated by Django 4.2.19 on 2025-12-01 10:28 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('app', '0045_remove_evacuationdetail_broilerflockrequestid_and_more'), + ] + + operations = [ + migrations.CreateModel( + name='RasadyarAppInfo', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('create_date', models.DateTimeField(auto_now_add=True)), + ('modify_date', models.DateTimeField(auto_now=True)), + ('trash', models.BooleanField(default=False)), + ('info', models.JSONField(blank=True, null=True)), + ('file', models.CharField(blank=True, max_length=700, null=True)), + ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_createdby', to=settings.AUTH_USER_MODEL)), + ('modified_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='%(class)s_modifiedby', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/app/migrations/__init__.py b/app/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/migrations/__pycache__/0001_initial.cpython-310.pyc b/app/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f40744ddc7757b4b7f2919ab40143a3381ff3322 GIT binary patch literal 4963 zcmc(j>2q625x}L9WSy4BiS3-5^&ZJadw6s0ZrELx*pi)SH+GCAvmgv&q!~*iKfTeu z_mo5_iYf}K_<}$1AHYZc3@EBtV7c$%W|t$}_puzIXY}OQ>F^0CZ+d2Wdb)dF zNsW(ZBJioa=VPsRpNK?WHNx&s9E1z-^%vm5BRuLvy3txRYTCph-B>Nwjo0E!jWntEG6X5-E(`gn1%`s80DJ2&CKc3q)tSvgNTrD%aOz zUB!jtuQZL`?oSSc3-I+{OGY9hQj79PjqqqKCgLAXh_O!cBhgm0mJ;z!nv)h-Au^pT zkHR0=!N<1ao8&`Lo&=f`$o+^sfXIW0 z97p5?A`c;Q5|IKT4AW404Mg67$U70KBl0dp7$OZsnuu^j1R|S=v=C_{ zA`$5z^53WkTQDnBm0dN(;a%>AH}g)tXp!0huHapvr_;-$7lW!!uByHhcmqu&U(%#p zD#Ue;^#fIJdV&Rl>uk@HUFHqyTVkNozVIY-R8X1M67 ze$RH~jJT#8VWsR&XPN8Fs0-R-%c>z^FNwu2la98d%Km&akXKHCE+(c z*)uO+I=LoVCD^nc4;z&>>-thp?-5^=LAxr!*1hkKSTRRRxQ?7*08*64x+{nN&Qu0qUAG7e=v>uf%`Gt9 zN|TE{$wgNxN3~?rq6}CRl)*qy&a5gw0IN-V%uHtw0{&MAJz-2S%(Sg3`!1`deZejB zRZm@&Zd2&|ZB~@QU^rrQEO1C>&hX@RA5v`9tQ5w4y)n44|M)=7~rOtW6G1)Rq1`?<+q9q`hZ0h!8HqZe#20FzWK7@BOfW(QrCQipT zrEs{flgfsUuP4Ivyu^ZL8+@qKV001A8mygO@Dv24x8$hi)|!AE^9|01P3yySB>?Bz z=%YJL8$ApHbJ69tD<3vS9l6nRws-$-X{0i-%&za|dgcx=QXC&?6;@F~` zB|V9Fm2I^h2|05+dd%>tkr<8}PC5mPHH8~oVqK@ImQ{yc6*u&OkcLxL)o87(_1Jt% zl-NM$i>$|*5GhNd%OHsJ#&G2>K`pT{HZ_VTBke>P-A!$rQM356@>=a>>5lvslB%*X zZ8k8yqZXPq+`+`+Ro3j=SRR7OJ3#%kM(7MiXZ7R)^Ti$~>w}>qtaVlOyiy%uP11+& z))RXET1tsA?Nrd7%9kLJzzNEa$sy=pCyrLGbH=RD@{E<8R z%~Gl#nAP;blHA<1XWVA)9{1Uv(K$n>Q5yO&*$eMC+745w9+Deb*6YoMLLqKb+ABdN z_ZH1#2_7qjgF02WIbE;oOuY`t+jj)CbM^X5edd^?1t}?^s=&4A#mq%8r-FYDZnh7`We7VVvD>#}ElBha}8*_wyjc*)cS zonBurmxj%Fzc0B?nCCe?ZsN_{62rdSf`S{3x#6H6<<{DdARKc+{>kLXeI8oh_SN{^8r(tF7d=q&j@y^nm4-cP3VJ{T+LQj*=(=+6A^ep)-Jx5-lPms^dK1n`3`xN=q(evcx z_%pEAPozF+&$E!$*9Xfy?XGqHaG6O-@5 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0001_initial.cpython-311.pyc b/app/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d4aa5305fac3271ba2527da26cf5ad87fcc0151 GIT binary patch literal 11245 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0001_initial.cpython-39.pyc b/app/migrations/__pycache__/0001_initial.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d246d107fa0e94b7388e3c31bf7e4d8dbb87a4f0 GIT binary patch literal 4548 zcmcJT&2uA16~Hy4ku>_SZ12kZkt|{PNLcY3q#TWWbU zt@Mm`S6f^tsLBQZ4{+rFpei}!Koz&Xa>|V}m+-nZ^2hUTQ3Zum8u#zLH~rqcey>|H zSy?Hh;Pve9@AKcjkxKnT!}*s3@Blv1He6_mT0v@J^({+}?ZBR-`{{|(cMPY4Og{_q zbdc-k9;T>6Gk-|Y3`>vQ->3U7O?Ok(>=!Uks%j}WVsXsFVN|tMVZw)!#9V}t%1#7j zLA2*lLwp_a4a7GQzk>KxU>)5p6YW=!_BF&`MSL6a*ARal@i!2E6Y=Ya-$48=#CH%^ z5q}%;cMyLU@%IpKBK|(&EyQ;bzlr!B;qWe}(whh&{x=K}--25c`NJVutt#@euI{F-JT`{6F?6J%;(9$Io?m zKqoZRXW8)nS^p00{&gzgY@MondwG!dRIVdtK`iIW=5$Bdtwz;RB{GYJ=SxOnMpbbt z`Gm;1cg*H0A2G>Ez@IZ!dcx#DM9d4xgsC)Wt7(;^?1;dG%4L+tWDqcworV148B@i@ zgdT-i;bdPp3B^;7P;dh0IX{{&m9B{ZlqwTT5{;^sEW@F$+yn5x2mZeJ4A6WhAkVyj zg~NEHoNyKd%I%OSdMYGU`5i8!SX(Q1mn5SVJ;OsOW>cdmY1|h9GgLfPwx}vBRWQ!B z#el=JWSSGg17+@NMKwR>PvBYPO&!~HZNC&YSmaAS)n8UrZl4Vs@X%@{8FWWv5^=S0 z0YBpLsK+7Ji{i&&FgIei8%y{i1i=(rQHRNhM`m?uK_H&CLhv1{qJe{{PO);^f|8&f zMe5c=$!T4LG2tPT9U>tmG0Xr4EKub(3uij^n(s5PUc1QPu(T_NJ-wDDNh?dL1)M}G z-yuWR<1u8%JqYK?Wh0sw7#UyJgV~b}W*L z<{*N}Drb|KLI?3+u3R#RpuGJU8pjEBoo0_X3uvTr!jw*=R+IL8L}GsgIaGNFx(;g% z(Qa%@0Yxcy0^uL;Gw88Mi;Kz76FKCPUy}F8@hITXGiTMKZ?7ydxo)p51MxtFc_CS z@8cN>bkhRmIP5BLEXuS#2rAK2m|5?auscjyNLlF5rL9$~wS(Rx@1Wb<_u7ve&0SSG zwcspL#kx6j&Au%4Z)#QA=EEAC#yfgnQ2B#{R%0=AW;0GzMql4jE4tqFDY4L%wgsGM zBus9qkBD3h3$O@`55o`PB+t?@35P=2bf8?biB5&z z#<6U>VpXiNd9PWQ-{lv`E?d1!a@)H7H~XIRrTw{c|3CYB*)0E!96VdMKC|Be-+y&J zHBVp7tKuTzo4yE-7S)hXBy?a3XR+cpPlcOMZSX&i&E?|APau2pclx3edbTKw(Fw?u V`|hGd-_w;Cxo{~#5?#wp{~ILOPg?*0 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-310.pyc b/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0886f4699d9e92fcdd96fc1a73602435f35dc70 GIT binary patch literal 614 zcmZuvy^a$x5VpNevf1P+5D!4bHm5*|5W17lp`64CU3ATACCg++D@WcR?9HJxG|=)G zSMV6ThFdCXItpOC3Az-FG~;jVnQwmN_T(gEB&(0#syo5h_vjppBpg5NEkkzJgx;Jg(*YWCDCghxv`U^713J#3YdBuwa zLrvq^RfR@6m=b_FlFl+}}n2n%9a(NbD^2@6Bq8Nw{tBqrHPPwv5k zM{hj|UaUy{F&=s-bM@pcWqYa@-z3>8tYzN z*{G(Jzh)iGKcTY^96Z7RlSx24T?1~67Z<^nO#fyaV8g@nrk5CvD;egMjOIl~V0b38 zP>wC_mkS-PCUrkaWV_ev-KQcFx$r~TOyX&nr+c#155xG)Aj)`}Bh{J2jE6MxCtMmO zR)n2|`8k)ZLAJ@$Ok_D{vb}@F23dcUi(S6qHl;<&L`tPYDHfWB9Q`(>ucv;fim8b4 zghz}=Bf+y&%|W)d_$1!t&jb&dbmD~91NaJa_3CH+r;mnP+k+vh82%a05cNEuX_-oE zHPlyPL@9>)5yMNQd@b2a)o@BM(aAm{%+6O~g5522?S?sfQ8-|)zITqSmE%tLczLC0 z=(ckL2&W1P>pvc^UMzlR`MNoKu2y<$ao-JBmo^*wQ4p`OSLJ(EVs0u%N$a3@W<9Rn t`$>8mLxMZoL@0DZ2nr;3zeD%$uP{5rEZ{PHaE`9sJ5dLx|2Qo>{syHv-Le1x literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..5c823a8e2c7cd560a0924194f6f8c04bdcf6efc5 GIT binary patch literal 836 zcmbtSF>BjE6n-bkvLri@l(wd{I4NY&5}b~q1l&T4OB+f`7GXG4-@}}dCG{jHcxxd; z$8Pxr9g0i;NT*B*w|43#aI$3Ton+%qCC~#seV_Q=)BE1LpKEI#s55)!@UI5IFHM%G zwgB@z1AKnNJ{5}0uc%tSJ>mIYjMqbND)#TklRNxgBxFrsldMroC?5*(#0 z%uzOa*;^DD&vIn4d8CTr8gSnpKP51d;|L|R}uUzz3%jzpXPpBwU>B0>SwHaQT zp<&Ea69RYAsnEBk47LKZnUpzrt1~X z|9;=B>O9=IV}E)j?l1c|@J;EmQ5X-C9rnJQL)GLxtte$Jg>Iau)g1T514W5?vPUWu cCL!e72J-mIZV~&7cd@>GzP^18ij>)Z0GOo3CIA2c literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-39.pyc b/app/migrations/__pycache__/0002_remove_poultry_allowinsert_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f04bc5ca2d4b6463fe40f695c6c395fb0e9de1dc GIT binary patch literal 615 zcmZ`#J&zMH5VgI|*CtoNFQ7o$<`gIqf;$NvN^u9u>6+C_mdT7FM_%t@Zw^vJ%g?xi z-$Un?ikglB7;l0u4I|C?jXm?mZ}iDY&d5G~dui?jW8YJ9Y?6{Q^6-cPFyNNeyyTp{ zW*{K@%pgO)5udVBfV^hK;0M*Qg2%izYp*-gxUfoB$2Owmj67UWKvr^K)Xvwu%usFy zi5TP;alnHkJUqgqgx9hh!k7k6;^gw*#6rYOw{4uw=kq7ZIMW$z` zuy6r=N2Ph)09xgAjZyY-UvSfc?l4Xl;Vt@LLWdA%H$=7w=c~@#;#Dz&>fYRqfhU zwbVhwPJ6YyUQ{Hky5DU@5}zvHv#EnXrIS9>>r>hR{mbKNyYm@Q56Q!03gb-tkpsyE u7r&+a&-t_Oxhk?afsJDHG0~Ge|&uW+0HS#V1h;Naw8R{h+t3NJ3s$E2rAZ8Xx+#1=M~SOE+am!7-^f zWRR5{SeXD{@ls&A?!^JvUk@OK-UWyL#Z`8&H=FIv4sT~yX_-Mzi;lwZ#npziu24-= z-k(e+52VA|o}+B+Mz?M&mDct{Wjwl8Dg&~%4#Qwq4Wnr+&${yKf``;>v@Qg}kC3HN zHBv6x-n$Al>>AD*P%Vbh%)dnEE8il7@tLXGnV&A(>KsptVaR0HFJ;IjjfIUy^2buX z-zXiw86&_34WL<8=v_iQhHMIO5@$I&DhuPM)@oFyONHDvxI4>N<__sWXMVkT_Gsah zSFlxX@oGL>5Fd-{6E29EhkGfxMboB(^^c~bX6xcl)F<^5G8s!m`X}urJmEP{fB)ah sesHV%6u+|_$97T)ED(b5Q6!4$rLuqtMMy!2DhMJ(DT5X1WO7I3=={OiDe6Q9 z2H3js9~4mg#}p|;bSo2^t8^+0cg_c@(gD&E6TC#wk_v^p9pHu*T zNM%N)sW7e!;WNMhLkdFZ!BFuO2o$gmu<`+5mB60xozSk3_U4+WVr>IBrJvI1DBKEz zF7vY>j#93NF(x$aOdX3)QH+qr%TT5yz=Ifg3WiiISUcWXO3W;IfD7G5xSaZU`xPS;pVd$o&sFePZGZBy6zpsNEmMsl*E0S zv2Em28ovvol&}o>5k_Im2ro~qywZ^7W?_EmK(0l7N*z@+OEw5aen`Zgc(sM zbPWeE&xW*RokemJ{Z$xWdL zz4hk5prlv-3QqwcVXmIM1yT`ua%P*g3Plj=JG}k9d0#WX_xAJBk_Ci}whaHB3cy!s z6jEA%c~gM*00Rsu2%rlC#Z@3szypAlJ%CjL2YQio@*RnKQe1VYIi+tBItsS}zt6nX zkHUoOL4*lSdeT)$ejQ=Vn@~0-z=asN3Wj~?stO?5pol0k#1|`A`t-rM-wqcLYX_x~ zs3qk*tk2?46cAq|LcLf98lLhPwE;ddj z;SXZ6{2{-HS&N5Eu6wQ|NInU*2WC1jH)pDHL4W;dW&v~Mtu--fW1}{`bYpt{+SIP^ z- z=e&yYh_jarA`qV$2;>{_N#p|JQW&|Q{AKCQ~NRc%=t=Z94dsNE{0ZpxUPLpsio zLY8x2c?5jTbAj<@5E|fcGlCcf7aWEcSJBblXtFmtz8zi1c>*a7I`QLIR}<2>LN$$l zFrUvKN{dx}j|MIht6#;@UwPdxSBOv8(z|oj+>E6MD!;f#5|%e{rw;7 qXJ31q#eNJMW!Ci!-u5tiaDDO`#iezRdidnYC1Fnk2QKh(NBjkxYtFs^ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-310.pyc b/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..882553a2c75df88bbdb0cf8d4ad6ddb30f8c7276 GIT binary patch literal 706 zcmZ8f&5G1O5bmF3CX?MkPom&i$YmK&FCwxli@FE*;0Qv9H0@MvHbdvfPJ+zEi(dCZ zd<zm%Zgp8yxeHFI{yyO@sCr`(NdP@4 zRp}Bb=WTdVpaFOAX4i9)<25H_)HDUW(6qvN61zwZO-i{~(J<%@l7Fbw=Uy9sk&gfy ztN^Q3fvu&-VJBIT3Pf_BKbBAYDhdJ796xR*z$p69YeL6pwn-8bYGOJq+ z8*Q_9%d?Ca%JvVH5m!$}UPk0W t(amu3JPF(k*1F2;BltAH8$b=k{kmK40o~}L=Ubv)cs^S{?XI{d{{l-e#p?h7 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-311.pyc b/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7cf54a56e3867aee1338f2406088caa5f9a1931 GIT binary patch literal 999 zcmaJ;y>HV%6u+|_Cw3Y^Eu>1c>O`Y@sS*JTs*oy0lpx4J5rY+UGQF$o$Y0orP$x1V z#MrG1b15Q!Oe$rFZe{A`DxJ#0J0~t`g1EDv--mziOK>L3NN3t}k!$@VWy~<~S!DKs%_~Tlw_K-wj&+EoV#P+=KqZ=eF z?%wwGB5HRTu>(r{FlPMD3~^|8_Yd8`;YtJIZ%oXUpyzp}473TVNMQR6d_oouT;@?; zem=wOIP5}<4WJ@r2R5|OGId@e8Hfsf;m(aj-c=n~P7X XE@L%Ci{e-x-FEu>1M>eNJdse*t7p-P1c2!ag2WCfj$-oSXU7Vqh#Q{Y_wIe~-us@vSE~l#XY^Qe-$?-c5TH1v zrL)-O&IurZKo9uPhQ4G=5J=z|Akq;aGKGD$Ag#V5IrnXOs92?Q0W66bzU#y|b;BTG zsvi>SB?l`G0NN5PzH#RSP+&s>Y>7Yz+OhCflshm}+{iBjL)~{D`BwHUER)y)WipltxGL9nlpw(*KLs2;J(s+ol=Y=2LAfa)3 zH8zL{PAS3xL4Fuhc5}%%#OcAI8#qka=l5?d$dq8ej0`-={WXL>46r8(2}Ec_144rXmnN}TBGdK= zc`6==6#=VRKdw)+7+Y%xDRpR^BO{FHa=~B0La2DzdGfIP`c1pbHR-O_-{tDuFO(=| zMVSl1RGr~!F+#G?q3iLLd%hE0N)62O5^vy5ERI5+4`fTIQY<**9 zHjkTAvpF%Fr~7B--HWoK8`tx;W@ba=H6~``6rY)`Jg-_Y)z2^Ddhu|_QkYKqIB>!p z@;(zOlO}KNwn)ozH@SDIJ<65djkh=yTS-KGE<*@^sQ_9R>N-@9jcILrQrrFsILO$) E0igHjr2qf` literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-39.pyc b/app/migrations/__pycache__/0004_poultryhatching_date_poultryhatching_hatchingage.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..465473f6ec256fd18c90f7097e9f3ed117751679 GIT binary patch literal 707 zcmZ8f&2H2%5VqrFH=A|^Cy;mmq+F_%fD1ymXJ+z#nAj|Ab)2tjPIEi4-<=O|~ zdARw?sjpB8!8p577bfy(em(Pjj+)OCM)K|FoAOh@*e~zwN=VKjo%SgyV8Au2c*d(B z3pjhnAOP{5fk3_z*CG=TUa&N}rCOE-E~(1Gs;;a}>n2qVsN1Da?aGv#LptqSQphq6 zEDL}aJQEnMB0m5pt0{yK-Ef%PjL|7YV~An4i55XNgM^0fx!H$tDy<+?(_}9ei^Vh9 z)V=QPS}LvUucc|xcK^ou22_Vq8IVxKiEnsx*ZQk178#zzXlqhkeQlhnU+xH60dcH(pXVxF!DwvyZ5LP`&jZ2%*O0v5cw;@L`&|5L!_{jKzx9+n6n_D@#m1We literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-310.pyc b/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2ccb57693fb6d02f103240bbb3dffaac69f202ca GIT binary patch literal 1652 zcmds&-A)rh6vt;j3Z+nxj{+9K#2e`i!4GbXF$krCNgF~*G)ct+u}!m|p`DSSua zd4(4gUQ~EV;flh`3a==SC!~QA0=y@(AgQlKLkxtnt z^~@a%u^lIAl?wAW1nUtWlOB&tPxy4Qx|a^r@rYOC3{A?M-nDfsUdc4V*%Hdv0>GEA znMeK}W{%6;F+CfYSB`<%;74`v+#xU^4a(ZbeB)NRMGxNDUQB?m-Soe4qaKYTxqZHr zIg?=0Chg-Pyyw+SP4`7#Q`(1o6`TL|$$^ugMp#^4zIt0r84bRWd0I5z4B;!8mLDF? z!?ASAuzexYE)&wzE9YurwrZ2SXeF6sS-fOfBC}!-1kYI3WsE(UUD6^DfKR};T?m;j z9uhu%0s}gPh6^6yB^p5X^n69^q3|cwuebGQU4}zUMwoR^+DBb+H@a8PR9D=R9g8Ic zjophgk@@-Euw~|3*e7Cv47P$1GsGMd@WiOGg!Qm4<^S!Snecb143 zIe75k!JGd9#^@j8!2{{lleaZ+(u?ivj0%g>12a3__I*FEeeLv3Kjd;IlGm%LU(Q@R zLf=#)zFMQo)=gP?k0_$pLuFjR7^Tn@qN&%28h}fw*kQv!=#zXJS0P1P7E!+SyK3gK zFw3sPN#HWSYDY-;HyAax-b&Z^2v7l2B%QH?3q}e-ODPUS4oQvAEgN#cPk#n&B3iXX zT1y&bZdzoEpbFk^lFJdEpb#! z^lOO$Epbds4DKeJ{z94#$<#eAvU73H=2OBTm5R7AIy!pYs<4_D@U*0;(_R!aGyP!CS`A_Nc<(TQuJI1J8dYDMTrV(C>{4#iCqgnNDV{hE`xPN zG?}h8o34qrFuHpVOprCvqehrx+$rve)UoJ! z4BQ4km;ldR1rBtQ@x{ktXixJzyZ^%WY81r4ZvBZH6j?1$(-+;57%nE8VR8PB+C+}WyzgY^FY=QTGsO#@zm~8EeaLzDfqSvRj$r1(Y63(whEIj zcvP6I0@0!M5pAiH>gS`0TgwZJGs`j?mj51U%Q7!+SUhxX%7mwKugBS7tG#X!pURLp zj8xXRI^Mz}Ei2Vo8N~XZyPihb8C*9~-Rbp*brWTezcIgNhBkYLH#<+)TaB#w1Ic1r z74^&xc{o`IaWliKwujGN@;;!`ith)KdIJxHYhRD(q@f|iopN6U4$h-@R2(e4D_A_&* y@u|4WFUuyDPqiS6x`8p4*@#bmK_~wG)zb{)bRF$ozB9ibI{hOQxBr8LWB&$Uztf`t literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..007b94db6b2d26ff3cbb12824cb5f5a10f2e75dd GIT binary patch literal 2803 zcmb7_&u5;`e=@XFuD|HwaJ_Q&i1S?Bc4CLy)h>N&Y_s$>FK-F29>g)SplTT9m0p z9nqo+T2xVsvb3l{E$XNiRnnq{w5VY%YD9|~)uP61Jyi+5gQ}Y7XrX++u zG4m1^#PER#F}g@va4(HtV(lQ5BUlYa!M6j_0FjU16N{XAKJXQvIoliXtPQPjm5QMy z(j<--c2=N4d=OL1-qWY|NWsJMT zL7}ViN!RUx;o&j!#eIG$E6w$aA&Rt40+-FxC-Ff^>h@wp#Mouo`c}A|9JJs06=`Dm iYnA1zYhaAOnh2l$Vls@)*Vf08*$*SLUr}Vm@!tXFw3A=} literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-39.pyc b/app/migrations/__pycache__/0005_remove_poultryhatching_basehatchingcount_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d3148aa467d1ddcd0723d670d1fb42152ef1fb9 GIT binary patch literal 1653 zcmds%-A)rh6vt;j3Z+nxj{<^V;+6G+;0HIxC_<@V(uR~KCQZ#|*g0&s?CvbHyAAbL zZ+!xvz~?dXVs5?i6}(Vqw!2}V_ySI{v%m8{^LggX;BvWyM7jL-%5BUd^g|kIF@>=! zzUYCd2qKz?e66Et=nWz|F+L$;fY#SP8XcXOC#YKZDcYf`#!J5IFdVxyh-@jTWkVRd z;)|LZLV!9NL880nXdMI0enAdQ%+Gqp1%)RRo>aJ~@RY(Og{KvsQMjz|tip2&-%)s8 z;RS^k6<$)fqVTf9D+;eFd{^N$h1V6nr|^bkXRR|qHpKzl=TnV5@>QK1I1KsD_V)HO zE2N1RvtbX%cFzqQi{Kc>#N3M=;Bz;6@cBI)!C}^apC&;pW+?fTfM*5R2X3ZyWsgzU z16KE_ecpnL1fuwe@Y#JFV%v>}b?~tVe6{ADogHG|Yxi)_#^*iHg>=x7CsU+THX3>6 z4hGmx(zF^0^EU+RF&~qjj7v}Xbh^6N4%G0FSL6&0%ADS{bu3=VG{)Hy%GUzGm#>*e z!5(Ig%iJ+N8<5zjNarO=7uyzLYuB zVA2Nd;{kl&YneLQ7kx`6 zr8dL%xk$TA7@b}@S5vcDo#aI;%_Pg>CCd_-m3Sa{#TWXtoL$=aUz+o8o`9*NfY_|4f~K)?j$iu=29aQmm@l~gEM|f$EQP%@j^{9P* z0v9oaQH}8FecZ#g8x5-9V-NUB#XUPa#J<<;;Gl`mJDv;4B12C~q*DeBJu?S=Y{$u+ z8-lqTzDD4L+ZG>U4A%!k1GvDjprBW3kDweJ%u; zf?@TFBbu1?a*k)ML{OH+^OjI0i9HbWf@NLA*pniY7J(iF1OnTIkcoE{@$4=kRVhAZ zNV8B2B5;HP6Fuf>57Kw~D`JmDKr;M%TY1rDIK*UtS^K0>Ym3X%zIxN!;u>xL!~NOp z4Ve5tnGiiJXb5GIZkWH#jIQZgUNe9Fzq9P8Bs2B0$#bNO1BY&s)1-1qy%OhDVTQ9! VS;*|mp$1-wbfQpZcUE6A{s1b7E&Bif literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-311.pyc b/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9961fd3f0c1169dbc789ff0cac9963da6f511583 GIT binary patch literal 4328 zcmcgv&rjS&6dv1)*>%_u76=4VLaLCmtxA_9MO7O`3J}7gf}(&_X@%rYJcHMZ?b*!Q zC`78lp@$xG>wl0oO8%4_Qi%haYfrsxL{7;iGhRCpERi}I343>T-jDBlZ^q9vvwszf z7U0*DyYJn(K>+?0LU#3}ox_{F^Cv(6X+8+Fnil9aT?0C}3y}UhKnB(tMh1GudoMmp zH3Q|=LAmEYVJ_>;3Otv>$RlBknE^rAZ#fxK{7$CA;VV;w#Gs}jP}7m-YBfU#IM>LM z;-Qhyn2p{P15oZ|&ohmO=ikot(ma|@7elWyLtdGopv+(?Gn`Ro=u>7WDl?o_X6RRD zIH$}opv+KGW*Agv7*b{!R%SS_%rK(NFsjUOL78DpnPFU+;i59b7s?D1$_$re8Qig2 z9!>Hs@G>i`W_uss2o2b5vbjp7^1V%QKz6X*B(WdS-8zh%x)-|k1K7fu;E*_sY#1Ut zAQZFyW4>%)o;xq6$OYlNQPx;4jD5ds@J&~2v~~ys%ypve+48WD*zi0ho{#C0Pn_-h z_+gA&Q5CVX3$O_tFWOzg0rW8&UG%oLmSNy;)M2;*x9h%#lOP>Ssu4!v)Uov6*?~@+ z?DQSQz%hkA%eqw8x>eWNnIya0E?$JYY*<8CCDg4S$z$-7nnW;7p?G9M*!d%3HJpdk z^{CgSPl?&^Jxm=OMvK_@b}+?giO}_XY~n=q8oBex@neM9_;LF$UQ{P>B!^_Iy-Li7iUi5 zjhSigQhuNWNh3O~ANVIOLz;Rp}U$ z(undYAmm3rE1lJhG~z31#JAFjpQI7;@8FbljIX5;@^kfnD)BdCK`)tmE8?b=Y$;tU z=U4$XVCa$=^dMQ`lXbnb*nTJ665ms%E7(ObXrrfq1N#us3%{2EMm bf7)hM*UUCJxqWKwpS$uVF~0qbOOn9{3+(GG literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..8ddd8435aec10f2bbd214cfca8e70a85fcb25a09 GIT binary patch literal 4198 zcmb`K&rjS&6vxN*Vs;&t9}5HuDJ2!8xK-)Wv>e(hQh-nv6%-{%kyc37#4~uk*q+U- zjk=X8wNef}=2oeHK`Zi~^n_FiG}oSbLn2kAoI2wlqCgT&r18N!@6C5U^Je@!e*0&& zY5{&7u9W@dQ2_oHMsfA!jk7zv@hd<8X#oherWWc=T?0D!79jm8KnB*@W-;je_t41N zO`}(``~DGzturh1Jqlx=L|tZv1mU3To{s@wHaE_G>lc$^(9{rU>PYjnrlA8|YNrAJ ze+b}VAkk;G2QT`Cg-Xx+4zDW*u{n6k|c^97$GMl z6tkgAS~jx6#T)s^RUzK7HCBp}Ag~QyLWr`#iC~DiPu%kM)zCwu~V7eX%SI0JF(8e{XLChQUq?Mmuo775F%vBno}qgO&`r|1 zC3B2iayU!uitF>MuG{Qd8r@wFufZN07c*=T>a{M!F?#MMG0a1#Uf2+J{eszuRv`6! z>R<8aU^adqQx`|^8V>veOfgy~^x=Ir^IG>dx%a&rBnY$V%l(i1xJ8m!ET4_#o#|$h zEz*Vu_y;zXd$V6uZG{dCxW}7K7MC?kgT1DYj#5 zheCIsCt&W#o?f-^rslR?VPz*xD92%z!?O}40p{%i$9a;#KqQ&45bodz;mGxImx}V1 zmG2_7E|QOyggMZNV(jq@O!Ltq9h}#?e}FSlg1*{V{c88Y!^SRuU3Ska;a&dXEWg7W zv)JiTQE{g?(daJl>7RmA6I3>}Q$rs!fBNp!0+k!TSjXk*qw@60#KOtQ+(~Wz*{$Q+ z{84TG_b>jc)nD|ND%Mrqf~4-Ir0x^Nx(_9Jvg=i?n~{u9cAsxa@@6GSWjZhCKMuSk-Ih&zrPf939(siB(V=Mjly2kJA$^ zJ;$=cwA#^ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-39.pyc b/app/migrations/__pycache__/0006_poultryhatching_basehatchingcount_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2458098891155eef31076fcf043158bd3506be5b GIT binary patch literal 2008 zcmd^=&u`N(6vv&U?b>c-Kf8?$Hn<>qU>YEHKnV7uD=X5fsjEP$Dn(xWmZnSM%t@-1 zBXHdx!r#NqS5Ev3NC@mS)z-}%IO8go-{-x?_IqDDxKt`4(JsEdakl0W`Yw&@EhCI= z@q~{=M-b6mu`QmksUrlatr67LiDqkU12Vm=oB(pY36de%OO50%M|46-^GaG!(xQ@1 zD(RGxmX!34l1?k>jFQeO>70_zE9rugmX&l-Ntcv#SxN6I>57uBD(O8Xy|1KeO1eHy z?Ui<(JP=}h$P0%f6$(ijI0*RG=H})LlYvM3UG%I?5+qtNdLJfgIg7iXZ+Z8D~6E2l)UL<4+N8a_S6BF@bWIBjti{jQtPY< z=P`s)o$xz*IKY+@4Qk+F7x;43IXykVp4;kTzlG1bt^>&=Lr+SiQw9w^)BAmF#mSi) zg4r9ue9CX3XSdOFKAEg;$A&5%@UooYkTSbFwvPELOe35wp){5dzBp#q{aws#hdH-+ z`eI%_0%n09Rl#-oz<|^!J3iuTO5C9P7nU0n;Hx+NADpO5<4A6wFQm>Sne>qMa34PM zm6Q(mMc+}{gV8D;|J^5FoFp~E;%4K^sz{j)K9_nLbhH`5mr^z=9v!7)p~bLuCIpy* zVf9KQnwX7Bf#=OcP^QU?rcfn`T@d3b(>#x{D@7(P0s;60e9M85iF+0C{0<>CDL!UM zbE@t~U<(B%dMwfa(tG+VVoyXs(*1m2ecAE+!0I${h{*smvw2+ah!fPgy4XA7EN%V6 zA=(HAOny{y;t7iyLU}{~oylf2UHpo_{^QZ7BrlChh8IW=`!?MmCrR;=k|oZo+6+e< SvX=Q*Lm9l5l?`RJXN*7Ka4)w2 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0007_transportingchickendetail.cpython-310.pyc b/app/migrations/__pycache__/0007_transportingchickendetail.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3416f3d93190de48a256c7276df3947b5ef2728a GIT binary patch literal 1469 zcmZuxPjBNy6!-twiPMHQ?NWBx-3!wClI==}mC%CPCM{IZf;R2NiZmK$CeEaeot?2+ z+yfGVYrX><`54^z40GkQHzW>799Z7iNn0Uo&1in_&Aj(}e`d0FyQ#r9{O;HIdq>lL zSK#hv0XTpmj$k4h(GzX1hq|uTMqiiV4|S+MwU9^>?)Q$h%~( zV)EYqoV|a0HulH^Vl$n*zcgb#+$9eoZ;zyRwoVdc%*2a@e7e8C{}EbbMUwM!iu3Ul z@`)lW=o*Z(BFzy_37Th|%DoGYQ?banN_>CH##b~Q&>XWw8jM_=NaJ)6SklKuo}n?P zIHyFm7M#s7FVPh(r6(w7IAPaR`rl9g=fvD;p z{4Gjo8s}4KrA3m+=88Lt%Iob9o{SSLL?G4?MP*=1J4$eR#qTStUX~*0IhsRIoF*#j zIw&L0q`S_g+yN>#*+Xmb^){5E_n#sJR%Mw#1oQlnnjR}hb(9Ru1F`Ncu_|~FN2PRe zB*4!&hh$n+W}OM62@$f9Evg%G9^8{Ist6(^n+QrviiE=2N9a|76Lkt9ZYqym@fzr< zIzWUAni86hOKvFD=HcbV=jd{H{1TmgH8}oK`Zqfm6|&W@>VKwgBUi70^p9A42%T}F z_(<>a@^nxyt)gH=+G_q#wg-^E3pS^<&OgesgyM8{s6WNLUN%plBUzk&0bS*g8BXI& z8YGf#RS9?sWTSsL>>mz}WiwmQ)${O+#$N!JYWn+N@bL(`1CtW-(aYiK2tpm*J|!c# z9?#L;qQM1GEl;YJ?=4DhgDnq+cmk8FHBCde{;?cG?;2fwqxw7gWBmaP<1foM-dcaU zZ>v**CtEe^-Z)DqbxOUJghW;L>$L6N2zyW|c-ngF2>Ejr$}=@7BDay%t4}~C-4}Iv SKh*&V^;Y{vM|a`hHU9-o!M^wa literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0007_transportingchickendetail.cpython-311.pyc b/app/migrations/__pycache__/0007_transportingchickendetail.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0636a538f6f0dcfc5e721303262efe20dc632d7f GIT binary patch literal 2409 zcmb7FO-vg{6y6_uSsO!aehn0`tF*;YLqSE2TG2Gb20{yIi=hISXtnkXX3cun*7{RWy$%UcrObNYzIi|2yf^dS z__vOZFazVq`G1Q)2@LZOo%kczWS*@7^DBcG#Hvi0&9N-yIh8B(Ildgo1>8BW26F<) zd9^Lq#xe5@3jEBVAm&S=4|u>c%pttq$cc#0GAZE+ou*hKn%J@wt!Sn=5-ux6L$(xM zGl@{v5mwFHg{GhT>26M*A&$m|nH-Cl9LF)RUcfiR!4l-;jRO|ehSwX2Epjx<^U)y= z@gND6+#R8IC;(3o2}f-QfO*)$-Q+sDx9{${gVqGN}NG$W=?13I>)fj7WRMP|C7V zleTeef(4ryaCcVNRIrLn(xzA38|ikcpNNthpd^v71V@XiDh56xNq4KVO1&h>p!Wso zF?S(6dJd3b1#1Xvg_=PxL2_wkb>)_{nw?#imcGu+E|N&gLcu0!PrK*8L~lQXb{2`; zREjfD8FMrq5?Wnd$arj^T2&AUQaVLCGO&LuN*Q~)$W2{Wv8*+n(p$3OvEezWNTsNK z1yv=WlB^YV!l677-IIW;m$ap4vgw)3ED7rs+`Nt-G0z|r=Eb$lXB*4eg$+n<>$Bry z`+^f6JMQ^o@D$rCYj%A7EWYl<*X?Mo9viU}Qx63vF?D*`PRySr=AFd69ldo;MM*2ox!We*dCld8=Q6qr|szH_1LJLoP5~lBqvX@ruJWDP* z$wfQ5RF4hYqZ9i(&gjIk1?w!YIm_QW%Xw#c+gUan43p;8IQZP*F!!8(s&tmv;hwq_ zM8Jb2w#(IHL-z3a{&&vs_;KcR?#~4$v*Kj#I2jE3D!WL{zU4OQXQW8|fr39!>c0j4 zknki;c=9B0I%Q|qo$Q8_EjU@#$y#8O;d0be;#@z8+oiMQJqiUBpny`S8rSF!_jESm zOl)X>w!w3~osFSrDEyQG@|=m&6ab%}e+Qrt89K9YkX{X*Ywbi7a_SsGf8|ijxBKdvq`@Z*kzwdqD z_v~LfIzkluc4j!~K1)%5IFsft&=6kaKzKwU3ehrEqH{Fu$c)UCd^umqpYywOpB%`s zp!dmbxi*HnN+JIP3I(ulJ<UW%Bx%Cw*f1oes3#c`DoI66G$d8g z30qPTmi6m}BLIr(YD`|F0P7KjsT_@{9K%qsBX``Q^^u6OTAZya8aoz%j5|8B5(Ca^x_u0PYl)4$u^&%X()EU803< z{G<+bx6a>g&rYLCfm83>IlTi$eW-tT;8@OMZ{Pi$oXFt+pGYx?&Y*xq?+!IESJd#6B83331zh+8(MWuGzx3bi9%k~adT2oD~chA3KB}HhRMK^ zCMtSa)tr`1uStastnk=a-X@B= zC5Q+%f%`&Qtu~FE%K(fdU}&PgmZUYO6iN6ifGuhmUxz)PKLwS0?}&E=87oC&jrf&{ zER#@!yO6Km>pGh#$fB+%^=3r*YBE3qd0A98v>^vIs44>7R@i``G%Pz&dqFXVO1S1( zk{+P)=JbT7`d$~LBK5B%B>gV376*83)Ok34*N9RAcp%n&M9d8y)cGpm#Jmps6bv{_ zzk9Oms)S{vlQy;N-mTY@eS{NSf`ULo0;CpIWDIgx5bjh&*;yqBnsc|2ZhZ^rIeCBx z%UD5JDO5G*DkrC>mzS;y%h}nCu=piEyFkKkJS41>_OzS-Mdu#ZoQ@^o8L2o8l`-e= zA;IP4dEOKKm5PK&z!FQBSev@R+| zl`tqzI5!jU5+QBr>1=wMpCuu+j2kbOAE*~Vg?fE4{mDuuJHG@a@Sj9mMtb{`$a(`JOPMf=Uz zh3#{8?1B}$u!j$0m(0kgwdjaBI{CQQ9-XvCC-<`l#^LCK8Ck4Fhs=?Q?M-`R!Wx;_ zGY-bg%ndtp%gWrcGkGhMw=)}7X2Z_tRz|N=RGPWLz;K(v%wNt>VgB@nmlPG>bWG7L zrWPGEhf>?$*h496D7D8Q%>6w7)4a_uS^SdC-?sSMHjgbHgLj2qa29>dtTKQwTyzoE z009D?bON5V;*b}lS_WtMEXU#MxgQVT7u2ex)R=v^> zHZ&;jc8OQs18s{qe4glM;ZgU| kH2sRD=+WP(#4{@XjB0<$4$$nwkR2JbB4e*8n7A;11H_4OQUCw| literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0007_transportingchickendetail.cpython-39.pyc b/app/migrations/__pycache__/0007_transportingchickendetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7556cebff6d8fc98254d13d7c0a4033f5d0eb10f GIT binary patch literal 1470 zcmZux&2QsG6!-WmcH*?%Hr=JmeqBK8OXvYD60Bg`q=gDvR{gkGkw)XpB$?E)y)!nu z=?%d({{tNPPq=fNE2q67aX{k0^2Scu3Nebl*Z8BSgxRtSERomZ7PdGd>oi;8`k_JIg3b%xt0|YZ7M2*N~ z)=xHbrtZ&(qOln@bS`RAi}}+gGN}i)77M0ru-VjKSYT^{Z4I>60)ZAR zwRWYgfwm57*DGxUv<-R()^09LSi1$f)@-&p-J1H-&UBl0G!nYKaKL}J_TTc}qwmq3 z3d#Nd+57&@-my;~P=_P>aAA#6beBGYzCBj{@v2GCF^lAR^wI9_?lYWcWm1UwgcQRG z^b^NKvXwH-%Cx{FrFfPJrgqK+NoAf1-T2;w4=-8TX9eMjGC4gzROV4Xv{gXLBEv($ zNWrLT<$}+MnBz+}SH5I|lZ0O}6@14;oJodLGGodDZ)m9oWg`N3l*cG9NSrX`mMMQ# zGS#XBVhT}#|2j#Uy~cz>5@4N=<}0UHApoax3PI!~L}DFSSHVjNI~I(cK+dMA*e2Vk8WU{j_1lF zv4lLs0-9-8opnc?B~+?LmRC3AB)q3QTmi&bH8D_2%Y?x^!1z^361@v!Vd;z=`5NG9 z9-zXUrIe+^xiGbBeedG@D|~TwaEgz=?H_!jg6kEWN!99A{2%MvDD*3!f_*;TgOhQn z@hJb|;;3Iw?Xu)lIa+?K+I{HXIiIoG7wl(Q!brN@)SD1dPn(BuBKbJ|8cvltT+S#Pg@pqg3Eme0d4hWHGyRO0W0{-=Xknhyu3L=rkD0-v584WQn^ z&3iI{JMsy>%^chkeeP*>?z{P1I1tc>Uw#O}vzo~K$98RGnjO?ZYt^@bo}dTl$zNt* zzcc@|-&K1;U$tuB-C>rF>aO}r3ymuR>dx(48@oUjyl&l9k>Z)IW>*Uh;UCIA2c literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-310.pyc b/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7aaca755d222e2358974cecdda591b5e95fe8d52 GIT binary patch literal 1634 zcmchX&2H2%5XYU5-6q-HvMsdG0zD!vNL6njgixziRC}PRy2~Y6DKfFidYd@GNhEsV z0@pqP5_cYh8_(b?r@jIbf^pLQD6OwpvNiLwXJY?7aoXv42-@J|_vmXEp`XfGY&JN% z(DO$y5JZd^C5CS#rf(YP5D}ADpAoUBF|j^bzD4W->NPH4E$W%lOIRdu!BU>fW|9&b z=b@TfY@6WhLeFgzA&Pv1Am1cLWcU`fCk^!h+MFyAn>0xC+$2lqQ|@TE3*3R#-np@` zx^*LMYjSind|AV9X?Rz|S2TQ8!*6T&9SvX8@O2HptKs)Fd;|D(jW;!`?*n(Q-N=Kh zG+OgL@({{rOS-S8bpu6Y;VkpFc6N5228F;p&r(q^9))8To>ER|fm!TtXs2XzpNgVS zE`C6f4XdKWAA*?js2EF|mvP*)piotD1{^08m>L`J7>$W^4`^P;OYbmE$zGC{yyzLi zg>2GMXdgmr>qrH<{X8$}0WPTQ&dg&fa)!C=9%Dgy0VC|F3S6$q8_tR<+&iH;BX#`B z+@2Za0EfOvooO{!zT1x!r&m&vj5l((=d&;VgLTu z@@8yq-L&rivYYlYXUcNEROdYE+0rEw%%gOhysa*%x|V8ku5xWX0X?MiqQ2^vhLT8W I)iu|xznCGhng9R* literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-311.pyc b/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e9f151e25e633eb23afb151f414ce031dea4f99 GIT binary patch literal 3566 zcmcgvO;6N77@ldDvMsDGRa68qen8yB;6h9^Mob7qf**tkUN)FoJLA%&+pg1Yq9-|c z@aWB(2M>smAK*{$2+1DETs?VPgD1WCPP<({5S7~4ZfDo=Z}JRaAZ^9P(zMvJSM2nRxzl6=Py-s{WC*%3iHUNz_Bj{ zj{PZc00H3_oM zz+M^3y(NttgTy|_)thlfhx9I+wHhBR7K;~*fSIme^H^ZJWoyZ{mZ?iAv+r3Gd zq%4>rAKt-a7Q*Agd}uh-EeA_H#s}$-)*>T^d4&mw)^&>pjrag~L zRK2E-=$thImG5VsAb$ zgSyZAe)J(27PD*OsO6e1=4lWy(JmH>4xQOT7tb1DC=G*ah5@0iI~440!+20P9T8sP z5n2;xfKMc7$Jxa#DR$wHrZ&$t0C)0USL(Os~sG-}km8f~5buhBLj z(dX%@ON+PWXBJ`UEPnfSun3Fj;_i#cuwbFs#4ud~q8S~jJz@&5g@rKuJD_W&eK!@P zjx}ZJpt5qKsUdaXsn*E$Zyg@n>gn6kPd*!N=qJ~#x0wxnd{ZB9=;O`KjH-P^P<#@_ zPndxOm}6V|kQirZ?fiyb+|-K=z4-f4`ja63%Un(+n12$?i3H<7ocA1q(+M!g6JY*V z3XdKDw!oHuTZo?>30p9}(B(3f7gCYvN|- z;(Rk($Z(ZZOt-o6u@WNrECj}O9gRVz=%MyiNTeaXpE8|M8pq5052Porgp~NF5PyWb`v?N z2?vkdxOv9FAK;&0;%O5S$Xq>fBLQQ=$(eSSFU6E(>|yr3nfHEu@9pc%d{3n`z@ClA zN&9mefFE3GJ}nJle~bxh009IYP=N(lkqQz75|{!=S^-GLu&gwlj(<1gNG{0BiCoJr zS8@{7Dt3{Wf$h0IRVp6Bj&B|N0FZ4c`%f8i4Pa1!2oxj)i?AR|04K^}z$aY*3j^^r zrQC6Po@*$9S~ispDO%ZVZHDy^R#G5K4Oy(TXCD@owgE2?RhuwUyTJTX0$CjbS(gN| z(gInX0$I91)@6aLE`h9WfvhV6Sv>+-R|T>%Axp%5b4_4W*^s55-2>U~e9>L7_hO`C zcR^e3%k@+BW%Jx&hmdSmtF%9#&)+iwV!D3SBZ2J}t&(jmVHe@Rv>lo`e@U6ZB$!6K z-&jHm;h|=}GaT#|gAz@+HOI-x?4aX^o8g)j%;xym^2WvvqUt2}BY&z*c^(?Ccr`c3 zL6TxLn&eXx%r%l`xT8Al`!zgi2AHOg#92&y+jMDq)+E>s*vKLZ9Xq0#SFRm|?%Evo zZ4~);9?MNY`@B~p7H));jg1LMeHiS5KztLc^Zf(+D5{lLuDq{Mw3QZO2eRJCGE5h-pa~wSE)#xL3I{Iu?^&2DU{3++=$-tTa=ZCO&g2qQMP<`1dL!s{xPyfI zM)b{&aI?@h&!ofT!)O~CBcn{^H+jFG4SO<#@RtH$?m($RsH|$+>A`w>@F(C}=>Hq9 CrO^8T literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-39.pyc b/app/migrations/__pycache__/0008_transportingchickendetail_certid_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2be0291717c5abb8a69a4932cf1b3406960d7b84 GIT binary patch literal 1635 zcmchX&u`N(6vv$(?V7ZOZZKd2c0{TK({3PyVACe19+;-JyHu4T6Pwgs;siU9wliG! z7a(!xKjF>=`O0bk0uqAfWc@L1zLF}|`+n^AYQOhl+-~~_p3@(1*w+q1zqD93gkL~P=GM#Q1k#QEe59pd&;w{`(*QP);}!XkllmU5};NlIue zLp`ystok{YR>+hpl{${Pmm0dK%+|J+(w z-Mo>u3^CdUe#^jb8+gaSmkoTy!0#CNT?1b=@OuV+-@qRj_!{u*IbJucehA#VR*^?n zX|y`@$zy1r4duO?_6;b> z(NsgDU2v_e1MTSbq%7zj&Z+9m%tI<9!(4R^v7kJM5q4BM-m1tkXL;%FA5qCj<-a_) zrvY01v=AY^+)}4fi{UCV3)dXrlX1+dcqR0e_ag8))n#1!mS5PU3ftkbI%p_wip4;hsLzI{mN z4k2%K+J&Q~w>!q7)T-6vIgRM0YU}I{SVF5wKh5anE%ObDr{G!+zmNA`juM`Qqa!Ra zIm042>i0&_O{4j>G=jc*VeYFSgx+B!z?{H21l`QeguW5$@XDVsG#vY{TXQWNeyu;( zEq})5)=lgFFS}_ka|YIz@{|W%S9xTDd6aIF_hpUB%9NAyL|4``$cAdXs;d237f|Y= GcAS4y`?O>L literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-310.pyc b/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41984aa7ff9cfeb1278fea170525b4689f1136ce GIT binary patch literal 893 zcmaJ<&2AGh5VrRx-Q6S=2S7q_M%qi1BUA{rv?}C4R5fr}MY7x-ceAP2yY+4)df@^m zq&x_Z!L85WE2oM#KteFyv`RoNmOPsI=Cfz!v&()zBDf|Wzh##mA>VDVxez0}xa+5A zfB==Gpb0IU#G&Lh0SDaA1YAMq?k6{K!JClSzd|mF9TOFKrg@W>sy3aX1R?9xrZ!g> zgI(P97c_z-6iDI#&1m8ZZ|>UyqBGwD5Bw#C&hiG`LNtH?@o?#E;L#m;_tsl_|FSbb z389ZeY@6`yP4_s8%d5%^hQr}A)@ZKks?<%cvUHZGXF`E!crIBg5Cp~*u%gt$Ji3!= z9=y_JE`>gnWqNij&KII?M({4C##0L^V;9Aa%Vu^YbdlphbAM7UbSi9qebqRQOu*WTjG2hx z5U`K}{T^fI3odOJHUd%EnN^yLT06E_um^BxyVI@>dn46|45w=w4)pr# zL_bDuYksnWovG$EhYPN!$CJ?%<({s8&lH7!{vY8_R$`u7G4)E!jdvJS7ux>g4(@sf zO+Xyi`|bG-b!bGrUn{S7i}!an_|e`ojy)5?oU5!Hz)34WJ9e8~54G~1U_BGOSV{Sk M+7@gt_ne3BA7M-S>i_@% literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-311.pyc b/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18a9ac4d47364aaa951f3d4b7fe643b5f0f630ab GIT binary patch literal 1444 zcmb_cPfyf96rX9kWm|TMHW=eS1R~1DglvolHDDqT5Tk?ua@cIrl+MuY(ruS%H_?+E zJb2{hH$V)006zjpNcOOqt0!(t;Di_7bhn_Q1k`Eg^}U(*Z+`DhKV`Ezg7I$ho3pJT z^i>GSNVS=RVPHNYf(Z6d1s8BdDo7YfXc7_WJt8v2WjQfg2X6CND#%2cL%GzR*v?5@ zuec7gA~*0uu2uparDj&+{^N-AkS$Ju7Su4md57Kv&3#H<92@@s!o@PAxAg%}`cx!H{>)1vO?Bqqr$c-RkPgrjE3mAM|?qM&s&(#^u3=F|c;GZVYTZ+%fXIM!s(3n;nX#?;{|G zg8X99+c5ftMgNBVMcFY%c8!s`F> Qy?*J=zSubY&2Aj`JJA7Zu>b%7 literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..bb9feee72aec5bf20c62dd5433bd57ac3677da8c GIT binary patch literal 1364 zcmb_cPixdb6rV}5X_D@i8Y-f#wJlvW2xSouDq66WYDG(FtB0@<(#$lQZT@U0S+F;S z9z02Jeuc{R1NadNo)!vS=Bk(87FrQ{awgejE7DS-b9j00&F{T=fAhUi&;UD)8O7U^ z0QkX$?#XqSqiM!`0SF-Ig8-T^5KI9A0lWZ6*aAqzuqtqI;}GG*_I%61Oo=QzL{<mjn zh_B#?LBYwp*~jIj<@quzaJjcHWmf7(=ahOiE8iL~AIZvhs`68{O~SV{C7g+WGO`8Q zGEiq=TNH-m53k!AP)9y#2g-0$8E##>-@07UNEoCt0tj$v6}FA0!@Oq%A@Sf6D+G$MP7Ix3z=8$>!kXFTjM<`VYAnMfLyy literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-39.pyc b/app/migrations/__pycache__/0009_transportingchickendetail_broilerflockrequestid_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d3703db26ca36a7e48d6f8dcd1e51b2934803b9e GIT binary patch literal 894 zcmaJfgc5M6(zj+0az-~il_e2H=_2tiA$LJmY#0v9XNYU`OgPVKe3cBJ+UC#3uk z{z>oL_R6W^A0Q!^bs8n0mbG>?^XBc&%=3y~FJQDTzr9YcUBuD_WO1BG>Rk2GU^WogFRj=A*-@bbt;p1md58O0c(+FJVpY63kf_g6za$KQuU)Z zsz@_b$5|1dkMUxGRXv0cp`~59$gO?4_9}?r{nsjTl z7MDCjnbb4o6Qnyt`zX_TWRC8>Ly^_96I6Lh2lc~Au~0FZ{N}1r7-*k26*<=dry*dG zA^Ba-FBT#*U6=^4G&9RM#Y)+xn129pY`Rm93A;mCV?xt44YvuJnZW)EHZo^#2r0BzGqd_xylibX;@}5#P?Y~^9`N{}X J8POg%e*nE}{2%}T literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-310.pyc b/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..caa4032ee7fe89d2fde3c7c3281a7d3f9467a0ea GIT binary patch literal 709 zcmaJ<&1%&^6rP{tHVG}bstB%yY)V`zDix*Dg+*FdAuvpHrnz%FnWU3kv1`R$H~JJl zhC82OwyydL1<^BUueS(#;2h3(e&+m5x3!fKq)(r}HD4GZKLWT-5rSRh;Qdp>+)^?!GPzTp-N)YTK4|^yS zDJhVW0c~i>RkVmh0X17}Km;+&E*NZFtnA6(_J)-Sq}V{_)7PuY*anw-tn#P@~jF9J@{%{9UO=Gw(73I&8XTUD_~bdjUU<*(0Mi$9=_c&6u2(ll_)6S1dM9yp`0{b(w{HA@v!*MzWSS?|Ey@IKX>7`%#ersC=$Y0^ec)PWptB9Ki67vHANoe nkxyYEZPV?*@ifQO{p4JCdad2X7k%>NdLz$hC=#mOVcYySqi4tJ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-311.pyc b/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4fadb531582756770ab76ec8bc2d038daaec43d GIT binary patch literal 1003 zcmb7B&ui2`6rM@4*(AD9gCKS7rHGhIS-mM;K@`i1mSV+2SQygGG@EUHb&?f5xd%ay z1rNP?s!IC@_$PR*u!m(%f~Ve6wx@b=Cc9bDRneKum-pt)_vXEC-qmUb;N!*0H}8!E zz*pgvqcSl@%iP!n7+@HH5ZW-5YzYDhtN<*%1Xw1pE0?4_ZtYJ!TgJ*duqsC)Y)Q-r zeUCbsA4e%u!x)nwbxWrB>l0`6mK(c(02^XpOBj04mL))xZdnw+8jBsZTb*zKR&eD& z-Q#WS^EDm^)t?KR$)Wv!4o|W*tn;=EravtE;myfTlCWl@(YS#!>O^T0)69=Nx8u88 zB*G+f`~Ypx*bfNZ3}SbSlIVe@}vGHs2gS~}BEaRwn~AbvIO1%%sY5!&uKf#3-b zlSC9Axjsp$cvPm{#`vDdM-}1fcRCI&d}hQ6nLO$AD#}vwoT@xu0m4XMap+Iy7i}$(hOJO?hI*}JI;f+GB zLZor+^Ws=>w$80nZF#KuExN#6$XEJ=LoP!Ia}_}A5L})8a&-=>IhchVV=#C5SOiXf I6D{uj4xnKNM*si- literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..f2d5bcebd7defb63cdb149f45805577dfced6fad GIT binary patch literal 929 zcmb7C&ui2`7@bM7X%byo7eVT_m!$}~l;};d1uZBQEk!+rg(1yMv)N95bdnYKrqF}O zf`|SK$`;T534*5uVV5}xo_br@iqMlY*^R463l8MVdo$mg`Mx*vrCPOs82txE_)Y=f zyCmhP%)n$_fFpnbh7?55g^}Va5Gddgz{&x@DuErn6wUvAb&6fJr`eSgNo<8%Q5Y~U z50g0KdX!*7Gk>lDz?_lEM*)ri0WQSARWJ;ot15tKouc4BB|wyc<(l5P^7p)CSi_ZL zy)T-R<9MMg>w>+E|J^H4T%%{&7B`=k-HBFJFHQNH<2ZLv&b&BF6PAZ@;I~76kHnbd zUP#dnOF~N6E=~MBM)tcT%R`L37^5g*gfE_}1}(?A+h1Mtn*9;?bV{q>Wv13d#ZHqFk$ZZI8 pX55>4y3Upbh2qPWL>Q|O!k;>T_NiWj`k^(ftqf`_KY$>G`WG(6?12CP literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-39.pyc b/app/migrations/__pycache__/0010_transportingchickendetail_province_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c99dc6fc093a7d24c6ec1e6627fa853a7d30c273 GIT binary patch literal 710 zcmaJI)_0M=;hYMq>xrJwyQnB2Bue ziaJ`+h`b>{fqf>xWVB$PSj8YdBt>$Gxul>z?^J8WsCwi4tm{E)*M!hIrD*IRyImBL zR1uJhLexeTlkp-64diUG0Wl;nyP&XfvGS*X`&(M2kl_Hi&)%*&;}}c~L-njI%g21Q z!nmQgqcUwXSIvnuAV;AzKeD~j(jM!+IkEC|Dcz`m3j@6Ct*q|@;v|kJew#nnw5us^ nzlePX3t`%R8;&L@6M!jrJM6V~58w0Y)9a-?4>(=Geuw=AM$^dI literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-310.pyc b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..764fe0aff17e1c528c4e8b55464bcc985d068ead GIT binary patch literal 629 zcmZ8f&2G~`5Z)gB?Aoc*X<{DY^wE zWH|?x3*Z&cB_^9R65wbvh6GX=T?!aqN~&d$5z!<}j{h+boz!g`mdoYAQuSWju64ez zZB?%8@)KIXUe`vo-d)tTM5QgL#(4~nTDLX5->r2|t+ooY_Xso=aitr){z$%v_SeXi8b?qqmsT^BN7TNLr?bccsEq5fN++(tW1X=dCueHzL3`Dzjyc zofpIuvR43a;tVe%oE)vSA8?qu7VozCo%wyL4(a#N>*s~norazE#mVWrg4R&nZ@!>~ z9H{?1s`k!e6tZY{K7QvBMfZeK#)M36l2mZPXFU0n-3;~BJP8xnXj{1joDFgZkwfub Y(CzIh%?a6yTjMY3*J54dcr5niUp%<3bpQYW literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-311.pyc b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3354e4a85be6253025956dfa0a816609648badc GIT binary patch literal 840 zcmZuvzi-n(6uz?^$F@=dRwaH_LaGpImMUGV1_@D7fgnN@F<6mKhwpG4?6bKz6`jby zz}T(-K>^V}fSrZ0NEsrpOx;|iQ(1WD#6?ip%{BO);tX(4Q(N&y+=&vxUW}-4gh^QXP(ZCZPctCtL>(iJ8>9D znuUoNpZ=`>CAR;#tvBAKLOkR~zM7RmdaO0cjQ~*9plT0*Tl#;(!~3ycyC+`6|YEs+0*oTD#iuYE*euXRv*(O2-#$?rr~lb4^Zo{_)7%;W literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25957567e67c1773a7e55eb44e021b0918b3574d GIT binary patch literal 768 zcmZ8fO^ee&7=9;7vq|XcS_D6KK`4uu%hJ6rx~MCPqD9nGC=A)mn5LUd;v^M&Q`m#Y zz3pF6x4KT18Ve2!GEWKltI*;*}L%Xxnjg1wG(rw&2LUt zDp|6gHLzS;*v~3OQl9Q-nP|0I+bvvhpXFJ~i-?6mHwq3YBed|N7-u|v8?k_5pAnp- zoQjKC+K&r9==y~WWud4)r$m;ewCyMK^qXw{svO>bhhxgZqALv6k7HMthA0y-lX3D) z?X}ktjY(Tdvv7Hiv2d_#MEWt6xQ_9gz8|Yt#R$!mG8RNM=gM!=qYL*x!%SInzO%Q}dGYdbM-JXuzD-A3u#Nwl3TKOe^-V{nM!f_QpqNY^{&1^~sf6lS?-yjpotKaickEG(QDjj313VXDf#7Om(wi zet5#KRVCZ5A#Bp~S(t8-{c^B!oO#o$Dy)pXF44Jld+yFI-;h-P$dD^A)e%C!O+fCM TSx4rPGhW*qt!@4SNy_X$^NqzB literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-39.pyc b/app/migrations/__pycache__/0011_poultryhatching_pedigreename.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1fdae025c84ff7fc32553394c9969c748f758f1 GIT binary patch literal 630 zcmZ8eO>fgc5Zw)QYucv~OoL@4d0!+nX{vr+;78zd2*)5j;EzfkTS!DJ5XQ4QqJL z8<7jn-Z2m$e=?BBH}Z$fB_zjeo?cKdn~N}Q>dNcBZfzGvO$%tcGL{~mF@ZyhZb1oI z&Vl6uc*S#x$tH~iINFRMffPn(0>)>OY8hliGzpWB{}_l)YUjdoxja~^-fP>r*7voo z%5`0SLkrmJ+9>DSliHT3v<20)9>XKoZcXoZYu!_;t-|aR0*ysn=>{+Ukgm^z8GWh@ z+NxiN#BPn5OEMTuDNB9y7IXTwMguF7mZ{-gsW4SU1Y3i2pDFcyt4-{U2+&1kwyd%9 zf|x?~3gB&=;bnxA*K6$u9Hy5bdwoogEZHAc99P!axwsF^CwD1P^+Mw_%`dx5{xg^Of$|!=BC6|B?Kq zKID>DSjYMsaffxBAT)`xlDWp{O{diE5FA1~^$vK|ylEVR9o0NnuKDQa?L+)~9CD41?d=-QC;ML%(cBySg&t{HpFM zJs=Pfu`@0D&C#094ZR%+B7FV>JHXM@4M|jZOIu($_fx=2Lo&G}8)0-Ezg96Pmo+wU zn$LWyA)0%k82I;=0_0Oeg0yk8EL+H`XYjjqSzE8gZd<_~_hH~w=8?izgpM2I2 z__Ve^%zhw3Om{~|pG#|;ft9i4_p{@Y9G5REF3I~R{iZuj=5~ga4SzH&-My!jG9lHy yN(2`?Lrvq{*32C~42=iSt367=uStcI2?)o~-(qUBQ`+I)b-wTs~W}IOl=ZPP4u~g=MQeB(1Zx8e6*|kJyf53WL`7lnRSdj2lKAd56-^ zLqC$S(qcT5J(7ONi(Kwi7%v%nEojDriB~+?z>!UaF$saUbb{tKZY~UwBy2d`%dTW)l zITmGD9lM0=%GjJO?M1$frrdq;0ijX}Avhax&fv-Ix6(UAui!QuSmQe@7t(S04{zP~ E4`NHvoB#j- literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc b/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e4e0acafc040026eb395a484332c63b799175cb GIT binary patch literal 743 zcmZ`$O=}ZD7=CAWGud5IsX?qIy$Fr4my#B|_)$T z-dp7W)R$!b0l_&4a0v%jq%_E^8x{rp_g;hQey* zunJ)G&<9s2pr%m!=gt35GWW3x5g*qh$I zJ8ibl9!#3;akG8l{b+Ws>xN~|blRj}UT62JdWVi7E#CKHKiT0QOJ${=MaK;lR>p23 qx-p+D*0Z0rkg6@`TWDrFA>=m&;#|`Pp=b7FeS5sV{R@zk*?#~{{<^sU literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-39.pyc b/app/migrations/__pycache__/0012_transportingchickendetail_age.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c3ec5f241eab399646c516a10fb979dd9957c4b GIT binary patch literal 608 zcmZ`$F>lo{5Vm9Iy}YQEI>5llf)oi=Eh9ouBm{Z`9oj95WSQJG%_DJ)ohR{TSo=TV z_po_o>R&)YLKRF2++nFrtQ(YjQB(G8sKf@a3Y3#YcpeqE?tFk zviNsw-PNWrbGCUx=y_&@UE%b(?enj#fw}0FQX(MWgdt>2T`UZ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-310.pyc b/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7309b489712228e654dda3bdfa35ad471ba8c875 GIT binary patch literal 591 zcmZ8f&1w`u5bnR(%nk`klste3VL(FEn}{YLO29-go`!+8-KtDx?dci2XN5iMHE-d? zSL%b8oO}gAV)aBxu%JKst17DMtL}blt6*eD?|(GkIAa%y+%!dGpH8?>01UWg9j|yN zD#6(+1_I<)1`_#Fevy>~b;8Q*C*`tI#G-2(Z^pKFA3#}<{Ws&ZiT7Oy@n{pEa98z1iXfb#};$nUP@G{l#GSSULH)4Z+a>b$_ z@b9j^Gk=E?CiwOI#gp2bU|?;0{r2RrCYkm1UTYHkSpTO;TN2chpxt5Z(+j30hi!tK z38^ksCb-}QSHJViDSlk4IESTiO}`5trfH`cr{MK4SGT)VC+1JDbU&j{!$RtDTkOa` D@%Enj literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-311.pyc b/app/migrations/__pycache__/0013_poultryhatching_leftover.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f366dfd8c58187b2933fdf00ecf6dccecfd6a2e6 GIT binary patch literal 799 zcmZuu&1=*^6n~Rsvq{*Z2C-s2iIwJ3)(?7+A_!us)C#V62n$2pnWkB@Nt|Sbp4@{6 zkG=IDkgBwQOocrxbM@pcWqYa@-(;JL);Gy7?{nV!y?mLQa{%ST+OP040r;VeS{i4{ zbQP67V8BQW1LBi`=4%8rSOcbg1g3M+*XyEv)DF%qUuQ-Kyv9!z_B81XqEG}ylqR_} z2Pxxm-m5Fsw|QnveN^^Bv$sqe(E}=u_C(ig?U6JzH9|@>41uN-=L3bJSau zz8eOy%2gKQnQEK#BAyGiOldu4?5Vm#7|Lv|Cj}3=s9e%XGk&(!Z!lHVPgkBi?7r-* zcad24&(6C@@jm^B1C5bFiWHW!9bsZ|1xm>~2&3~;nqaS#x^~qZZIlk!H$ORJYhg0K zG`X@caTj;*jNQer502dSceg!u+hxMW(E+0R@N2NQz(qFGn-9KlQ>C*-W2xW zac}zvJSg3N;;A6C%+-^(Kv#r4Ig>V2eTO&S_vXDf?|buYWyJ<*qlaer83FuIq_Wxq z%yuL=0SXjF&_^EXYo3NcgC{_>BcM7%JzNzn&yhaIo<20(+D}DXP1yY~;C>z^aVBs- zp)AU}%Nl_Cg3Mk^Z~_cGM8VT23XrF3z>How@ZTjM$DryC_b&V!SBx5`wULyj>=ai+ z$!_Mb?wZ1SR?Q=a)BQ9R*W2x_TO{XxoTUlR!#L<3hTXR;rY!fvi1+~$7t>@A<$QSP z=khWRgt^BK^5^dvf8`=!#Dgeub*WY9BeCCSGNyd(AY>8UcP(L(GERuF36Xh&h)LWa zbLJ2!lFGt4w6m!rW935nZI~N vrIoo?B|10n%{Q~duSu#tF=WO)z4l-9 z;_va6t0(`0AnjzUv^XIjnfZp9`6hZ}BWGmae!Ok3Ib%Pg^Ux$YyLA0C0${)m>v+k# zq)a$_&maMD$v_}qhzn5)kSDB2e^D+gl8|?8Y>fZ*`@2B6Cf)& zurdMO@KT^$q_F|c7Hc3Oz2Y#t62xS%Ms2b%|M;&yH4}Om%BS1gFJ7wAY3qmHjje6! zv$j4*3pnc5DBWOqH1ta|y49H;iL_0~KH%wi^cCHwf(L1r#uS2PkMk<4JET~|^t43- zhs8W(YKkira-}G5X^`IQN_|;s6LX^nIK;NLZqd7h#D(k~z<#XZM0D2=?1&AzDHQU4 zz`wit&fH^4nBe!`-s`HfLtPzfuVJN~IzBn5NNaV!+=^7cQvbFPX zev=>*$&E}UPw3=-5M|!RKkYsK!Tyo8lG= ChM>Iw literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-310.pyc b/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fc8aa1f7d4c96c72fdf143639b6191afdd6155a GIT binary patch literal 667 zcmZ8f&2H2%5cW^9n?$YD11cA|BIQyQ!3iN$R8&BsD?~X(k&MZ>*{mEpIN6Fl!?h2> zoA3-iaN*QfsDxmg?rK+zG^6=E^75(Fox{TUiX z3JRoPKxKus1?h#-c^HG}E(<~;fTykj^=`b3P`LikJwyuH*4{XHSRETs+=0s_@31Ikp5 z>K#4{@ySbovryUb0MpaCbR+he?bLe7KZrZT=xA==yn0qT*-KbSSAMv7TjCbV?SquK zkEfe`2)!OU5U6lyAq^lqr;fUn3x8mO+CM;(5XPgwQOqc#do=p9^^)5$bCyRwg@rV= hJ%Z08`;qe)-158g?qfxtJipt+3mTe)ZU^j;{{t+Ywc-E( literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-311.pyc b/app/migrations/__pycache__/0014_poultry_locationnamecity_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54d5fdc945793c81e430075b13b8bbeaf96eba2a GIT binary patch literal 963 zcmb7By>HV%6u+|_$2LT2tx5<=B~%dLrD_EeYCx!n3REIQ5rY-!WPDf0kz*UjsmMeI z2H3iFWh$Wd58zK=EK-K(R;F&Q(y1)GbL{d_2KvtT{NBBfd%xd(tknzz@@Dmi=Sm2D z7fvaa!Wb`uv5hFAI6xh2RJ0QsMz{vJ=OAZgFwx7Kx)?kS6_>le#TG^hm%q z(rA++1%V|4Z-OflLN1&MUD@zi zK>5t?ZJs94rXRYjVd-2Wc{U;3AOxy=0R#IyA+LH)AUX(-vY3UGg|5%KiFh=w-KX@S z=$t6R)mK_hlKb3sVW!aD6wK0~f>Yz5tcU7-K+$t$lR!^p~mASk2IBwPg&at{sZN(LbX3y*~l1 CC-rXt literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..ede32fdbfda87d65ec5109886210ef2f6e48664c GIT binary patch literal 889 zcmb7CL5tHs6n>MWX%ek;%YtZkLF%I9vh1>+L|3$+C~Fb*6beJk%%&-6Qqy#?H-$ZT z+}r*IrHf~Og5aqjY?-U4y%oA5?8!H2Lsvw>fxLWQ=Dj!X`zBvYB@1v39~gnB0DPAu zUxhiCZX-AZ28@KzAr9#%jzU0zN5GVQU@9kVJuh0khw2PF>Oiv#Cz9BTusVUCxM>ha zJ)w7E#>1Ysr~xqNWcmrgA#iXA14m)RCyuHB*V@^@=Su*`U~*4yU;6#KWK3g)BYlYC zN%Yecg9M*+DYKyF6k%@&evVChBf3uDOX0+{zuG;asLX(nFcljTp|8@b&H> zk$+JZB)CJw znQ|=F>jj9GMU6lwsg<-+7IG4 z@$PM|p86FEqHm_Vbn%7vc>m_j@AoEhcQ+#_SHIpi6(i)g54I)3;0Seih6V^wO%i0?1r?y15x)aM}0n>EYq?7ozW$ zdbF##9IJU_YN6G|*j*~?rt6B^`_xqd@=UhsxEWWsKM~lMz(!u-0aK527n!BjIY)+` zl`zAixgA2Z;CHKF)K=>-$x_@$3fAc#r=BLw~p{ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-310.pyc b/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57b479f7d48c7174aa0a49687054c66137e938a3 GIT binary patch literal 5752 zcmchbS9lx85rBaKK%x;mt*C0rqKgV#Xi1h_WZ4!8k`gSDq6t!t8O6vEy9AFs+(CB- zNl<$1^zb2X`SKLKIA412y*oW|nzQL~n$nBYoW#!T-W>(#_OssteSmiUo1NXAota&p z-Pf0m;b-r|kJa}N#bS>Nq4SeO;She^5&WSs8aHE&_*^_L+F(K>F_&m0=aN!Rn5nrQ z?^CTZ${7)`OnQu_YHT$&~-v0~2!v=b}FdD>;3XIOQ&2t3;`>W=Oiw&n7k zhE192PS%88=O>TCA^f_p&BS6XHW#O{Ibey`Cs}H#=X{*T>oC_V#-dQiIk3!97H5ES zpgpvACAk2viPJRF9Lq2DAx+ZEN{u)0pc)+^Ws1>2}#n~-&nx;a8FQ}o*s(b}rex?I7wDcE4d+7%IUWrSRX zq`%8!S4YV9NUt48F7@h81>2=yMFqP?!LC)X>lEyI1shVZ8x(A}g6&bTy$W_CvhH2q zr_kE3U^gk)%@J$2M98g*eg_onHU&Evv39#c>yC)loeHf(3O1}@BN1yQh1RHojVai; zf*n?{BMMelu)7rOD6;N7J*Lo_P_Rh_JFZ|;3U;@GO)FSM!DbX}R>4jn>(29gBIFqn za<9VDoPs@5!A>IU_T{q_TK6efRl%Mut?8?keja5a>K0qOG_aIeTDP>G*2H;3=}Jmg zex}e^=+dbB8XXoEsX>>56KR>Ij5sw{67u9~{NGP53um`Ro?CWsmNg^fRD?JY;vx}e zs27}(EtJK+g!1V~k29BOoV`SDM|zx#kmp3mb0g$=5%T;9c|nA{FhX7wA%3k8XMX6r z7e{pNj}ZTC@9gzJMCTvY>M0lCQn_WV0Hu;X-yZ7v?Htm+_Iqj-x*W^{t(i^O1cJ$gTJE*bH4j-oF z4DcaOd5-Qb7UPbF7g4@$#IX&NIpesb1GN4 zrr_yS4`uxoNLncAOG@t!1K?uc~#+*g@`l z8Fw4K-BZG##|33Dbo}V&B8vPb>h_KWBW8jIGW1_VH>{E)(v|mDJf{m}Mf~`Y$a5z! z?`a_PcL;Jlz0<57ZjfvQ39~NXz9^z<#=wl}#>XwQEpaxiN4N}3BL^!JwsK`x?2Cap zfWok8+GqR>4}{q!6^=|#*c5jL19Hn@$3UN09xjbJm>QU*xKl1Fh$x+4R%;e3#Bi-9 z!dL5-alrgByFMd|mt0z3C=Hv2?()o(US~6ghmo5dJFVARG9;Y1tS~{*tj@R3t=+z> zX6mk6bi-0Q-!7(PCGx9J#p z1{L4$n)WM~s2rjty`L4W;fAbig>cXy3O9AjIB?A|*)$#Pe9`%vf{ z`UulaZxK}+hDhveScpY-gl(PHb=b9;`tGyK8%-&aS>Tqif7BCelyu>8I-5Q?>^oqoFwXi|13XZ+a}Yk zKoaG(jz_<50#EIrnZ;v@8FlL@UQc@H5+3F@2RhHwGPkhi^WM^Mr8GP`#$ME( zH^!U?MaYVu$45pFoWyH}PTRV3a=KDJi3>k@@eSEYyiM(2b!m0g%NYGsX2Vdk?WE8U zz9x&gS#(i4mQ6rB`9!h@;t(H*!;=F5PZSdH-$D}pQ%J$TwH|n!^uoVL8vaQ#@DGxO zzmpvNP0Pb$S|9wC6yPsfKm3_!@F%hc{zwS?L0b#I*9PEs+B*2HwjO??ZGa2fM))<^ z1ivDi;g{qx_yySlKPOw^QF1x_jBJCSl0oy04F=) zdt?_pLW=NR?Hc%wb}f9HTnFDG*TXl-5In5i0N)_H;p^HS_!`*@UnMufSI9p2vbG<- zL~epFlAGZR6@7;8WyI_#`<5pCH5VaWVoQBPIAK z8HJCKG59bUhYyj%@Ii6}KA@H1{n}mdKJ6&HmmGulkO_Du0l0GlvqL|@1 zKQf1Ewzc3VQ6?aCUgn#hD4SN{5auSnl^qJB*f}r4^>yM$gxbaE^;>U1#?uG=guX)@ RMy`0xoChtQ#((P*{{w@H=V$-` literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-311.pyc b/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72635c1241129e29eeb3025c1c45082e9087ca76 GIT binary patch literal 13301 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc b/app/migrations/__pycache__/0015_hatching_transportingdetail.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a182fbd4e31104f3cb4ea6259ab656bbe987a9b8 GIT binary patch literal 13690 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-39.pyc b/app/migrations/__pycache__/0016_remove_transportingdetail_certid_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35bf1dd454fd425e08c1ac4c807e6b97b88e150c GIT binary patch literal 1096 zcma)5J8u&~5Wbh~^TiHMc(oLO_7}oNrcHTmdQDw9AJi zzyUXPGBDDeN*6DgC%0!~L7P%}pa%f$P zYmJm`+U0i==)^8Ku?KGA#y$q)nmqu5sW->91zcaijRhReaUGfvVPhP^3bdv!w5PVB zwXTx2`JeU1(%4RAU4!+73f|JX9^9nZ2yRj3+f(oFdEUS0C9QY`?hsLTP4o37LqwO) ziz2?axw-X-jkq3;giM%LT$V+yG%0|Zi`1+yvDJI1bRR0tEzeBy3{6nU&OTQtHA#x- zk=LxwEXPvlJsTJ8tNc{RA@;#UqAVxKfNM12WgEudN${xaQpHJ{c6}AnuvC+TshtQ+ z!34Wi!Ye${Z%$E}`aUX=!-Y#Rl-B?};geLGpeOYC#V2dE?}MMQ6lJ1Eszau|Zp(zM z>YXtYF-C7@k|N<2WA7$BwfC_aV1W`)4h5FVvu&&#V3wcai>jG$2cSaAx4u?iYD`eg zoNe3bk;vw;&EAO5JyBlZ{JDN~)O|{=#E;|MCxc8D!@&VBIh=FF4i5VR8rI6uOPVA*NuM8Gp>zViy5D* p4)(f%X~LMxB;SCy6`2)lmGg>(8G1mSn(*mtEYB>trDeb4{{e7dCprKC literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0017_hatching_archivedate.cpython-310.pyc b/app/migrations/__pycache__/0017_hatching_archivedate.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd27853ae16a24af77fe3684f9583836cc21d798 GIT binary patch literal 596 zcmYjPJ!{-R5Zy1GbxICGV*C>ff^ax45=cU@!NjDn3pdTUY5_8Ghv=nKx25n`Mk__xiT_%^ACiR+8A#+y`9l^G)G5o8KUB+d5wfrbz{W3P>ZwhL?9ubD36K>W zSRsH{ypX7tNgRNa{F?Ki?5b&UNgCqb+L{(A7BM-i zv4P`!8d5#RwGNr4ez0ng{O4MKUzsM>Mh4iU1+w7ROk~ zx*q=@?H6;esA7b>4+rl{XS{(+9o)F-4L*P=hspTm5d@j`6L Ee`JB6x&QzG literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0017_hatching_archivedate.cpython-311.pyc b/app/migrations/__pycache__/0017_hatching_archivedate.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f8b42761bf7ec57a092e2314ac0f2f3045e4e44 GIT binary patch literal 805 zcmZuu&ui2`6rM@4*(7$s2C3UF*B2*TOqCME+AuJ4W-?+_^Urw?GPwv5k z$KLuMRHgNQsj!D-uAaQ5Y)|##o9w0{btZZF-h1=rec#KMR?8u{K5qUVe5Zu`R8GAb z3ou(pa6o_njYv#=8f(5riAFXFXrBn^oDTK6=n&D-h3D&FY!k2XOQk(cI&nAsVKr^0K5poi1j&oz=8x=oC+?j z-Jt02VqRX^5D4~oHz@dyN2QUBqR7)xty0L6Am$iTw(&0H5o~$3v{)5qOgaqjgHgm0 zFERFh6h!K*@_=VN0iN_jo(nZpX>9;JQ+EhMxvi>Y81pJ7oiyW%@qQySHG}g9-N(Jx z+s}Kbu=jWPJ=FS$)dE;B=MTt#HTxh;EUb(I`3{=##V$=^Kc%IvT{FioONZFEKRXla z)^z3WbotKIZSS`yZu@KZ#O?fWI}^84HVxZ3C1}o+DRt8|$1l_tD|MSK&yY3@gJh7d z!rMw{C2vmTx;j>!y@BZ5TAxqriMWZb`qlXxG^I`{MRL?TA@?sorMX1Sl3X_X&gAO7 MQ>R4HwiJ9@ybG1n^UnYSk8C zwx_@aFkmQx7zHRc0t0~o&wv?cz)X&MxJp`nhvpmy=D_l6zcld;>BeDK&>~EeT;e!o zJjy%E9Dw?Q%-$(*0UQFvATSu}qQEqOTfI{7zbT+(Fnxx5H~)`o#;nWQP+8OK5?7*B zHG5F^ZRxzK^eAyA%`(~A+S-0d1dr2GP6|PjJWE9pCSAr08b+kU6=Q@ZjKrzn(mtj| z=UAP~8~Z|mQ+`Mb{?=1&Bd+iY zAt!wr>ARXSp7Dh7q!aR7=(b9GpRuR9hOjhkluw2+FJsb8Grnl@SD0z%*E>%hwO_w^ z-c}CV%MrAd*IiN>Aat&uDgCW%AoNhnO@mzj1!pkD;2fZ-Y23yiUrt?cHa@#!dwpcD zPu3nxZrz`F&GY8iYmU6;m%|_4_Ep_-+^LB@{ON^Qs|p_ZmULK;Cf&5f-j|k2Bl9Qk w=xgQOy9!;~kLP{a6ZaI=qs%wdHZ>7Ke=s2b3a=o1?v7VCN2{B^L6I{1FBx>Uk^lez literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0017_hatching_archivedate.cpython-39.pyc b/app/migrations/__pycache__/0017_hatching_archivedate.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b642b1aa9f979fa4472ac6c0f9b2ce0da265786 GIT binary patch literal 597 zcmYjO!D`$v5S1)><8`}`L-Gp+Ls^nb3#GIh2n{(jhomQC5Q=BI@nXrY3ElT$zPGpkPB}E)C91(`>-)|P zja>o`x@lF7gg|Kv%5)AxcA(fwH*eyEJ?>*`c{4cFSK)3f7>L|4yOu1NlS^`uGZjU*sR^Zwe!e;Lp1 zx5;H9d6cQ-34Qrr`8cvCg$z?zX}j#^a6WE3?l_XqyKJIe>JqY#8{MCx6d&bni+@ag BqLu&v literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-310.pyc b/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..391229e55d337fbebdfe0a81429d89a4aa406a0d GIT binary patch literal 526 zcmY*WJ4*vW5Z+hfgmU&Om^CVjz)^ z#iJYwPy-gU-f4~n-1=D(S7wqFc^$dZqWuF!HsrwQIgj~Jq8hgxFsNric^g^;+P0m` zKeRwtY0A=WY;A4t>XDg5qa=^Dspx({FcY-iU)8Q0o6kCv+WK14zn$P8DNPyU>+q{SAyi&$ZqdBpNU3CSH1w;7LM=F~LAIN(|gKn@onzvvkv6b{7&(?!kjc zZu|!rgMW+%4rH#Lyp=2`y!fWu0twEv-@G^Ty?)=k^!x0r4>Z24|Bbd8z;BbZ!)b!a z5(S5#K(Pc;)?*ATSO;Z&1;vpKthV5Y102&k9X(6gTM#&ZOd2rlr*TxuQJiPPu%Xn8 z-6WG`3Jw9G#}rU8i&&3afcBs@LXwLAw2w&e_)?Tuu5w7o)!v6zA+R);MWG)pF1~mv zcH}7BiL*$^lGZ&`a)i3m?&>?MvXEgs+F!#|CP=k@nk!61CR5b5!HwXS?udFr2<;0& zgxv%wzAeP(U6~k?$rKitDa^tchoxzSp4r4S-@~;S6Q%vUz@`U3U}7$QvGQiQzq$3c zPj>rP9qN&dl3hrN0P<9|AjElq^HmRy}Zl;*JRI6jtRgYOWNhl!E_hF zB`8oNg^WamfCKMAIp?6LCIh!MEcOYV;m8@gq4(F4kQkmN{Ys9KA|J*JEkJv~w2R$K z&=3&?k)ueTMAQN84w{hvTL7bNp&69mu$~YN~4|FC|jb5G=N~a>1nKrJihv6gRi>4uj;XS6G=qH3&*{P8^K*Cyz8Ij-z?Y6?Rz+`@7WHG^QQrp`M1{;B2=y!y#+{EcgWQ9K0AEXDjL~3q6fb_d-}WT8B+XhVE7VC bO$j0Q3`pmWEfIFXZ&o(1S2phfN#p(pCJ>q@ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-39.pyc b/app/migrations/__pycache__/0018_remove_hatching_capacityfemale.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d7a0912c8bc106c69aefdfc1b6360aeaa604a26 GIT binary patch literal 527 zcmY*VJx>Bb5Z#Xh;RLj`wY!F3r7=cLG#E{!fbMe1X1N*R$bESSL~3pQA^sk_ZLRzZ z7UJ9i0VkQ+nKv^p^Hw*THY0oayb6Y#v9F@oHH(UC^8A-!#V@ZtN%+WqKMUaqbt;uKgoL=5k=P&PUvpXiX{wF<9?{>MB%-v})>) z8#YH6sngUw>U2&{)mTscaS)G`&gh*Z=qZ}o1~si4ooYXrF1i@$5NX$r62MT!IznR= zvFGfWnkoUMjI9(6%tEBRq15wChs97)0j3xO#(sc#CP-}Ka z0rku9^Kg6aMRDqTeVuDq=uGto_Z}(mwjbn?mNS)=Y+FhG`u3;t_IA3+B(YY>^A?4g v6icgOalyr}wJdu*N18fJbUaGhFf5NO@$EUQ?2y(??P8_$vS7^%K@Ir_AAXE4 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-310.pyc b/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9728a305cbe2bbf8c0d39eec800787334d6b9176 GIT binary patch literal 599 zcmZ`%J#W-N5Zy1|`A!#v5by^gMRIcrRDe(v1PV$)3X;mQwAy$kj*s=)tnZMnPTKqs zI(`e~wp8>~k)kl`Bubi$HBUS9Ml+dULV{ME8J9L1qtg-ikREG2ez+UX(WejKgZiyB8Ar+== zhqssZllkXVFu>)`r+0-ny@9py#n;3Ag47oG7hI6;w~q;)cWWR25LZ7=9kxgassOH*-sdHLQ$n(-+4!0C=xba#T-r(G}gxcWXkoc<$Q G-FpsZ?azMz literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc b/app/migrations/__pycache__/0019_hatching_capacityfemale.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a832a594c12863b82f1d372f73ede6f134d9a51b GIT binary patch literal 737 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

(O~3Ma};{bZ4E4V zMbf(6!*7){q@c(b$4uuU8W$A$c@8hGAX{ gfI0gINIV1aXQ20$Fv19r18!*22~EBRWa82M19YiifdBvi literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0020_killhouse.cpython-39.pyc b/app/migrations/__pycache__/0020_killhouse.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b23307ddd27fe528f0062de025afd312bf4589fc GIT binary patch literal 1404 zcmZuxPjA~c6c_c+k}M}_;vr{b*pB-e`wF}9x>Juk?9#)!N6ASFWEA+o_j}~~^LwO7s}&e9-v9Z6|KS?OUt0Nc z*r4pf%=bZ1gCb!hC_+fDO<^WhWF>ZFSGpyf$OYUIji~X1L2c^%Vo--!Gw)|B@~CxY zbli{N$LJvC<*X=pI>|ex3KBk%q~KYaD>um~6ZuK3_kB6qpzOlTLu44th!8a*lUcvo z%$d2rA&Mqu)X=f0NiF8j0*DV8P?t8A_SmEzU`-azT7cQqUs`|#fUSYnTq4lImDZ}X zHPF^!?|P+efVKfUZ^7KG&Tid6+BcBfH;_AkXdgD)oNdkgS$lSy-qjV*ua*wvaPNQY z_pj}fCjFW^9MSEiH9^rG`VDaUt@4jA2?RDRGM}sMZuil5cuI8vOmZUl2d2WeOpdag z;glpySzzs0szKS9l%h}`qr4y^2;!D0e^WBmtQ}$sUZL@IkTiRT356igZa!XI8oeq5 zFe;~zB%gMW+<=~|;5CuO5$(a<`1lC`i0F(2NiX2;koQ=ybW%)}ot8o)+URr}giRSm#^dSsMC4RHav+7(sqm@`3h)yU@6T|epERUWRKVyps;;dCh&tV4|7 zltk!L7)wj1)6U;PUp29i)tsf2rSU?V+O)nmIDd%;X9uVF_^1BCk1D*{!C9`Fy{e(d z`dvx=o>jQdCwtK9L!FQE2ZN)2y|l}cQ{`y+M78=*^EppgZ439aOfZtJ4)vx)*2~~9 zlZ;Q&S8z>SIwR>MQzjiLuVN1#wQBVC&U$p#P=+kM={S5)uJ7t#R-KFs_f2+st265#REp#f^ a1=Xuvz?AoW-PPy1i@66PL>tIMp7kGS!le-a literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-310.pyc b/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9e0a63398b95d7a114113c4a5fbf8e169371c21 GIT binary patch literal 1095 zcmZuvJ8u&~5Wc;KeLkP_77`K_5&}0-NEsm%lLtg0i4-Tz$<+iF(6qQBK7+E=_Nk}OtD zTL=9lmaItfOzBEL2QJic&)D5Q4OF)As`vPCDf42ykqt^&VcLs3Mvd8VKzIV(8O?&!_x zgGW8VlxiwELA#@-r@gLV*_AXKplf+XF)=T=4kZ_*XPMqEa$U!w5-g((wl)tog}bBU z=BoB-SvI9QpcKD`f}(7%Z_pXbakiI-f8Xb=^!8Q$xeQ<qxlCKX&(!(r1UbR^YfnyW*w_CA^O#P{FfHqv-Mt{U5weRO%Ujo#E(h4I|J9tT~q5*7UX@?uBm3;_*i;`nD(EH Shx(MDrcA-1y+nL+$N2-Qr9UJ9 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-311.pyc b/app/migrations/__pycache__/0021_hatching_killingave_transportingdetail_out_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86043817260e9ced78863cedd423dfa5e423b81b GIT binary patch literal 1798 zcmbtUOK;mo5MDk-((;RT8x&1~x`|sW2@Iw1sVIu7v7DxM9**sx5sWM-?OLWnkt#{K zP%rhNhaPk5KX6^xhyH*bdgu?Z0Um_C_SBmUyO;FR*_B8;i4i2|lAN8H-T7vAXNJEF z4_gSv54ZoV|Dz)G7Z=i@4VdEx!2FB|B9e!iQbm$DFMD!RsVGggq6%5@w2CgH+lZ(? zBBD{HkxPMg6omHR>yJu~C@ZL-|INjM#Egi>vFq2Pg3PR@TMwPs4g84d&45rZx>p<6 ziD_gY9RDuym?)}91XW}ifj@}9Kd9EwQ+@~b?ZMX{M5@b`oY-w-I+-Y-F&pA0xR$8< z+KYDk`ip0H2_Z)efiRR|n)}upAmp?CLnJQ{hBJ*yR65caP34A}abp=bo^oXP?3wpR zb|80qY5vf;(Vz7_`oDaSy^Zg>TCvGE~PPmf9W#K9BLYZO7wS7>B%~ z*<|z`+>KL(bwXRzC)BTXLf%enw6wPR6<%8@Kg4(M&zF~2KHK5ah#4h97Wj39ycAge zjvv!H4TXy3zYGG8I(}cWN?x3J4`1H$FB!WCRJvL6GLyZ+^y2etD0Pjgo~BId+e^JXGB5Jw_q!LS zy5pC+_Vlxl5_@`g?!Yb{+Qq~!_HwFe9U&kmob;?yi|gI-cQXrmV9y=ebBR57j>To} z<5Ks+hr-7d?&Het)!$bCc=YGvq`a1tpCsjt9zt8vq72gm`5XC!Pn%qtaOERGK?VHl z;V*aX*TFAwz-9R{hhLTf3?Lf=)I0nQ~V2VlD;c|b#1~G^Srt+J2XMB>+W-In literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..358084b619211668c96400fecd5dc5668e510030 GIT binary patch literal 1837 zcmcgt&2QX96d!-A*LF5(;)E7x6E#hit|^KZ)Dr^KZR$Wt`jIb0tf(XJ&g{lpuf5pb zpydQo4;*{rUkFML{0VU4z{#T0uBHbLoVYDYBBY)=W3RJ?-AFy*gXewC@4cD#^Yd@x z<0_!f;ceMI6#@8@De05x3&$H&_yHh*I0rO1ljE4oJA6Yhg@$N~u`W0nQ{us=0Etfk z%3z^Bkpd0YLm`pPY+KN!znG$PL=JEm+HNh-d7?J#ns0@+=LSS-cnCYe{mK9UfE4w3 zjb~M1U~&kUJP&9_`PINg#+iC<*m}q%HpJCafBG1A2mNXn6V4$_+=qQ_7!MtXaMPedY~sLu_1>e>j~)e*L9!!|TN`VNmK4*LxG z&-q7Jec^wudh+$Fu8F4Bp3*g<+)K$vnJ8GzCYdM}KPbY-w&U!1tpF2w&k8Ghl&eHt zrA8{0_VE_wu;{iNM;9o68E2tuH88cYccyA%2N5mwEjMU-K4UtXjKD?YYDj9|I_&2+v{ajYQF1K78g+j@p%%8une_8Gs4;<=C}#vvv-A3O2R zI6WVFWQ-PN(=uYPnE_a8F1PRN(?o`G*$@&HLh5Qcn94Z_ziL?y!-CMKGXjvA;A?s} zR+;({ZekZP28U! zKZ0YL1iV;Z{&06=^X@LKd3P{fc4=qdhiNj!eDa4Ra@`duz{<@sJln329+>*auQg+*MBW&7;k~$ zEkxSF!QxL_KY#J-&M!M1V>>doJI15Pc+@efkx}gdu+OdXba}{s$^XNaJ^t@xIRRkW z=Fdqm*VSG>!5T}j&hM}U>%7epu!SY4_Y=&&p-JC;?%zo7Qad zK*{f++m?!sh6V}5?D-V|d%Dr=w=+BYeKWLP4-8yyzC2BSIEL|6Z*DKdjBWho78)?X z51iO3_cnK9@3{dExbF>cnVnYN*>MHzwh?*XFyDwwYxz z@fxfm$2CFHXRPtQnUG}Nv;ykFSC(k%D<#V?-Kc|;1EG{TG#9hb#cUq^TZevb=At+`(o)B(n~eUB_P0YexR<9mz%op#o5-oHd5y+{IEp{<5hZJ20)^j^~&be!(xt z{oA`c$I$y;W=FoNO~^HRnYfq;TAd=$Ew!KMc4rPY%5js8nGpFs%~-!>!F}RwBBuPu RlfFLDeUu)W&|EQn`wz>TKzaZG literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-310.pyc b/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5470cae3009c1be17a9e715d963338d8ac9fb92c GIT binary patch literal 618 zcmZuu&1w`u5bmFu-Ps`lQOP3+0}|q%L_{_a3_+4ZavKJkcB?X(wdcp~-ayWJ&4c6# zd=HO(_2k`?5MuRgLUOR6zv=qvud2T3x3_afHvjpj{=pgh6`iM+kh7rUUJ(ETZdl7p z-ilIicE~`0{LVlkU&(K>l#raUBK=LZtPmk@o7!sM^qmWnwg)tB8B z1y?* zF^0bS5|y{Qb3<=E`G8(GM)hm2bO);KEr#sjQOG}SUhQ9^B}rJp!xZpbuZ=Gx?G*P= zoo+ECBc|sK8aOFtAyZ>qsgNsTg|$JtZz=V4txc?r9^il-V7F}0SwZ|E-!~rZ$H-!3 z3~U{B9_#y1$om2BRlH&L1r?0&cX9Bpvf635(zZH1JE};4>QV8Eq?jumssAU)?r>$} z&yD)K=L8uOGPz4q!3EEGa+}?a`I90EGg#@a?swtyIPf^+n0%aOb9+fVA$z}B{X-Pb K#U9VZj{FA?)~KWa literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-311.pyc b/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36a19aa8a7eb6b61b7462877b5a6efab7aadeb8d GIT binary patch literal 827 zcmZuv&ui2`6n>Lrvq{*32C*Vk5UiL>S$k2W2nDfJYY$dDgoR=3Ow+9SWs)s;at|In z_SXNPD(&5Wqrx7Rxq9-JvOU#{Z?c<;v@^+@@4cD#=KEgqb#Bf99G}+y1V0GCFXc3& zH3O3s1P8!@lL%tslUVaL0vfCV*FFQ+1?lTe(jlUw3(wcNu?1f1x7zkJ>BM1>vocJR zLYi^PMO17znQCp%oQaR%00j7igRgNC5MS3o82yG6Ud>g+>^C{UjpNoKia5e|I*!f% z>0lL$w~>$~?N<#Gq@}YglaIUI<%e{amD{^v643Wy6yeJD1TAxx6j_>==yOrBFrw+8 zq%7eyPIDoxCP_Lkr&+6eBG-_EM`W9e9X5zcPe=7iF-=%3q*2?}PADS2>Dkhvb(~V^ zP^`)akwDy`^uvHf>a6m($V9?LvK@*dS521AYE+8+xvG*ID$rR^N)gOL(n&Kh>-Tq< zsHU7hdiJFEdTYIhl6(KYMi0d=Q>Kbt)quqH}9y+OwzmZFJQSP`pJ`>4Xp@N4yhwaQUgs4lygZ SZ1$bewR@*(rs>B0a&}Y5O`!*m zz4c#E(z}0zr+|R}(rI^&0Q5EZ_uW}y2f35~h5N?kh)dBhHUN7|&c6Cz!r zva&(M6>bpnen2Dbs~O`NPZ&?SATaUtq58 z;qv~Ihn-ii_d2TO&T1ze)%-T0I@$k5u$2vkUUjK7$o1biff)v8AI(hT8vd|9bHTa& z$(`8EvE7_*+?if&PQBLY-HF#4d#%s(yVt&`TaG(3v4=lC7aLW=1K*Mk>(iu{Zn3vz zV`VdoC$DR_()Wf!m-eH@bauo|MfHO7TT0DLgwSsc$iKi1giqbc`sR3j^A{*mM*jgf CAikvl literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-39.pyc b/app/migrations/__pycache__/0022_alter_hatching_killingave.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12c21ef836394e29ca7f78131ec7eda4526274ea GIT binary patch literal 619 zcmZuu&2H2%5Vm7yHygE55AX^|kx*57LI^=CQBZ~Gp}j?sEVDCBvp7z$y%jyfwGYA* z@F3iL<-{u>p)$_4Y7dO%vFFF%%zW0{+a)9U^7D1~gERIk84pF0aX{NYAq5P$VLh*T zpVb*>?-*ntzA+HUSK_Ov1;{g2<-aMHRaq?iu5~(egY|LN4}iumQ|O`0$T*hKaBQNk)7=YZ#WZ9*kzrZk7L zy2mIdou7AT;G|l_LQQ_9VyOrf)&}XmrPSxOHYqn*fFoK!yX?@rjPPT5Xac&o3B`%z z*gCcW+gn#GhY@dC{Lb7XN|@B2qc<;_-j2)WRC^6q+NsmCv}iAbfQJkcW7Q+Tj!Gi#F9%_iOC72jE}{X_gu zJbT=$r`|mkL}#}x?|}m|nQy<@o%wdt@9yRVZT9nbtr;P|JlM7f!2$aC1OpJDnsl_J z9V;0nZwN5p-w1F;m;5U)IYh^#h%d306wKvaTU$A`y%}B7^`P`vd1~7-1PAEjTMUYn z6iCT{*0kg*TE@PCN|rkiL5!YUaM-!HWzzqdnw2SJI7IHU_qW|~6fTFsJ>K7+&4kpG zvZ9ew)wHG-r>)lbmFLQ3K5zQfs9bW`PU|^*y8MA-72L%qTAEW-B)29RfmRsj75C6%tBCWds$Xh{1|~ME?LrM#ds#h;C)-<|>`a!aFxElrSLf?C-vJ@7}xjy?bA&SO~_;wI4oL z5c)2SVw5IiyaHqoQA9CEUF_nn;wl&^Xbn;26{0G`9kmF02kg_C<*HQMK(*4Lbk`JN zbpt=~dO;MXLhnYD@w8P$$~7+r*6~|_J;acUDRLExee9|VVp^vt3a+MdNAHwnpd3`A zC93V~=S$cxpSP#782^*SS6qXdAk7ly!$K1XRJ}MB3rkD&I`MdqC8X{3TJ0e8$yUHQ ztll;grsVCYpE990g5HippB#P#0X0>WHn|sWL7%)AgtO4^wS^Y;IR}@O_ltyHm%*OI z(zAeZDy&CIv>k*k=Fs(;DGZXIAw*b&Kun)A;1>yb-uJkSlNMz$3n>d*0ZSA4T*A0Z z={=b*(WGfM+Fp{|!ir)xd9;sc3{G^?SiRkRyx}xKZS&WYHbM7tE;JWMTA(eUziq^m zLIb)O?<6{8%0ZI!4Zz@RW;!zKnX1g{g9n*~%=y>W(3l%tu8wA|jO^;}&7ocWF#GxX zm(>H?`DQyq+sVqBX&oVeV+nsmUHiwV$^}~=+?O+%E9zUXX~Lu(FZ82Dx|z2tZ_=rP ztMXWWb{^P?v2xn;JIMl=82lrq5tKL({Np4KLj|l8)oQc=LOI E0y`-6W&i*H literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..9899198d9946c14a7828a2df0b0a97609cbca38e GIT binary patch literal 891 zcmb7C&ubGw6rS1LOm|l+Z77JQ_7ID(mr~+Qq@WQcqD9ox5*W65<7U&@AMPf_+!T87 z*jxVvr9FA_=uz+#5EAC*T%}a1Eg! ziWI9f1Ct#Iju9Zh9EI4$q2_8BY3LCG?GS;^aEBC0^Zi7hVps1QPU%b$M-z4!_^H*^*cff?D za69g0Optoe?Kj}%*;m=Vql?lW_o96{HSZ1OEb_Z;VMIO7<&m9Fk49d|q)*w>tAKG3 z_OmoT2%;8iz^-Enljbp$3Y$`y)8kCy%ap$Ed0gcw1}tF_u&5QVEL9gL%zFS2RlU?u z)T+0=H0Q#O6E?fTk7%OCd{M98X+D3^XiBxs`2{zn?%TQ0TpVplZ2>Gel3AkxY$g3v zy`kJFkcHA5qA@{MZLDi+h%*yC$b+meIRIVP~8kVbra`nU7=bK+1 zd@nc7mki7PGxo;cW0xnbddU6<&>ygQxg kPP!o}mS3j)V;y7siy-WrlT}QP?BUAhU}f_sk|fXm4V0hSbpQYW literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-39.pyc b/app/migrations/__pycache__/0023_killhouse_cityid_killhouse_provinceid.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..633af083dcbed1cd2927d19078ee0c395bfb8fa1 GIT binary patch literal 666 zcmZWnF>lo{5O(Y&O(KezKw@A-%2HKjLkNnBKo5xuTBazH<>pM{SH}rXUe!0l+8@F{ zVQ2Ho)W1*(!P#xqC*kNWcmB@y_nj@aw+n*f{MRd`DIvdovN>W*_R*%N=zu_^Ngq{F zPb(UccLXS~?*y2Pmh2m=7{tenU?!LL14unJ9@-o^Ci`g9dvuai z5s->P)J7GP@iOrT$aJ{{F(hc|1%s`NTO|7*X=#-~jwA|~f4DszsW35))sx-by*)1U zEG_TE+;qyc{8VX;e{m+O+{fLpnxsn))VyB6=gXf+t7I-Y(ZZafB5}^OH0|8E*sQch zs0hlq5xvAY?~^Y|YH-CzJDe%g$ORmhxyyK{;oKFRM07~kXk>q=<9&SxM;X+WAr z$;sk{5SP6Mc zP2XubHH)Qzt%ue(UyYk;17X}Yy;3saoS(w8>|qErj%JRrYj}g;Wk1Qifbg{Lx#D{sSq$^vcFx5rJ;C1MQ|pcOK6| zLi!ruO|0g5gxT>-`2mN#Y4wWapTzHCbTGFkCof8`It5GR%a7;pN@Sqi9Hc}pp3Bve z0~7zinuYy#>Er!JsNEAZDPdgv5ecJ=KBVGqy literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-311.pyc b/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbde0a54de25f4d67253e184d1042557800960dc GIT binary patch literal 963 zcmbVJO=}ZD7@pbPY<5=zb}1B%f>aUXp%nF`r64Vqh!(NpVF?V|%(&Tf_QTyo%*h-) zcoBN*9}qvVKft3up+XK}uAaPYNlx|RJKJou#)CMsJo7&De(XH&`@T}K5UiIQKfG8$ z=$jh3K)BcB8oW*u!94|Q7}@_2BOLmoETVB3?gY5X6x1w&!NYn51eEQo( zoJ7z4u*rNX%5l`?ountUHHdobk1;e#6{T(NhC9$N_XXiB^g1n}gq>;7giLr$>=_!k?i-;?e$xYM_csis`O=s51H1m!t`F>b zR@O}G5CM!O{E=1t$E?aJTkqeKJ2_XpZ?mQeleXQ^iMWX%emMmW4&Tg49KbhhXa?*poA9V+*2S4lm#L=6f&my_YYgk^}NNzH6~q1Nf#$ z{uJh5Qj_2a2oS^}KpqM-PeY)=10dP~5S^lqnHMeI$NCI=df#vh-xYB+;RLLe_+1u- zsW5|xP@XmyH2~RlWMcABh9jWhAp)L8Pz!mw2Gr=}ilr)|5p`yE&MhV9kQk&uj1x1z z&Pg#x|LA7@f47$AS$*4eg#9>oDDCQg9E+>l+t;q+ea3k^>ZKGnS+~!~QX)>GS1fE& zMno}=dc2$Tg;AHP=WL4P*mP0Y<9@g=r{}-MoQAD#TNq)Fb9v-sQ^cVkP?=M)@PbiJ zg!N?JcGtCqg);@l!ogTp^f;CHEXFT;K37$W5gOBw(6Gs9nyB>&>kc9JRky@Y)ULPv zB;&$~Vme>s2bic~pWdq9Y&?Co(~zDUi#0c-`x|&}EA#%F!{x;`pb53dZ%)j_%Xe(lrc&-cETccw+dcK*~> z{;n;ZDVuK}CKvMW@4AMtNyiUc(H7au#*mqx-SE7UW!j2Fr`GM+ENjU{N#(8}-H>6d bBZPjMfZVCMip)c2xUxA|+57>LWYxa_+D_V0 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-39.pyc b/app/migrations/__pycache__/0024_poultry_city_poultry_province.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f083241e80cc2f5ee1e71f03c493729760503656 GIT binary patch literal 664 zcmZWnO>fjN5cNm0n?w|Gq7pvu7btPhj617&<2OWT$sI6(LBFep+| zASDCZ(2}cUk;V(uWHE&VQuN6chw0U(lKo$4SeZeNLlhx@zquVp;j-_`NBjGapNMm9 z%)A@C6185gG;A&OuKS{Gtu%yb-wkHzRv|gWu8;Z`MM^xRXGYp{WF{|!QMOsmLt+PG zuvCl;g_W(swHVV+S{Vr0hxM_?vpi&C><}UpLg0?UD9rB&@p+IY?urOhuPi8AYvmn2 z3klgPfH(0p$0N)S=hBTh6kV^@B7Y<9K32zYef0WS)!M$UPNbKxl1`kQ9#tqqb^9t6 z3i4E}nT~S&0~;y!`jv}6!35nuz>snFCrJ~^@VonaE4v>1j%P{8VIghP?ZMeN{5bMh XydCc*+r{%j_WVYM7m=BdZ13^E0;08% literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-311.pyc b/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70a8c97ef1700e394da71a5a7e27a3725441c559 GIT binary patch literal 670 zcmZuuzfaph6n^ImCcc6M5v*;g+QAD#RcR|!m?9x)gHY)dMLM~;Q|idE-Lq3ETLuP3 zHf9!31^)s6M28I3t)03VkttK(`3FU6-}yd&&+ol^-#uS0E;2y7IbZ$qo&fwZPGxf? zxqFM`3zYxS#-6xC?7rqILxC+;8K$M6-e4Q(o#vVbU#A z@>f+*wvo^#0&UYFUop<0;?TEe?_M&z1Ilo2GY{_KgX$@qv`nzHZJ8A`8^BxRo!hnI79&Nn)GX^1fLrUJOBfRLTDim zAuwPMm~jgXbJR5ZhQZmzJ?t4B(;fQI#6^;{f`;(3Adb@dKnqZcp&Z1)Lkv8Fp$77> z0o-gBA^%%Ijeo*j6k0c_#3Zgof z)pOxTX%dSph#I>*^Mg>OH6y>pPuyW?Q>r1Ql2F=;Sv%Btl+w$#AC_N68Bch`cvKH~ zD)d5fWS56LEplfwW2 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-39.pyc b/app/migrations/__pycache__/0025_delete_transportingdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33cc70b118038008a94e13d8a346e0f72bd91050 GIT binary patch literal 509 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc b/app/migrations/__pycache__/0026_transportingdetail.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..662eb62573cca56a875790695e250d0078e3a949 GIT binary patch literal 4897 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0026_transportingdetail.cpython-39.pyc b/app/migrations/__pycache__/0026_transportingdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..750e14658f04712c0ffbcbd8f0eaf86589815602 GIT binary patch literal 2296 zcmZuzOLH4V5Z;%hm9&;0v6DDB!4L=tf-xZpc~Bv?WG61LIlF`1ew8Th>V^E-a8Vi^A@ zF!?wL9^)(5ai9h@1EXg)OjFIR!0OozyXQ0vOw;%)Vj&%CW6QK%AYL5U`E5F zM#EzEuMW#~^S_zYY+H?j@5aRuGLV^d+J>RUvkvJKrsK7rGbes^SLy>NJNHyOruEv|rQP^p57n-FNK$X1uq3 zo!+B4ZqoawcH3-Rq7RVC523g{qAhaRCjCBKTV1_%$4CCMnEA0Fq3lOOv7EA)@Brox zCS>(gW^sD33D#D<>VQX*IPzP9k(f~^_XY0}G4M~=0E&_cP6Ga#f%k%mW+a&(k{$ya zwN)DmlpT{Kh{0u)$D|oB$R{Cxo-in<27QWFvGYFNkj2|0{k zcB-bB!KQ$>ACQwyz*C2F6JX?WWopKHHspK%^@r1N8 zmg;!C6c4j1?J>z|>ScC3A35=Mu|#dbnBH2(0F`wOrVvcJdCEu-cW`5mtK)KaMf8G) zEe1}F#{;m}+Bnt6XFp3~C=IFOHwUnU^~>;Y#H{9^niGpyieWvXaL8Hk1Pc`RQfgUo z1a61KtqztH=FSZIBiU;YS-&zuRY%(s_m$-bYIvy1oidE0QH<*9nUS-u@HGQbk7}1R zC9Y`2$Y>{2mChe?7ElR=NS9FVR4;?;>-c;hO1|2i1Pte%?>|pSpmzDbu$Ak1`4R(E z&43B^Sx8yf8VI~U447U!Jb3CK?r-e*+t2D7KY(|(f-?!_nr^~vbr}hD34*uI+iTdK zn<^eC9v*Jh)2WjroI*~Gw_!>ZAs`J*PC}1QUqOCAyZET{{M6E-H)6!-n7;lH) zW25J3mxS#IEZPKDe@YZ{3$?ZV+FE@BN>QH;@5ttdQB3sM|PXj9iNJ@myh;R@Cn|1Ve> korpM4sc)-6g+4xsbf&TZ_uG^lj}#fCi-U(DyQXXZ59bZE8vp1SJRl1P+LED*0f|l@qs(l2cE-nO(anL_vtL{rtT*Gv6D(AO5LQ zu@HZco;uK4+Mv)XNL}-aEnP()BU<>KREwnuwq}&@E)u?fM+tO(p6g}x!TBWD%HSZ_GKi5l@<<* zFYi0lU;YNkFq1Qss3953xy7U=tMo5rdf&{^Y>wtKM6I(YKAhQu$RA|UNB`=({J(rx z{)_Lf)|#i6AbYdiyq~2C@}`mDkXP&VcizQuNc?CRgd(Ms#l-cv(IauE2RgqRkpYQF zjHw%SdL-;JJY->q`7!CTP=$a%L6j)lBHLcCj2EOVZn?~(+&;&R)d?Ai z8O80<`p)I0TE`<%*k|V<5cw?>k7~lVFrMb$>`3jds+-OjGM|^ZBN`jZ~`Z0rGNfWmkUYz4QLCD;$ ze~*p0PW!~~23)0WZpd$hp5mq3jkVj2l_s|W2>YbZenuxii=MBpyubN)?d~R=a`QzO zZbDAq!&(0DMd`!Drx1dWEe}Vb=zS?fn?;MzfV=rM){$BJ-b##H`$kgx=$X+-j7Dm_ zF)nHg`tItujLfTI`jxbLBb|RcwU?g0p4dzKP(o{CpbXqR2}SV}Mf zzL@^{#q_I!@R9mN&_7av3@H1OzAsFG|4v_>v-RCi#TC}FusH^wnWS*J6Zl(`LNTWn z+LkpnsfR1MaalG?w49|od@W-OZwVyH9YD{G4<@DhVfYrP;_n#6AjX=aD3BfH#u0k; i?46?8(Rp`zX4zP;D*71xQ#`ejxy55KaeB_IJk?*mKdig} literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..b75b06edd99cb8ff675ab947e070f03d80096c69 GIT binary patch literal 1712 zcmcgsO>f*p7#`beukGx%i5pl@lc*&LS%U}>2apg#T~ZfH(?aus8Y}8(c4v0u#cMBP z2edhX)C0%f_zOYFfu8^;4xB8Ib~PM0aN@QosgQbN#$G2#S*rF@A3X1upXZ&K=k+h; zvI+Qe_<`>27XbKEIQgTFjN^4~d;B3ik70BC&W|PzNB85&Zn8e8QnZAqS#xD2SOoTcpLNUZ%)YwI| zMPQfE1_@%+B9u!@2(ySu6Ycr2t#DlmEy4hG2rHy-wdoNbGiwZu*`Nf)1jBl7bN|v} zwc(>EvLiSO*L$|g)Vhy?&pFnf?=vF|AcrS0VI@lZ^xKp~jzc!VsXb06;P$7_(DHD- zcgMDv4%6l!WF~|>wdWIVmmvIN5BUNMLdqu`u<7V4enzOy^O$r=fJxBkQ8Ae8Vr^^l zBe=EUti#)%TzA%3>9oQl5z}iJ-w>OoLPD%`Gl&U4tTe>TnjfFqH$qChR&a~-n1mk#uP^;%NB_N!hS=&ub` zWm@}sZCC=vjHtMr=$8kTtAnXG2iD@lSNqmtVl5t^->j9BV!<$nCNSni-E5-I4l1t? zre+7$yr`Q`toeh5A2xsd?C0&Dw)@Uj;%xPu`-yYE?=%yqIRxNK>6XlwPvv{^KVsRH z|IU^Z04{m*{}9YQ3&ENoxGQf9g1fRO2*e@?+9QI>q@{iHF|Fq3Wb14qyR+p+7&J3w z7^4WTry|M(@bYPJIh~GZIlo`}N{&XCgq4EZ+ b{sF4LgDWRmMbaLc{mF%7a^Vr+PKxm_j(U{V literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-39.pyc b/app/migrations/__pycache__/0027_hatching_samasat_discharge_percentage_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c92ee79caef4f0d420cacecfdc262e70a16ef6b0 GIT binary patch literal 1053 zcmaJfgc5cPK)$7xHcgpew6p$K29iUUX$f=2y-3R@_V@Ll@mXJ3lfM~r)hJjSj(f?x3e?*-VE(_0|VEG@6WSy$1r~A&HO^l*ur0K zq5%U;ZWLy0n%cLxRoJmzII+|0ZSKb23j-W*KN;XMJ8ylo;}+O`Bl3RYeIqiJFIin@ zWhx^}1x1z$T4z-$l~+{2xI9dB-24i0vxUF>jD{Jp2}W!&`-{We-1};RnOboRYx!V- z&DwdO>tC4QUD$|rpanjnA+({*y7@xh&KL6~2=r~}T)1;_;SF)!`MA`MZ@~hxSyb(V z+0&7SO-G~n&c?>0$D|gtl%q;$ioj}`apj-UIyu9=T9ve*lGX$=nVeCPGBRQ!VP#EI zCQRgq0=0mh(lM_i8}-qekdhWmIgNEsGsZzJ-%ut<1fw+rGMpTr-(Gu|a4Kaa$t66T zM6Pm&oR)7f*O+tFu1bRGSt0rYVJh7>P*?JCslbm)vSGqz_5{b rD$U(1aJ`uuxjthq?rDnp1=nP!-Wp=ce>!d5Gud9Nm_8>j^Cfl?~oyoj>Z|1#u-}mP0+L}Xf{AtDGAC!<^%4tUH z94xmG>=PhBBN9`e#+t8DqLDrU?K1&g(23q89UwZq@O&MN0r6VD)v>2ZCk}(0mtmR| z(u`9OQ88*V)xUl2EPVv~L=c|>@im|U^>vL1W73eq(x7(CNs~jsIBFfBh(lbfab*5W z2XC>Ujf5;|ziF5tEuCkXeAMebe9XqY9F4;yUWOWj;fVXmhf0eqqeQxP(-lf+0tV5K4a2hcqL3D zfw;ri$0?6gtnxr)A_0+%LQ&+Zxzc(L@KW888_Ml$C#48PUT;Y!MXIYVeDmo*_PTP2edmia zw{9=i?=G%yEZoh#`*U~m8$Wh?Ki%Hk?Nx2Vc1{SIQ)MdMbj{f-HS_hR%#LSB8zwvn z(k^_cHP*^jL~g3EI`$T#Giz(rsAu^Gy6Uxy_h>4eQi|lLcT65!{VKCV&5B$#d(QmY Ny%TkC`k&Lf?q3x|%<}*M literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc b/app/migrations/__pycache__/0028_hatching_goodsum.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dbf14ac2d2640aaa91e89fa5e1e41f4d5dfb9fb GIT binary patch literal 736 zcmY*X&ubGw6n?Y2nd~m9)F4*cUW7*2O9=H~DN<0uP|+UjZ3&EHX1dw1KjQ4}Avc8{ zJoeUqK}r2fJOzY=xq9*zNJZ$$nN64I9NvE4oA=(l@4fxLvEhO`ljnB$4FUYrq&l@* zusl-W5*RQPL5zG98@_?SfG#lO9GJ<`5LZd-@5EeT-yBB9(1kJ-V$s~?b z#-psi&H*InpMjpAhL1Rgx7E zSGYmQhk`~rRx`#&JYhWPhddK{ywZNg*h^hQSeiDDlbi=!lrHI}s@2u3zrs@8!%h3e zVejqfaZd^DtvAtAk`LCB1EnA<;`V4P^j=G&L8gC%b68+-x@ch<_wdKp3m2T-&+g3L znc6$^t%viw+w*4Y;?b6O^33Z8hDbl8w4LE2{TOEsm2 y)sy#iSQ-03p&R?@Y9vQuTT#8uY*(3ui4gjO0eRQBf$)Vp+uWOO?)?Tu%Iv>+LAGW9 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0028_hatching_goodsum.cpython-39.pyc b/app/migrations/__pycache__/0028_hatching_goodsum.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bfa0e4a573a11332263f03fe36534270e018445 GIT binary patch literal 600 zcmYjO!D`$v5S1)>*J~2Uq5Xw|p@fhgT1seBC=EF@hwRN5gyNZay;!m<+0dNZYd)lh zeob$>_S9b}lyu}JY({99(F`;1J?X>4oRNL~^}hYd8T%cRrzR;mr|Vyk0|vZfhL_wV zWy0A7g9OBP1_Jq3d=sSrxn@QBhk99&gxs`^(_`CP9~Pzu?0g+dPi;ZTIbHvf9I}!F zD-+-iF9phN8W-SVy95d8J%`1;ph^ZyT9bv<=g0Z9Oz2?rHDL<+agX zj|y5}Z?tPr4d`mLqoz<>P^Nbnvd8|gyy$yaPsWiHtl(h@c&n#wECg|h_?6WLgPeVO z+hPY-#VTZKepf2wiblfJA;kwueVKF@dt(MTparybi{2$PKV%;OKE)YM#Ps0Oj@Y1^ zpF-Xf)SY%en0rPIv-^AY@oi=7P*>N)4DPg3*XzrQxL13zD^lUjUWJB8`N5t)N20Fu=i+dcq=s8UZ+1ZZryU4;vW=G;b Dug{`S literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0029_apkinfo.cpython-311.pyc b/app/migrations/__pycache__/0029_apkinfo.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0bdaaae03b9de992ed3baff41089cd174f4a4b4 GIT binary patch literal 2221 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 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0029_apkinfo.cpython-39.pyc b/app/migrations/__pycache__/0029_apkinfo.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0a22d6ac0d2cd9af01fe23194f41a00715f5318 GIT binary patch literal 1350 zcmZux%WoS+7~k24z3WGkCQh3cka{U%FIL4vf`Xt490zr}=%a`ChZ6+ih8}Ui|t6|I@Rq-wb$j zxd5KRR);{SMUk))6d`2Jwy+Z?auPRkE9?j_Y5?C6&8YdMMP2IsU{Q}b3;%m3@~Jbj z!p0xq#|n}56)Os!#wxURE8(#u17HdPfImH-&*JIV8`c{l|~r{}|6nF`Yy4aGYgSm5FW+^5tnd z%e2ku<%zaWhoP%Gq%1N#m5daO>UJ)9LgWfB*-8hBNlpZR$#myCCMTIN6Iim`5C4A!M!aPDCIyd=U{VJsaJdrw_M6HPfG zs+^^irPGy!d@a2_xVrobUyY70@Y%EB@wdA3T7xsC+ecL!&&=bH=27a-A&&>p;1d&% z4z8|FhxO4dOHQ?C=!d#Hgq$yV!fILPFv|oZ>Bi{m(X;c-@n}wDeQcd%lJPkG2Iize z7bJ~gtms7hRUzS#>gLg4bTk+q>sFSt&BOiKl21(84f*GT;gfNa=F{;7QG~9D#22H} zF{D1eed%ME7X6tBj5QCupW}q literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc b/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..262fa7ddf76a99951397b04759f60179f9d382c8 GIT binary patch literal 3970 zcmb7`O>Emn7RN`QmgJAnjN@-xvL(x=KV;cfoH*^KO{}<$+onmZIEmtfWyG;eN2atS z<*xU%3-qwZ_EZDC_}GPg&{0Pn1?*)A5MVK<1@`0{fpoDzFS|38oH%t>2xUNiPw&T> z|GYPRGymx93<2^vz8#RRbOP`%>YROiP2=@VV*Ch1Ai4@*&y{uUxwCE;aD&f)=>86f z9_ZTjpFQ;U|FNfGXFUgA&UZ>3&W%HRQeF`>sVJ-1zgHAtLCw8=27vaa^Lm{O`6GZJ z>k>iMExPiqtj7(Ych?qt{t-ZAh$>ib+FO*(M@^%sTW)wkIOGQOn6_lKy zs%fYRQUSXqF|&riUe$p5h{kij)chC8SKB`P@&_Ps0!@+)#43V-4YP|j;R*ejO{1tSsW?F75HZ>T_LgNyJ6)vcrJ^F`C7H}v+?V7W#O=)=auoD89NcqW${X|@$u{49 zj>Db1(vBcXd~*!8>7GY?#cyS(;O?BD@Mr7cbL4t}+eJkp`E2CUS1OPtV!yCgEX&#{ zJ-kloLOHL!Xxt^j94SeGCtMDyjqHkKU7FfRNU$syibM;^R!3ebsw)32l=3?oZr20_ zo;e{IYHw^cClp{qOQ>PnW$kR(3d}*Nq~WeN1M{>B*i$TPoC~*!a9b!BG_vKq_GA8S z2^K{49(M@`czaPik3&39u0mxp4Uao`x?2hqrk)5(P!^$_lc1{58x?L}wYT3_^zNk4 z3k~kLE#+^Kjk!jL#=+GcL1~(4BBg0&$WCaOp*4~Mtzmbh8wqQAw~NIB6yzpXEWzeg z?eE|Aph(hL(!$9Wiz^@N0+Lx`VxBd)QDyg^UU&*IGKZup^2+Uo94t-ed200 zUEe^DpBWQdhhmy;40o~${6?*F}JKsG|c?pa5oLJE#|*WfgZpPpuy?GxH&kj4^CHlYSDVy7<_=3 zht?Ge^x6UwRA53MNmMd5uQ755F>6*I4fp?k{u*1483SJ<=DsyRfkD7VQ7m<|X2w!_ zELBa_SJ7tHh&@BhmNi6)VZeq_BzfdFBS}4ytY~!)dbnvs9wX+7HA0C|zz(9JnZsps zXht8Jsl;ka^^7s}5HTB8m;w>NP9bjP=U$Ur(YckH7d^QR(=VvIjUOxBvD#1vrTX!6?8zBzeKpS)HT>neKs z+?afU7~bM2G2J5JGZdHw>;#H0A8niQWj(%J&D3+~$(9j+j+htL93>L1gw9hUd0~?A zdde8QkC+G60tFWBj3#JC6Z#OTYJChn$sz$7L)(bSTT2v50d@q9CJwjF(S$xqOP@pc zGsfs6#B5quDX|RL2pU^F>NUp}^)Zr=TG|-9i2$JQSx zakCZi2_-&twJO;y7iDe}X8fIAP|Fz6b;NvOt=d4E0DY)`=Fo5U&*=R#l{-fN4a9t8 z-J#)Meeqz(@=US*zpg7^oOP>vMtxD|q literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-39.pyc b/app/migrations/__pycache__/0030_transportcarcassdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff1c79ac5b0c384c58366a5b6588e0ddccda6b6e GIT binary patch literal 1857 zcmZWqNpssa6y~OVvEn%CzNO8gF0SgF+Uc~Z?Q!Zua&UaoXa)ll5Cxe8SpambUfZjF zNPkanIP}t!{z4CRA4u9}19I@@y^jwMZw2vS&~@Os{PRb4Z{Rq88=?LLAUuO59|0i_ zabqWOr*7g+J=b~e5Rdr3JH)5%(*Mn$`XqSej2j!!b;h3VCM*(Iv6M^QOj1H)8JbV^ z=P?M+V986*ai}wOi8J+x8@W@T2Fr#yfHs#c62RLaP10HibC0wEYXj1O)m{65^em)r zAp;8;TF4e4#%e%DYY*(+0l8a~x2+v_Eo29fUTx34O5;9YrMGWcd)~H?cP!*x3wh5% z-nWnsEaXEA`N%>(wvbOO)BzSDmhzA)%wp{^a(bk_F`#4uA3I)ZA65Y!LOR!j>bGp(UNd?0( z`<3ec1r=whq=@5$>LDZOmmGs}#W-DTu3#3%zHXewn4iN0;Y$=#9;t;6cpk@kM5qMK zVyaLk=!L#pN5Tc>5ggvi@G7BP>9!I$gb*Sf5O8bki4mM2wt?tCG4P<3iIn7_(ha6) zB6S0;X=_pA{gYe%w;2sAw=E8Nt$!DfeXdi>;M@DMbLUk zXb2^V5$J_fmf0l`my%^dIysM1@CCBfk3=dZdQDlhP`anEpw~i|Q+3135XZFirCahv zSqCLAXh>P6^zg<*Edsjgta6NCw-M)E8?x^5PdW+XN zqi^)Cbw=*+FYn*rs<8hO2DU?%FfQpXIV+M^B1aF literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc b/app/migrations/__pycache__/0031_auto_20250921_1447.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f48b274a44ede1e8be2ba62dfa47cd286add57b3 GIT binary patch literal 2363 zcmcgt&2Jk;6rcU{dhImnHf;k*t27@@j3VQNl#~ci^Wi|DEm9Lx;)bl&p0QbXz3c9- z6PXi8J#g%;|3Zo_(LW(QwGyWlk!(#495`_cN-CtDnAx=(z)qC|Vh=NK-n{v}-@JM6 z?aw_uG9X`VQPP(}0Q^Q5?N4Y4hgl*#1`t5T03{~FFjQs@w!~$)5})DyHD?GJk?1)i z)S9J?#DY%%Jvd5!HaiCLQe7lQos8d%LYHXl|Vm(yj1NjY1NNfp{%biG&hm^~3=T5g5D2{Zo z8|&1;aQDd7XG(qzJYbrXC3RrNBzZjI<-)Qe7&cQdnylS{^z*#{wHzi^I3Pz ztNPh?cAo0~ijOqaEtd6jok#^SbFtbVKaaz=+J#1{j?>CzJeW+rmsDL_Go7+!yE)Cy zX^sPttLX;5aDqOPvytW^6_R0%AVsx`YpJHSt!fbB5JY*cVz?`Do>VriX4TY62=o3Z zZ3x-G zzUoJVHnw&!ut3f_-^3Z;(e3yEmQcOJgfR7UCHQBN7&8GE|6`{ncXXX}kr+DoMysZB4n*+}KRRQ>>f zE#@nhOkcBz{gX}=_K#pX0^r;hdlce{1NqR`lEMs{X@ntw9CE4+Yv%IXRB z%;o|p{t0xc{Xe#5B__(Kx@1Q+pHn5u;R>bc= zv*+567ngA)NV-JMGV?(Whg%w$_0v5_)wf|^^QvZVihXOavD9K$d#MZjG76-@4f;e9Z)4rb&T;1DqILJWfc5fniERoIrt=nWVXBJhQX*+Zd^9$=#J` z-D`XGe}E&uhYPb;h68_r0fx7do#c?NM$d2Gd;9ID@9moPdXa_W{vPTIk}0&sxvFpt3H-8{~F`4)I92Yl$P+;u*{{5JA475zNS@8mlW8XSmL z9&}e^T^D2BUA~*|;c6FpD{>>ZbqmJ!Eg1cl3*1@RH&*Xp^d6$#ZKE?keFt_?pFJHu z-iU$95Vlz8_lLtzhP0BbP>WJlQzoZODc}{$gueHdcy}r}t2hNTPZ23*byd=$d_ft2 z?f}1JwWv-L7u7e4(}K;pb{p$mW?X>oFC_HeEGF|nJCo+R(;fHtHk)e)tLPz#QJOzHEQ z38N0Bk{D9E>IF8(u)?oe@B(--T}sEKwvR5JenT(LPtNG$A4VtN>-ef7<4Old0H;P_ zX>OVBjZBNOId5Xxhny9&QhRlk2`sKK^QtVkCfGb3otBbkv*J6x)DBE^&?t&GM|X~o z&X12qCpx^icrjg`?S&UV0dtU_}Rfe-9J41bg)=T50T7Yi#kOUkjQrabA8u# z@Y%7Qe>VOH|GHiq?O%D-k%L-66tQM%wSp;m#xs@Is%iXC#|0ET?Gft$yS4n tM)G6ir1#eOM&H3kUOB{Ev(vR0t#{un3chI1!UNNLWj-*r`*vU+@;?qkjL-l8 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc b/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..667865e88e0c56b30c31fdb3f69c451c6f3116a0 GIT binary patch literal 600 zcmYk3F-zn?6vy9WVoc@~R#~(W<-jHivb%bSdRXYfamQ(KXB8HPac5YvWRqNyEw)pz zu(b0t9P2l+vQnnCx-OtLR?cJ-_FnPk|H%92{oc&|{5$~_<0IQ|BY@f_KcC~&ivDbizFHNy@X|c6sFy2FF@H0N!c)qXsgls(%5S? zX>(_1S1z3;EKK7l$&OjlWogrDUl2AH`_%P6Vj?zCv7L;G+ zxQIo_McDO4n&?gBr?v=0CQc$Q0!gA+lso^07Y+M*8llz*)N{kM`<=z52A^zGA~6IW`xq z%OA-?Wj=MWbaH Q8}e9Nf2gg$fhr332MNQEGynhq literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-39.pyc b/app/migrations/__pycache__/0032_delete_transportcarcassdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3e1794ba3a17716891c8ba4be0f7e07d85c13b7 GIT binary patch literal 506 zcmYk2zfQw25XS8|g*K$H!HU?jRB0$eAOw|&ggUfC%M?YjOl(!D@{c%`=nN|l!t=0s zW#ScB$~kG(o^+q?eDU?<6p|IYUnC7w#bkD=UrXC9C2*laW5!4+6~)Ql5hd6kv|vIiBNy2y@ZW#-F-7 zXe?D{y!CPnMOaa&GuOTBQ?{&f>bc&Pd*k(Ke=xXKr_UwJWRaKEBP$~&r7tQLCjew- zEEN;yP_-%5C8f%uG|l-k(X~zK>yjm#iOoeJGA^T1TimF@NM10QLYE9xn(qJq`tQH{ z|NAlgt**{Zp=bZDQ!FtQ^)FnhJoa+oV-gkqMDY}F$xvICq{V{EbcWutCaqhxq>a?A z8GF)!yGJ z+gqMaqj4dvYqRlK<8qO=p+7tCIH=jTnWA<2j~3oZ_@>jm;Mw$@mLdzb16O5Uhy^#X z(0&GMJE*OAPDsx=WZem}o{*hq*t8#9Izcjo^q)c6_y**w_k^#PtD+mLqOVj%H&sP9 z6T0WjQQ8h#_Gwc?X1SHHfeW#|s=R2cif$)#|AqYMILC75sVH`xL!XYhzbd-BD!QjC zy0R3l>!TpzCqvih}MdRxY21J)@%& z<1D(X2#UZe5|@?pIY~)zQi_vhUQjqO1Dg^R`K&3AnsQp?6Z4Q>h=y#?!xfYqo00@h z5qMaem&7ej+F{=aJJ2NylE`Jm-wM#PEl6uQSzxo=mH@3t8?wS0URdV}83j58UR1cX zi~t>ltoVIFfVHMUmPc06ZOiN=n|sT0Jn979vBdSAiqc6uKuTywP(Qjn z2A55vA=c!%oh>1YyhgpH-k>`mv=KLH3EzJtoYK&yh-jQOc`3&iQVO(-im)X^Cvpcl zqwGK%8mICBXCJ(jlf<-`MLp)W#cT?Vy(~y!&|y|!<8fC$qbFP@eC;s~)@_O#951qE z8{TsDIAYJe%?c81K!L|uK*qzS&>a@m@{)+6W=71O&!9*^2e*|gWR(y2s__BeFGDsm zXjsn+DHQk&i@1~^o3qQKaVfGnA+AC;lS96s+47{NoGi0%1u?y$z*>cqgi6Jo6_n3q zImKlJ(-*f{CdpH0mL(x2hP0=0a|kf1-i@m$gb@`KN{8<$z4g=wVjatSm0c_ zYYk0jth^X3fDO0JxEA`&6H-Cwawk`plqadK-io>T>;osBr}SQmv1FTc@Y2j; z;y$|=pNp}NpGM~%LCS3ffTjI6$IA9XSWehY@-geM2 zyt|}#467Z(htXoZq-Y%pz$_Y9FwjJKTR>}Qw@GgesjZ2gBIGu-XwmOcZTe#~fhhjV`SA zf7yT0TMB5cPXY7H=*B<~jP~=yHk4GklHqM7${DZ5?WgfFmYo513}6g1flEin)J|h zHFUjb1J4s+h1Eje0fsX|7#Tb-oI{wndY&J{myc?T9bQ;N>fA;5A@aV+<4H=S=tn1|pQV5A;v%t?T_$YX8(x zqLc#5t6Kjnz`QmlF)?+Xqt`GoeX5h5QbhAT1I%;dItFf#84cqZ4XbS^s-Wo`dS_Ve#Gy}tX9=xy5im=}ZA^SadHtY!e6LCG9#^~3gcPG% z_X1!Z7~f*`9SiYv42O11^^YCdiV@9!A218Xj0FRC5zq;`Mt8UMu2HoM#U8EiF0#I7 z2@o}b5e$r|T_cBlQ3lT!wXP+=yfEenGk-2~k1+QU^Yzdz5at15PVNcCgx322Fb|D~ z1bBpiX3#Q(cdQ|`W$18DYqtPHJ;JqiW*l?+bEsJ)-$w%t!L;cwvJ!OdiNZ$K5sRi6YEPBs-bOn&al!~>OZ}- zjJVu}bQgfT{q8ES6RZZk>l4qH(Ngo!|13+|LF@?jx1>n zTU)M}l+w6FdJs|R7w0YWX#YmqLRI{~Jh>137*>nL^0R}obpL}2{zUnIqG~@mrY(*i Q-8vIcnZVB!st_~(1C;AcnE(I) literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-39.pyc b/app/migrations/__pycache__/0033_transportcarcassdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff7a79878c6bf62182e2560439c918d86aff7035 GIT binary patch literal 2511 zcmZ`*NpllN6rNQYZMHCCF=R1hLm_e4vJnE<7EY)HQibh{%2i#h>9*8jG&A(fV3cce z^?yi?`6sz2hg4s4@?Xdy@XaDyFfgiV_51quTly_MwAHF>c%J=rNBr5=w0~1#{;@#Z z#T%_-U>egsZKC&eJ)Ik#F){n*#OhlaZF+XU0^Ibf{pxobvzYy>#%ykmonOqp!^|zM zTRDUrt*a|1;&CkeVbnELeIkaE#vVdUqFb7zJH^(ht7ONeY!0NyjKs63@P|bpB zWz+(wMer_WR2x(qoG0)uWqVJSkWL9XRYFdekTXD1sTMnXV8DuH&`WdlxzdjFCFCt2 zC+GIOU2wbuEVuUE(w>zPa-oD=EFtfekoQZ-2PNdg67o?Axl}^BCFJ7*Iri%^kPf{3 zgnf!}HH-9TrF~a`%%9KISLkc6(AP^6Zj_MEOUM^M<|Fwf=;I9f3e>4IM*Q^n%(yl_ zJ6>jAr@6~+9@vQcH?LX0b-X^j#J**=(An(+bEx;vu{)@yyQ=nJRywF7lZIjc;*~4c zuMyM`k2#4Y^`kJ5u}h^(qlodC3QwKhp5Yrg-pg@AuQLBxqqCtR6W?V75}_#REXSUH@Dm<~LyDv2+iBwRIe zfrLRSxL_q17IE z)PIa-LZ1mNP zm7GwWc~g#9Uotu4Z_M$j)>w=v6Qq!_RFLy5cChbrsZJp9X%=Mu5Es2wHJB8LS{^Yw z^biSEp_3r-<3j_6A9gTwt;}h)z_^RRdjxzgkMh%H@GFk;1F0px7r+*rR&ywWC?fk@ z3`enQ#8mPbQTKU#G>=^B@!XbrKF^Y;mCq%2xd>yma3na(2W19Htm;KRlEGB1z^&IL z_bg=x)2=-ixLV*BMWLFKr%to{1dKQ+5>Ehv+zW4zn=_ zEK=1V% zEw1fse@}L{?mZ$8e(K%(Q8kY^1j5nS$m;V!dS}Y?u2#);F-A6Q{Y>M=K zv~_HxNJQ){rR_61n8~A&90BZ%p23f50AT1w(tH=v{ n?ySzvM-o^pchVts;`m(h83(4ETX{0wPLn5cFf?J9qdVpcKfm}< literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0034_guilds.cpython-312.pyc b/app/migrations/__pycache__/0034_guilds.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f06f7a446bb3dbadd945f8ce565e9219e57c07fb GIT binary patch literal 2423 zcmcguJ#5=X6h8ilreryh9NV(x*j5TRkqp>S5Vb>_7O^cmNt>jtWamc_Kv24~Oqn7T zl5(m}Es&vOwtDQ?!XDhAXhx3)x{#;<3YVb;GG$Yd1O>9RcchfKu#h54C4l$tz3;yF z-rc)L{yH=i0_3;5Bq~1(06d|S-Y?Jv5O!<$~DcQo>U@NikS7k!2}b#Z0j{R8uO3Y$>{C zVxgu(q?$L%uL%Gc?M|M(Pq@AV2ox9y3M>nVNAW1omrv#eERDK_u&idojihzc(_C#91o);#^EC|o_Y)H$Xj4X-vT@4Vc+Q+FOP<+XOCN| z!+mtgKDxQ%IvDF;MSJ7B-Md20Wa590DgNIvRR-ZC3@FUr>E8KOn8H|dDm9IR*L&BD z+&NCJ*YRXJec^&+8M0>9b;BylMp-sZh%8xAv2eMesL;f$0@qeCdo`Qlaae9xx>Poh zY$1pT>xNR3ji$7PnmA}8Ly=YGD}=+_$SCP1k~F!7Fh{H@4i7-IAvaVDiwG)~Tv8Dh z8k%yif$*SDC_%zXT7&OI)9*_%Bu+>}P&S%9qv%CIj5t8zHaAm@K~EX;)YsF$iAa0} zN~)}Fk-j2-DXB=SSewM&P*u#A6|0HGx}k3?TA6sRDw{G?q%vtbIMmHcDm8JW;w9fp zwbV=n40=Zmda-a&*Cf)VkVSGekV-eh&y}_GZompr5uRw5$4i3fh)R@8CJDW4r8t8& z2rO(Uh;HI3!7AaYIE!4olL#hOE+5CCQ*Y2#=We$w|`fBoWn- z29Z{78nor&lZ)$XSETj)N=~}|S$5?b4!=Su$i#!o-Z5UM{nns0jl)YyWsw~4DvbvR z*VnIReUWc86o>=#nZZL@lJA;QL%uD%r0Xh@weF(jP1*3p(5h}ArJ{XGibH@^S*z%n zg(WO{J4c#59#~$?FE3_Sa7eGC?hD{Y@Qj24Ud}FmP|W487D;l&*RO{nDcFqU@99Fl zX$%mk_XrZfd_p?>1JDsbF!^oB70)^1xgSI~dC5s$`b}JHiwm6qHzIs}trG^p8H$*8 z#OZc);*aR49h-Z&?Z)Pu*xV!jaMmtJwq~?qrX8``(J^~Gxg)saNoPE{Kk`fbr}zP~ z*KW7Q@7R$-J34JAGT#esBI6`72eYljWjk`^-`Yp8l~}eT*>-f?j?eF$b>s6+e10Fb z;ur16N9}0Lo=EMCxf3a8BDK#SoI1?3CO)?#U%bgOX;01X+;perovHc#>_Ps}YE7-# zk#)~=n#PlM66t;Gkh60)TZvnClPkHo zEho3-=1eDNb^usr*I6nq-Po)={DPmg-1?wPJ`&=&Ps=4 zM^8MT84iXz+{m!-%_qiU@6=O4Jm^=}LRr@~{IU;rHL&E}5Wlo1UMUyIZ6Y5S3%x2d zKBR2#^(c)?RPsD55$UCP(Z78k8>?hWKOxL_$)m$D4D&(&%$eUo@-av}27}LqNk(`W PawD@&WcCFh6OZN}y+u}_ literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0034_guilds.cpython-39.pyc b/app/migrations/__pycache__/0034_guilds.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f73e0a018cc85948d950dcb848acfcaee1bff911 GIT binary patch literal 1387 zcmZux&2QX96!-XR?Okt@rrU-PK)sqnRJA=I1f@wfDG{Vd`M6jsjb=Tw&ba>SjNR5; z;ky3=9QgzIOSsLIQ;!_Da3H*~H%+B5){Nf!y?NhnOvdA(0qgA_-|*jE!}wD(A1)i1 zXRzfy9MqsFGjbFmq-irVb1SlPJF+|8%ACjr+{y;g;JHC<>ild_hgqrjlNEW?Ix|A| z9oR8Kq&&&$niq)-O*PDUB1p~4LMk^eDa+)GSl|0_O@Mg@TL#E5m=PgrL?*L-v6+*) zzaokfGa6`L)T9>k(;@hW2&hX3OM78b53msn(lKB*^_Lc4L%`O68!ZuV!HOGq+!}D} zaCg1qHh|lJn|EMucDi?OA(LCky<5nAK(q~;ZKiiqKb@ra=$6iaezbHThVB26e|#fP zMs$Zd9MMmfR)V7Y^i!zmXUadhE+ACXB2^XbJbd{0F|GwEWL1hfCL$(MQdSe5DffB9 zGb)wI>G_c|kEfxn0@Bnajs+t%qiR$Mo)gjHm#kI3WP+27|HxGEnu&QS87@f9lm*hz zQUl5sq{(XKG0JN)&zN$Xg1>5*8ubP-1*_2X-bqou!GwYnXf<( zL=`J2E8t(@yS!RqBE2V==B6@OoR0_tE;yV})m!_mhN@dcy z^18~wGggCxy|aV8>7g2y6Iwiua}3eh=mFd!3c|0{n_c`p}`=WYbem0aM;reM_I}7D^9} K0Bs--dDeeW#hkbR literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc b/app/migrations/__pycache__/0035_guilds_is_steward.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2af498b90438930552087df1093a20c575b92b4 GIT binary patch literal 693 zcmY*W&ui2`6n>LrXOp;<8j2NL>7^^=(iW^2(LyU!6zxH8VPTAY(aG7mW&59aS`c=bt0!-Ptq46ilTBEChd19hdGF=>-h5wLvO&h^zzn_;fS-!g(Wt;| zPl5|TKoUYkJQ8W1MnHoXfZ7?L&Pk8fO^b7+&#|Wu4Y%=25mys-6m&DcA0%-uXp|ri z^W#MiK(ivV_YzzH2ah0l8j>#YbPc%CD+T}C0#XL5Z?t#&|9i#IxN3}~H5FI17A2>d z!=`Hr>rJgkiqrix6}NVF9__O3AP7-PtWG<~S>ETL{0t9WBAUog{6W}vb!kYMV6h)@ zVU)RX67Ud@TuYd&yk|_Sp`-lg`_BFFR6wXR+Rn^zpdz!4~qj(qX1vt4s>y&ty7- zf`YYC=-LYX{JOBgTK{5C%(bz(HeKDA-gz)}+UE}^PJ8UMFZmB=_qu6VcA-;;p1#Uf z>v>16AuR0qaW~n*52c&Z!~BnTRasekPof+1>3k)7*?mdX6XokN6*?j04+Y|0(-xuU Q_GEc;yuA4vBq_W90`!Wey#N3J literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0035_guilds_is_steward.cpython-39.pyc b/app/migrations/__pycache__/0035_guilds_is_steward.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5658ec0695310193d2350e18878a8a58f12fdf71 GIT binary patch literal 558 zcmYjO%}N6?5KcDP?RK?L&}R@9L<;If{HY>}2R-O*SqQNcmtFSHO^f!dC!r7G^LWeE zldm9%PPUbHLcZk73^VghWUm(xwC9hL^oM~AsOP<+X#w86iDO%O=!dv z&su;eB0*$BE2stYx5TRe~x< zsnU&u3XFdWaA9*a%+mF+ot+b0uLwOS11oirO5(8Bl8`9WNi^(elTTEbK|;`Z(; zMnUm%f-y?lUq};6MLYGhv7cn;sQU;$bAGwYse>!{;lHi-Cgi3InJklP2kzTW+x}YT WvXS|16SElqaIX2-%FtF?pZx)nmy$vN literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0036_driver.cpython-312.pyc b/app/migrations/__pycache__/0036_driver.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7aeeb525bb347ca162052bf231b5a8f05a9ea79b GIT binary patch literal 3031 zcmcguL2TPp7K_@AAypjCrjNF@7z|NH*$eeZwo z{mAF_N##c z4}QNoR2X8Jn+)PUWl#Y7x5Pf-llQ*gvkOAQpW%O@jf{^71~yGaD;pV>gepo|mrbRr z8HBG?5mt?NN>2zF=DA+u(FRA=VW!|iOo3$?7*QAmdNvMhg`f8B`#c}=m07C#c(sT{ ze&`EsMW1Fs9Q*@_KN#8v9rU-sBEdzEdhNj{4sXQ=+nx>a+(EFP6NnGF@%zC<0@j8PIt41lZ^au;)&I9X$bd>;%~H z6JTR5cKX2z*6V@QN}Pc8ITxGy53Ca>V4ZZaGsm;y=+^AhJzHmv@x5@2Z~kc? znmYc}9VGXAwFRIf>v)3_Et8-k+57ht5QkFvWXEHuIWle)*I3` zZjhjXbwyT{k1z>CSg~qgNs}v>_@OuBCqoEt$aU2u0!E4{7gbF7x~6D3)YD`66-VO8EHBQQ#78)~{#f*MZv zU96Nh%?zv4;-=GzLc zdt!R7Vj~k6;0;za39b!nLPm8E11a~UvSziH76n|u6Y24|sRAFk1i5HX=_VwDbJv02 zP%tbp8LHOYTj`xlj0lp;C`lwFNf2FEG1y^A`k*eWG)j_mdMl8qu?u^Jt{ON?24Rf}2ygm&wrbQhs?UyFx-$SRC)J{+f9N8ks**%df2G^0(Gu*6UAh z@^v^XFH2sw=W7jp2%zo*K0O#?4@%{yOqXYZ>CZxr@VqTN|CQjR->}nfd@n3@giJT! zkMbYi?uMD*6h%zh!el2B`zdnH8k_xm#~GWo$7Tg$xo9UBTd8*PrX{}lPwydWCzmZT+lh=@ z@wvSjCq8G#=bE@3f7KFS0|i#%(%#EX;*y=X)J(NrJX&oha+a8PSr#bwf}LDwnn!*s zcfXx{V2KYqkqK++^4^X!b=jV}+(a$Iy0_Mzx^IaOI*~Cemf0J1Vi`M@X>zTzM~m&) zT}!;zi6pFvxxM?&#GE}b*UYx^M`n9s)e_fSWwTV-tR0_iMq3w-vhDaiOU!j5No)G* zmov`vReSpCVf5$%o%*ylbr3#Jh0oiG`Q~biYbRDL@y4@;nX%H>zT%zqH9LLn&^$`D z)9+g1-DeI06J4MaU9hJh2d$Kqd+6lew{!11xuTsbI=O8-x9#K%J7;tmW|>`M;ZrTF8=SxmrwezZzH|@L$ zAzAhTja+9DC0%DtN=jcqdcN+G?y%j9XQQXOvrHthx6<{q=T1GIiv>enf8q@P$y@r{ z{jHh_LJ@S2!+fc#ZFq+`*z=&Gd)~c+8vENh548b4VCVZsM_-|Auk|VQx2WZga2u>Y zgjc;<^16N(n)DOZxCoD~-{0QnA%* zi{A7f+GBrDZ*%P_J@g0kP`_JM-<#?D9sVYS4H6$G37dFpNL7u=qJ7 zJf)HC(ILulWR>v|_JeNtFp*KzhMA?ghwp;ujk?@p8_KRs4V02AkbSB_uR_tA0LN=C=%_U@O3Aw+7JXk`u3DJ=q@o;7l(??4dj|o{@ zuy||9;%!3KwFPX9Hb=o|Yjj_{qjM*AW-j@B_kZ;7-RZ+M@xE}SDL$Clq1k;PKBQ`X zgu(G`>8Or2PgC4_^5m1xSU8c9$e7GnmctcS0=>49uRx(C#n};Bop#H?I-leT8z|s8 z2&|<_j=7q$OPFGifs#CuKLXZiTR+Kw#e58CleT4JMZg80L^=8(WX}5$pf`!-%L!nu zbjSpGrA{k@#K{%of`U+g$&2Z&(k~d065U+!Y}hhYlbQ^@0ar|l*Eb|kG`An|_>vlx zU$Y3}Fdw25PofBGqBvDat(siLpvtu~kogq-R3)!uJOFf4i1;NoD9YfH`koD_&(XUA z84mN7r5;is^;n1Yb?AJW0rUjfI2^YX?QQ9P3v?>DLMC`!d|4K04BTFgQQ&w9BP4nMi@IoA_z65UU9lr+m+TH`FsCSxoZl zZY_B44wCqy%yuwGM87CZnbGYx;4T%BUgO={GpYk(p}x|SCU$qWa@8RW{jbZ)f1@j% M`83sukZ=0-e_+Jw?EnA( literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc b/app/migrations/__pycache__/0037_driver_product.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03d4cfd61a754f5134bde7abdc995d3f97b8ee25 GIT binary patch literal 713 zcmY*X&ubGw6n?Y2ne48u)KCzcN+A|uK}tbT5GmA(QqdmN(-IiAd1Jb9vspKZn43Zm z9((J>KR{{!0FT~11%!mTdg?8ZiqMO`+3XUX!<+AWzvg{!_xs|a3v^B%*x@Gz@KclG zlyWfLB5(`{$RcPnpS2C&U|_&wK;sb5l&r;zqWOJd&aiI|EU$E?iDxLc9X8XT7k1*V z;_VK~sN0y=0600BB7tL&;4=i@K-OfwX@Im^*}(sn0F8k<##@*F_iKh0me4xo#W<(s z0#QeMV0(^oo)t6EfM$>+>eA-s?K=X~@U2W0&+l@QcCg>*y*&FveLYi^_M;$vO_G9l zB9d{lcc84eA4L>$Gif3Y+LCm;T=-*}y5-OXi* zT+K!@NcGptj0W9pGKVnX;H*tdW0}8yI&r~S{pgPD>d>x^uda=+tc)wQqno2jZCI&& zUjBOH+ruA~-Se{LxD%6C_=hLyO3`!Avy_9aAZ~Uxa6i+MDVV)_O{ZnKRYDi`{n`MS`SK0<=1b(#QbI5u-uLoXO2~%?|AQmg$E??|00F8=K~q`;X+X&d zfdJSu0jB7PJ+YJlzaZUkioK*8xTMI3R*v)1)GjJYP`Vy?>VL!t_A%=o7DZADBn^NL zY04BIg$_&Rhj+=?rNF~jv!pK75p0D9`t~8vZTr8S>AzUH^_D!_H z^`a1W6RCZ#N1!TYK$$_VY8#-Qiw^*f{TY^d*gm|Gw!tnbD>c8PH)24?DSlh}>`12&|k^ zR+uJ?1dh*Mo&FM;n+h-Ncuue<8s@wq9t)bC7FUDR^Td&nH7=8jm@x6euFE{iXCo)> z5SNmM=?mc(*uTzf$2V|in&N~&+R zoH*m$2qQL`-$yW#JwCTK@6}(t+^UOG>(lAhMbS0lq@9pdt?C`?ZgrhlwYA!6)Q#oe zl5G+szSs`H5CeT>sGtS>_Sw(?`r><|ua$dRd2nrMFkcyzDu=iFrAn_<`LOW$=9fp` zN?T_$s&4$LUHZGWc&UWnJ&nux_qR=z>$L3z&2W|OWVL4%k2Ab3WtnzSpmXj1xPcq- i4MCxJ5*Z&V5W=4rK=TaGLwsoT=azeO%Rhi1nfo{P$g6TB=t4i4 zoC3)`pcT!T^p}CXK!(c=@F74CuNZ7x-7(SsOy%Vf#5hD^;xBi%<0wq@eZHM#&v!ZK z`dn(>>kg)JG~o)HhiA1?e9=vV@QAFs)+yq literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc b/app/migrations/__pycache__/0039_alter_transportcarcassdetail_tracking.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b026427d6ffcd51307fbc7542a5e1df820d831e3 GIT binary patch literal 780 zcmZuv&ubGw6rS1LOm~-7YA6=0?I9Ln5!w(HQ;~wED2f*Rc~}C&G&4;%-OO(H2bh~e z4<38#zo4XlfJcvl7Xw1VTs`#`NJZ#HXEs^Vg9H2ad*8hG=6!GG``nxjAeJ zU&_f>VFE^*5*z~xDD*)ay0ERe8Uz}645)SpsLo&u!cZ)h%eShSq)C7)<;tD%M&&LpS8rFvl_VlO z4udFZkf=f8n6iX;zAz=<*!Otz_32-Ej$??zj!*c$R7~DspYdk0Ck&qYzCbDW4pQdm za!*YFbJAvVPuaq*$9%didoppxV=QcpWnAhriDxlBNQtjvl}A~~IAy%yu{cr#7xn`` zVbLR1B~pTgRof$DU)Vv&Cd2;>Mrs=8wc5S<%U4h8QgeNJHFc?e0~1vV|6i}7Gr4PF zCsMbc83p1kX%4{<0qf>a*A~$GXG0rUDF7qkSn3r^pBBDc z|GM?##hahSw`VhkWe;^!L?50;OL^ICIZcbU2yX^!bSKl9X&WDWRfT1-*CaYO?~jMI l8LdcHK57sveyBqT{~!RJGc*g)k=>tP?aiFyJR-5#L}fSwuc-o7&2u>5TKUwgaVI6{x$GVsMD=mI#Uz z6i5*Pt!cp&U&mp9nyq($LyXR0cFkeunjxP+g2Pgue)u;9M>5&>elO1-t%MwhPAv1~ zll)-$ROGA2tK$A(rEz^{hf3N?ItOZyjrIxVtMkUxpKdm|#)A9!R7-P?7syMYm8pj_ z&&{Z{pN*!u7}bIy7cLS;whFm`@#jWqIKrJ0G3ABunGjevYK8B6LR^eehuRQ<>XiXy zszx~*;as1+(u1;ZLl?_JB7J=(x3SNvZPQsP6;`ro! zi87S8>X#_UfsmoO_`d`pJt?r?U)k`}XXtK@kg#aOV@@Od=D+!7VvkUw6xPzz-9DU7 c%TEhWzntA1a#QHR zV{iQzl=R@A;N4R|NSLc9Z-G>Vo}Aevq=L@j&G)@|@6G$(%(wM*7t|U)vcsMVKbJ z#Bs`aln1LE0DD1Z9R*H-gO3>a218xsn+9;JS2lb(1ymbMpW)t>zx|pqi& z!^^f*J$ta`+0uEr>`1j|(kzp=o6Wm>ghmAyq!2X8vs4rT6#>n2#tRxo+8rE)NmpL` zcYv&BB4z!cAdD9LjjCMfL^L^)R??3m&s1~J+DSrVu6){7-iAD4hn^#CQu+yzE+Hze zA901NguLt1NXKf%c*YaPlOW`|(4&_2K4VXG4Pj~O9H^U1F5NWai=lspnV!VO{^R@Y zSFfM7mEQL1N!rckz2^TkUskl64TOI4(rA!BROT3_7@XGBG&b@37gHCU?T_x*u8-{c zWb4l4>di^5adK;1Ym91*Pn%y3zSs87*DS}Knz)8PJQvrO6%Rd2I;=;NZo11lrMyzq z{LU>MR>s~?=)!(5pHWNH6;;0&@@-|NCPL^p2IQUND#9o3cw=X@vGWTQDYO3oLG;Ap literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-39.pyc b/app/migrations/__pycache__/0040_transportcarcassdetail_product_date.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8236136b4e1ab62c53a42f765cb6f300333ff6c GIT binary patch literal 628 zcmZ`$&1&3044yyldY294(mX=JJuHUi(o)(KLPHMOz@{f-7$(+a@n$@BXS~py+iM;q zZ;^M%ZLU4_6$&BMI1SlDszE}ZBqV(rwX-uNDBtfs)wh(8UlDAJKyZNSU!ws6)R2Z2 zv|$CK5-#K{8= z)3($9j(9`dE6fh&&*|a&vawxNE|phsrJP)z9hZ25^7-mzp6}=XJHs}~d3WXFSC3Hr zE}E3H2ayQM@XhYU!;oEMB1~Yd?5dr^`LOt~?vQ+5?a|xAE+PH!c!H0Sm5)q!`CnQ( BupIyZ literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..15aa539f9059df5bde1511cfad6949bd082391db GIT binary patch literal 766 zcmZ`$O>fgc5S_K1jcuhUSXGN?Z!`#BN|1W0N+pUY0znUOvmz}^cAGl#7q)ZA4Wu48 z_SU}uO8)}CfKw!-M0@4L%~FbxdScg!6^dXEJ0S{EqZF_Vl6Q)_y4BYQhfvUP^O6jxvG6 znDHR%E^7el3o?5n!8vg75CczRsE0gV18(%of&VN4IR;bzaR0{jxMIw>sEwpFWf!;_ zN_I1cb=MTu%W57uoKBNO+-tXY+9XeDlqGSRcWK(CS;lxy{eUEC%m&?@Fq(6*_U|Oo zJfYdO%tIH6I^)N55ag~dcc65Wh=yDkrLP_PJYYwzB}`Jr2@y6SGH(!Yi5rBx8_+=I zD#m!iBgUhy&$CpmS(uL)J5)VVL(#@T90#06Wk}d@!WTRL3^TQet0#|lJFi|p>qx+J5tX^oxMC;rXZxvU$OUFg`sAD*Y{Rlg(G5Ekpxs26Xux248X+5E*dl~(57lIY6Z nn=fiVy)CJ_b+##8p(BKTVL?&q8w6YaYah z@F{ZZt0!L}AhCL)B#KtkMOD{FRefK>_I4`RE^ppcU!@S=Lh{%&CkK4pGj=FY)}oQQ zY@$4p;zVGC>a##aa;-k8T%lfyEdI_|kwrdjs+EPI>RRU~O@~ywGL#*<$< zUxaTIKV5g=6w0CU=4}~(F<1N<^R<9o9AwSWy5cW4{>vLiHh!Y wtYyR}{h{y1>RG1!4A;=Ex?Oxf?muol79ZBTk9N3=PxkJW*bn4fAUsz;0X$=|1poj5 literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..591592fc55c89449631c608623b205f2af888e6e GIT binary patch literal 4076 zcmdTHOKcleaJ~MmKS^yTO&m8Lm!_>9r6EC`p5KiP6BqWfy?21Thy&gc~#LcLwka}X?ZrrqusX(Hr*~7kh^PhS1 zW@mqDYx6VkeEyYB{65GqztK(eaqj?+asYh6AO<-krsT*u9290Hw&ct?ORk*D+B+q8 z&I5R-PZvOZ+9Vs0f-^ zmQ~^@l@XTI%Y|J94AZl-dDQQv-eD%^KunHh8L-Gb%V@*cy$JEW_^di?4004%>UC>x z5sREa^DTD1D9=EY$b|!o(Y=(#NDEx71+I554)WI0-!;$b&Z(?l=m*WCZ?weLUh z+P^Pz?MM4D*MWVR>%eQD>;4uuI*8h=+Zb;_gC2s~(Sfzls>`M>uqbSCzpAm3rhCt7g2);gPg5BLtggs_^3qFW)Ew;+q z6tH~gA9KET-50!n?e6;mTlAq`)Gj*K`kHl6^ya#2{mB91yVU%g!nf5aR4Qb6bTl=_ zYl+N0; zv4ltf2qJ*g(%sHoLrrwPMm)u;C?S<}wGM(rrsdmJQK?NR7-3lx1xY2Wh^7cTJ(+Zo zpitGyO~*-~qKG9ysqss=Mtmw(fL*)`PD9lBvWjgNoj?Vzy$CM|RY@ZpMxrLS;|bSiYdARa4SD)E*p*06Lr86_NVdCT*}&-0M5s)PX!^8D?pAkifA zyh0ld=~VAPDNz66j4D`$G!<$Joz2LB@!6Sk{A@Oz;V)g8OkX6yryL?yiGN(uurfuD zN}&@8@lTZ%EEeSpkUkGu6y#!=uqaPB>+oTWBi@Pe?8NwFngrlLpbjq4lPAG5VsRV} z!cs+iv$NBaHt4EWMMT{6og!_MATT4AuuTh|DVHTI$U8#kvsW(Lpub$fJ5%G=%p>rN zdGgW3JM)?B^gIMQzdKXTL-oJK3p5DcF70L|K)pSWZ&sW|kP#$Q!6TKL0%Ip*y?g+u z4anL(rr}|HiO>8dciiBPKj6&7X(Ms^XKuXCoocw9ot{rFHiC?=pK|mWTwlF=pdRk4 zM~>V-W=4(}ks}WV*Jn0A{9*39IWs+Lq-V|aO(T8NOfMMeg$BbcJ1(%We865~|D?+; z_78j6W|$6<-S)bC{)YcW1O5NTz(s1{DmzCFTxCUSfG*U);@=tA=MlX5s?Punyn-_r zpjFgwaQ*f0(O<&{_3okj%VzhG(LJ=``f*Ut@w%*Rb*p+vtB1SvXkx`so)@QD5Md$QT4!qOjsV_ZdJY~dFn}b{NvwG;<^Vkiv6`#;Ull5>^kDXXKX2wn! zu@mcfD|S*3y;l!+>pjVpF0&_T^d#3^8>y|H(|TyU9**g~!z)u}@37H3yq*Fry|$J< zePDED*&G-(21eJl%|ShL&CFakGS|&a-pJ(5%#x8=GBc`?QK23upx|M-!D3pLH`ppI zOS(W=#+NB6e229h9;0E58S$|V*Jeu3&Y9VHBRg+q3r4nJW+fvlnOV)qY9KPn=BOmk z7O7I6y+f7K1(Y8C*iu?!8y)`6_C}NmA6iK_ob18&?L#5BW2Z(Vo=?v!XPPY_=_3KV z>5UZ1@`Bw$eLEPGx4Ny}CwrbEN1(C5U+qY8mg$aP3a3}3f{=RY+ uw)DSMJqoXe)8TMD_Arjazc7i1O#C4e*!H~b@Z9&Cp+O@w_?Ur>rRFa!plHni literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-39.pyc b/app/migrations/__pycache__/0042_alter_driver_created_by_alter_driver_modified_by_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bedc2b3b1cfb45c433ddb0742cad5c826f48110c GIT binary patch literal 1771 zcmbVN&2QX96!+(@?e!*UvQ1M6&NFqjdW zV8j-)zjc^9ZhU8gIkMuWjs+Ij%pV6B-(jtBIQGZw@e1aFcF>r+(45-~JMR^C{!4bj zHT?x}J%6oh`fFXw-ztRA#yZw?y|4nSur_yw7TiGD4YoesK$!#Ua~owFDC;2CnVZPn zTyUEecMG|jXuDN$w~^bdJialv(Du#$@UKM}?O%(;&>H!$4J+J)x90Y!8Q+4paW>vj z{_%1Ua4Kv%oyPCqy?g&2DFn^rG#AByiUE}pSV4J8o={1qB8PHN5TFH94G{cGCR8vG z40#~Q?Cf&m-S-A5Zi*yXh?805DmO`K_Eb4pnWoCmGlFBs&_^g(TJ6o~gej}YBO3=) z4<)H2PDR}zXDO%_DmX56q|44#prtsOsm7?}DM+>X>LS$oQFc*sG20gmSXOYFN@a04 zRMt^9a#TpmB3~x1T2sL%RLsazHdDT20?qj)CXH1mxny;UHfk~JCa@tb(?WR+ctMjC z0V*?oQ8Lx4k*H9^!&nE&@@Is?vZ&co=~Wq^Qn^@yd=i;r8_%I~5ONw>!be8vTSPUp za*{A1l}8hawu2(F#j4gcD!8O-=F{q!pF~^ABUQG9sDKaztV|iMLqaY}nre^<5w_mk zk;w@T=nOa+Iz zV0@H)j_@^LOtVq0EJ&1BH6Je^)!g6h?eBIER0|t|b8xIXufjb(+Qmjxu9Sa%e$=g( zPFZqLuBP`@yNesn_=MHEa4*kOMzh7H&w7tf>Sd5m+2X$Y-VhHkv5Ne`x*zo?*>uo9 zrINyo3Ub;z>SOKws|&J^2jT-lbzP*M_T_Nk2>x5X9KuSG0b(rJ&U7YR45*tX6C|D; znATrT!!a#2uVt9X&GS~cD~gFGA7-SZa` zNUBEHExP?&xPt}YuV81{8*vZw6(4G%OSl5AUOhya@;4Bac=^+U*9nbXae*m$? B10eta literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0043_allproductstransport.cpython-39.pyc b/app/migrations/__pycache__/0043_allproductstransport.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e71007f2872da498e35f8c8f240e62821857e04 GIT binary patch literal 2434 zcmZWrOLG%P5ZdfCPn7(+tHgM`gPAwXV)0LC^66--jtz9_CtjdsS;h}Eu`Sz+XB za`k^mj`=+~q^eVuOHTZS971|#C0Vem+TQ7}d!~E(F(cY&R4sg-{c&4_OP2MIX67Fc znLGHZyGWSD?ARLEZQIskCw2yI+Z}jq&+u;Sw@Zk-ak*Xo#$q1xf3cX)-G1=1+YXq! zV}+&XxQ-Rt5GbByBI&Bof$BhXCCx;dC@2k5#$)v`(t7hx3z<9ks=pn};#S*cR@>q3 zuO9dNrQd93cb#@w+hPuLd8J=P`{)5HvGTEZ;III(8n5>oh>^f0Yyr92v5j1P z!Zi%HfZQVLE*fqLxh2#*h3~SNyHY@!1?2P`;;}Qvk5$C}^ zJQ;DQVY{k)Yx9sYoK+{RD`# zVku{!Iq%U-^(D`Zer-+<8hz2DOpwVM%M*59#ZM0tF5y%}C7JGzM0lP;ZBj8NXZ5a3 zl_G~+bbA@pGAj9$sU|#|ja5Wrp3kr5V>7*xk1-`&3^Q05C2@+5C0&z6sLXh9(@_T1 zlPW!0xpX;-sZybumRV;U`g1|9qzS>}pJ!NSlEY*W6rE#odY>HWL zHLqrMRL4$f&D8Sh${XRRd18CoADuA-w4-#WGOQ`jSSn%X#7sds9hw{IVR#M#Vyc}G zs1ocZHo~|Ns1t%U5bIflNLS~-sSeQtUH`a^Ax{`jqOrsa3rk~tZ}(fWx3l$#Y=6JG z^#JNK4Z#)EHcT^b>)TK2TNmngMRy%L@}BkwDtmkPH}j!48VLrzrq`jdi9y;G1D?z3 zchfZHG?`4==utTtYQ20|y@v_Qrei!CL^t^ko4myO*c>T1tOJ3`0^Z0_-dNw+Sl`@& zU}tNWJluQm0IKPbPwwmAE%_rlYskNMHgD_?l3}#}h$_m)ScQ*v?(btj_D?SOeLTjl z;c*pD(>KdrYdDrZu2sQT{e&cNtG4r>SMqGfY1&PD!TgqO{cGAw=9|+Tdzmhw##E}m z3-(3(f_?EX=d$<0`O|x0Y=sqU4YTW3lqLsxrYaMJbxcz8Y^=?|78U^hLupMTB=>Xx fwl&f2pTr{{?IQ-k&Ae)E=_*kHk~%sU*n#^$t@GW9 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0044_evacuationdetail.cpython-39.pyc b/app/migrations/__pycache__/0044_evacuationdetail.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dbd645db2b3b017d498de0bcd2486d432fb406e4 GIT binary patch literal 2215 zcmZuyO>^5e5apL7ilSs$u@gIK6E|(zs2{G|xR*|*jV;-+rnQrit&7Gp9EgA=$P}pn zWD@1tUiBZ^WB*C-ybmS3fiW_>=E&+=3Y$T$n+M(u3f;nE4O=+(vxalT9NIsb zT^pOHT0Q?7;%IeU*qp>M4g0)q2xmn548=4GxyX+qOagx5OTXpkK7dE?@v)(4MCl(!T#Ui<3{#PCAeWP2Dxv+svQXD#vA1c6kT$oxH2DX7K5qDSy&cem137i951yE_K z19E4mtWX8e3iz%lR0UL35m%=M_|^cg0=@>{nu@iaVXkMG8^FkX7EYsV0A7x|`4+yJ ziE!&JkM}Yj?`N3X8RiZ!%XMsJJU+-UcQed~8Rnx5b1%bu49xPJKgoF9&oFghmh1f# za80fwxi(xI7KiJ@>-aON1N`|k2fOpdJM7!|%b9iO9oDZFqx*O8*EmOY{9tPK_3jP4 z3%dPA6p!a31;v_ZJnnAp?Cd`9P!Nn+gcCpJF+(9AM=TcAgXhRkl%$&^Ml=ux#b<}Y zXf^AWa8VLRp3ex12^OU>qa(y7-X)ocA}5TZfW9KaeNI>};=~KlhzJv`byE~Dxj;z} z3!7jXqh3HnJ_+fwgosia(8CZF4p^Ebj9z#MLlQVv^kOnM+NuIDiX0Tp2X&pTz}XV( z`z)dXVTVEFU$zN^<#7wcgmb+Bg_pt#lOPc88AJXh9Nq?;)z`nnz`Dsc|<<0!&=qbLbsZn7_9r@a$7|H?e)X^i58 zi_QPzCgDD#WBCser89In2xywMwgl#R-8gkfGq0US3G+!Or14Y4V7e-EWx=ZaZi*X3 zdWdR@mi$XlfefLX%K(;al_P?JcmU}~RE~Dqgj1Z>x4P)h%PTQuo~_GFCSGqMZjvii zVWq0MhI*5FPHn(!(WB6VpD2MvcNqz!%2E*-aU|>kiv0m>o~SLtfxA>Gf8~O(x34@> z)le7?*>5e}XW5mezzRki^`!j$7&K}r!R9Y02{0FhNbL$gsc#6|Q+0Tra6Au2Cjo)J z>v_)-6v$DY$4n`kHU0t$k@AMh#w5ff^d}5{{F+$V>zo~VozsK1cl@Mz@S||AJSgF! z)KJIjSl%K`-d@7pr~N%RaEG!UQS5YD&9rMJ3B@8O+g(wX8a<;UlG@z;C<+J)XQ&m% zqz}g;4bd2&S=Tv?7@_^}2ROQUJVaqX5(e%GTP?p7W1+Ek+SqFz2qzko*(LXz#?GKJ z)%^3Y`R(~A9Q)^O#1Wn#=Cw~-=P>*8#jSV_f0|wI?e*UtPgoA(6yf7-Xl&Ebjeo7Y zr5nbYzNS~yTh(jot?KfvsZTO^_OwidSm=)y;1S&MNvxUw(UpZMY;{e z8H0Oj$I_+Vydt+@ci|e}p05LYA}4$#8(H#V{%NlRoUk9JlK4(afZNcxP^7Kf=6|*5 Boq7NO literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-39.pyc b/app/migrations/__pycache__/0045_remove_evacuationdetail_broilerflockrequestid_and_more.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..790ab8ffbd5839e0e40067d58d4ec4bbf97a767d GIT binary patch literal 3565 zcmdT{OOx9~5SA=IWqac!yMaJ}@W{gumH-KlBqVWc@5UrfQnt6KaxJAAduF}zjwNSC zPS%`K1=sx#aO9tGr;5W|IpxlYDjq!}*`Cc>oN~b~$zS)^(>*iY(~?oKXdCd^|Mix8 z_M&0@E(QIQ1mQMZ{2JV_flX?R%&uuloS=!3)wM>+Zc@n>O?A_o22SGC4+c&VYnb`o z>SnOjHp=PeFy1JeBFjk-xZZ%56T%+31BL?E_qa%pd`u{R(3f`lrv}1pxcF}{7h-fx zY;+UE`Y}mT!}L!kHV27r24ZD#0$VtF0Gz@p4W~7n(QsD7IStzy&TF`!;i86DG<;0M zB@G|f@Cgl{)bOf?*ED=e!>?%gRSlok@M{sy!JfQM>|q|C!EYRx_{{?gc1LR8TB z>OKPf3e5AxRbP%g9bNUuvCJniF+PonaV6H%)mY}Um>8c&BaZI*7qQHju~DwYGS_37 z8?nq+vCPd_=2k3o8<=I8tibxzH-GOPf&lNS|la`a%s2p zqDHLUVZKWV+n|1buSFhD2oD-qwO83v9S@C&NUD3WM))JdfUW{1@*r+`Zty@_*qgqO zD_wlsWBD`^wky}>V7a(FQ%ebjLJ)?Gs0yY2(}u@k9UJg$%V4sDCNwBpEC)|4CLgUL zwc`?sMPAu%jg`+_oiU%uS#=;!sUAh%9;9eOsj%z&0bw4Z4gCBU7!SVAOE>li?K_ls zgJ73kkcwQGBblxOBZ3{&1D-ee0_SLyc&=c062hSX)6php8D(oJ8LLLvNZ@1hZRMYieJJzPUm ziCP44xwjIHeUhLR5%iQ55#5)--k(G%HFC0EpE z1d0edz3F!+&t2?O#Ce%Jk+wH2r&M;MjQXAf34$2EIt(p2(_Ak>@f~t+cC^T3y)wm_%=m zKO3wEvDNL*UhUfU$Q$>!TZkh(Ma*fn8{4qb?ZvC+HZ<0&4pXZ*(qElk*i3h1Gi6~j zb+Lmy4BN@b`gqDx5G@NAzXaQrwQMu-cQTzc6Y@9tzx*}rzmh36a}5>dx|KOvrdu|4 zF=827cv+yAW4Fx9%h4@nx( zPLykV)qiM@{SW;Yz42P0K+ioC=%MK>SBi7!3LNm884kaBP^8;!8}PmP?JNG!HH_bD z@Zo0zcmb<806`6kgpr^Kp?Yr$GqEBou_Ie!OE{4WdP}sT*4GBLsq>>j9cInFAFRlu z*2oCmKOv40BIOmVEO|OBLQ}O9K9i*6Sz0JJ$tV-W*`)US@Y@3L0#@+{2xdfx8j;DY zpKRvL-JcOfGc#({cTtmC%%8X6eqcad+FIIElX{@*uwdQ=olX6v1-drqHUM>&2vD#> zU5z#X^}x5M(I%ix9r4c61m7*dcK~n0>g!l{L9l*#GEu`*AFp{)W^l^LE$ zMoLCiCzm`Sa)GbeLiq)goCyAwso;jmI4c-VNy3x`*3eQd%BG|erScf%C5Z)7Zk2Ml zUv-**m_k(Odvi&ey~c#XCD3g?U963sW&lRzl#&!zA(B1lwz4^Jg#tLSAnCQT(@F?s zPa#wOs|n*|$(`D*osc(Juyj^l$z82jC4=L|+wIT3mLN5bnq{^k%0UI8`nRDpe^AE@<&n4m){_$IVe8_!Q_ch}R4dE%aG!-c%ELM+ z#;T2>C$tg__5sGPDkADr7)z_>-Y;H5yX#T{tDL2jrIUq(Yz@`hzr6ScUyhE>@#)Lq z(f2BN@4;E2I)}Q2r}aaU^#fMH0iW$dbB}92%D=ok88%zHsyJ0nEg!4y5OTiY32SV@ zL6!+d($%4FM=#G-+ruj&n{E3Tri#zf?_fq;Iw$E2MvBJD(}jcwty+isqr?5-k!oi- zTRrk$4EYpjY4OkA@aZ^7^T~KUn)rNlGKSR0xBm)bnE5X;OoX0Yu+{T0$QROqFg~o} za}b`@M&`e^Ya`R_qdwZuzfH7-9-s$*n}Pk#{L6l)&xF3}G;{}(ES)xG^;a4i>kc%f v+kLMbK)2wZX|PUBK7l*spcXZa+mxE!9_Wg`kg5bJ?=^*+sh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DD#VV#Ku{bfM zGO;KoDA+S5v7jI(H#5B`u_QA;uQ(TZlX-=vg$c$npAi=@_ E05aGeEdT%j literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/__init__.cpython-311.pyc b/app/migrations/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d9eb0f3000d87222480f5111e2b85edaa23f737 GIT binary patch literal 142 zcmZ3^%ge<81oiH}(?RrO5CH>>P{wCAAY(d13PUi1CZpd2X#0(Sz007w@umAu6 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/__init__.cpython-312.pyc b/app/migrations/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e29035b25deb6303f419fa49925c3936256eaf04 GIT binary patch literal 130 zcmX@j%ge<81go7mGC}lX5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!QgpV82@3X%Nh~Oc z$<0hJN-W9D&nu3JkI&4@EQycTE2#X%VUwGmQks)$SHud`!3e~~AjU^#Mn=XWW*`dy DUt1g5 literal 0 HcmV?d00001 diff --git a/app/migrations/__pycache__/__init__.cpython-39.pyc b/app/migrations/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca5bdc667143004f2fd1fc5cb54e28e6104f00eb GIT binary patch literal 138 zcmYe~<>g`kf{M%bnIQTxh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DX#VRH@uOK-l zD6u#(r82Q7J}B5TCb6I(CO0#^D6u3nKd(3@K0Y%qvm`!Vub}c4hfQvNN@-529mt^1 HK+FIDmhK;g literal 0 HcmV?d00001 diff --git a/app/models.py b/app/models.py new file mode 100644 index 0000000..619461e --- /dev/null +++ b/app/models.py @@ -0,0 +1,720 @@ +import datetime +import re +from datetime import timedelta +from itertools import product + +from app.cityandprovince import search_province_list, correct_province, search_city_list, correct_city, normalize_text +from app.helper_excel import correction_dict +from authentication.models import BaseModel +from django.db import models + +from helpers import convert_to_miladi + + +class Poultry(BaseModel): + UserName = models.CharField(max_length=200, null=True) + Password = models.CharField(max_length=200, null=True) + FirstName = models.CharField(max_length=200, null=True) + LastName = models.CharField(max_length=200, null=True) + UserGroupName = models.CharField(max_length=200, null=True) + UserRoleName = models.CharField(max_length=200, null=True) + UserGroupId = models.CharField(max_length=200, null=True) + UserRoleId = models.CharField(max_length=200, null=True) + Mobile = models.CharField(max_length=200, null=True) + Email = models.CharField(max_length=200, null=True) + UserIsActive = models.BooleanField(null=True) + UserIsActiveDescription = models.CharField(max_length=200, null=True) + RegDate = models.CharField(max_length=200, null=True) + RegDateShamsi = models.CharField(max_length=200, null=True) + RegDateShamsiWithTime = models.CharField(max_length=200, null=True) + RegDateShamsiOnlyTime = models.CharField(max_length=200, null=True) + StringId = models.CharField(max_length=200, null=True) + IsPersisted = models.BooleanField(null=True) + AllowInsert = models.BooleanField(null=True) + AllowUpdate = models.BooleanField(null=True) + ModalCss = models.CharField(max_length=200, null=True) + GridContainerParametersModel = models.CharField(max_length=200, null=True) + MenuUserAccess = models.CharField(max_length=200, null=True) + MenuUserAccessId = models.CharField(max_length=200, null=True) + LogTableName = models.CharField(max_length=200, null=True) + LogTableAlias = models.CharField(max_length=200, null=True) + PageTitle = models.CharField(max_length=200, null=True) + UnitName = models.CharField(max_length=200, null=True) + SystemCode = models.CharField(max_length=200, null=True) + TrackingCode = models.CharField(max_length=200, null=True) + EpidemiologicCode = models.CharField(max_length=200, null=True) + PartIdCode = models.CharField(max_length=200, null=True) + PostalCode = models.CharField(max_length=200, null=True) + UnitId = models.CharField(max_length=200, null=True) + UnitTypeId = models.CharField(max_length=200, null=True) + UnitTypeName = models.CharField(max_length=200, null=True) + LocationIdProvince = models.CharField(max_length=200, null=True) + LocationIdCity = models.CharField(max_length=200, null=True) + LocationNameProvince = models.CharField(max_length=200, null=True) + LocationNameCity = models.CharField(max_length=200, null=True) + UnitIsActive = models.BooleanField(null=True) + UnitIsActiveDescription = models.CharField(max_length=200, null=True) + PId = models.CharField(max_length=200, null=True) + Province = models.CharField(max_length=500, null=True, blank=True) + City = models.CharField(max_length=500, null=True, blank=True) + + def save(self, *args, **kwargs): + super(Poultry, self).save(*args, **kwargs) + + +class PoultryHatching(BaseModel): + poultry = models.ForeignKey( + Poultry, + on_delete=models.CASCADE, + related_name="hatching_poultry", + null=True + ) + DesCertId = models.CharField(max_length=200, null=True) + UnitId = models.CharField(max_length=200, null=True) + BroilerFlockRequestId = models.IntegerField(null=True) + RequestCode = models.CharField(max_length=200, null=True) + StartDate = models.CharField(max_length=200, null=True) + StartDatePersian = models.CharField(max_length=200, null=True) + EndDate = models.CharField(max_length=200, null=True) + EndDatePersian = models.CharField(max_length=200, null=True) + HatchingDate = models.CharField(max_length=200, null=True) + HatchingDatePersian = models.CharField(max_length=200, null=True) + Date = models.DateTimeField(null=True) + HatchingAge = models.IntegerField(default=1) + MaxHatchingDate = models.CharField(max_length=200, null=True) + MaxHatchingDatePersian = models.CharField(max_length=200, null=True) + HatchingCount = models.IntegerField(null=True) + HatchingCountInBargiri = models.IntegerField(null=True) + HatchingCountInTakhlie = models.IntegerField(null=True) + TrackingCount = models.IntegerField(null=True) + TrackingBargiriCount = models.IntegerField(null=True) + PercentHamlToMojavez = models.IntegerField(null=True) + PercentTakhlieToBargiri = models.IntegerField(null=True) + FlockAgeDay = models.IntegerField(null=True) + PartIdCode = models.CharField(max_length=200, null=True) + UnitName = models.CharField(max_length=200, null=True) + PostalCode = models.CharField(max_length=200, null=True) + EpidemiologicCode = models.CharField(max_length=200, null=True) + CapacityFemale = models.IntegerField(null=True) + PersonFullName = models.CharField(max_length=200, null=True) + LocationIdProvince = models.CharField(max_length=200, null=True) + LocationNameProvince = models.CharField(max_length=200, null=True) + LocationIdCity = models.CharField(max_length=200, null=True) + LocationNameCity = models.CharField(max_length=200, null=True) + Mobile = models.CharField(max_length=200, null=True) + HamlMorghMinDate = models.CharField(max_length=200, null=True) + HamlMorghTotalCount = models.IntegerField(null=True) + HamlMorghTakhlieCount = models.IntegerField(null=True) + EvacuationCount = models.IntegerField(null=True) + EvacuationCount_1 = models.IntegerField(null=True) + EvacuationCount_2 = models.IntegerField(null=True) + EvacuationCount_3 = models.IntegerField(null=True) + BaseHatchingCount = models.IntegerField(null=True) + PercentMorghToJoojeTotal = models.IntegerField(null=True) + PercentMorghToJoojeTakhlie = models.IntegerField(null=True) + PercentMorghToJoojeTakhlieWithEvacutaion = models.IntegerField(null=True) + PercentNotDeliverd = models.IntegerField(null=True) + PercentDeliveredForSP = models.IntegerField(null=True) + PercentDeliveredForSPNoExclude = models.IntegerField(null=True) + PercentDeliveredWithoutEvac = models.IntegerField(null=True) + DiffHamlThanTakhlieCount = models.IntegerField(null=True) + DiffTakhlieThanHamlCount = models.IntegerField(null=True) + PedigreeName = models.CharField(max_length=200, null=True) + LeftOver = models.IntegerField(null=True) + + def save(self, *args, **kwargs): + if hasattr(self, 'PedigreeName') and self.PedigreeName in correction_dict: + self.PedigreeName = correction_dict[self.PedigreeName] + self.LeftOver = self.HatchingCount - self.EvacuationCount + hatching_date = self.HatchingDatePersian.split('/') + date = convert_to_miladi( + year=int(hatching_date[0]), + month=int(hatching_date[1]), + day=int(hatching_date[2]) + ) + self.Date = date + super(PoultryHatching, self).save(*args, **kwargs) + + +class Hatching(BaseModel): + poultry = models.ForeignKey( + Poultry, + on_delete=models.CASCADE, + related_name="poultry_hatching_poultry", + null=True + ) + Date = models.DateTimeField(null=True) + ArchiveDate = models.DateTimeField(null=True) + BroilerFlockRequestId = models.IntegerField(null=True, blank=True) + InsertDate = models.CharField(max_length=200, null=True, blank=True) + LastChangeStatusDate = models.CharField(max_length=200, null=True, blank=True) + LastChangeStatusDateShamsi = models.CharField(max_length=200, null=True, blank=True) + FlockRequestUnitName = models.CharField(max_length=200, null=True, blank=True) + PedigreeName = models.CharField(max_length=200, null=True, blank=True) + StatusId = models.IntegerField(null=True, blank=True) + Status = models.IntegerField(null=True, blank=True) + StatusName = models.CharField(max_length=200, null=True, blank=True) + PedigreeType = models.IntegerField(null=True, blank=True) + BroilerPedigreeTypeName = models.CharField(max_length=200, null=True, blank=True) + StatusColor = models.CharField(max_length=200, null=True, blank=True) + SystemRevocationDate = models.CharField(max_length=200, null=True, blank=True) + RemindDays = models.IntegerField(null=True, blank=True) + PartyCount = models.IntegerField(null=True, blank=True) + GoodCount = models.IntegerField(null=True, blank=True) + ShowButtons = models.BooleanField(null=True, blank=True) + HasSync = models.BooleanField(null=True, blank=True) + BroilerFlockRequestExpireStatus = models.IntegerField(null=True, blank=True) + IdWithFormat = models.CharField(max_length=200, null=True, blank=True) + ProvinceName = models.CharField(max_length=200, null=True, blank=True) + CityName = models.CharField(max_length=200, null=True, blank=True) + Address = models.CharField(max_length=200, null=True, blank=True) + UnitTel = models.CharField(max_length=200, null=True, blank=True) + UnitPostalCode = models.CharField(max_length=200, null=True, blank=True) + UnitName = models.CharField(max_length=200, null=True, blank=True) + SystemCode = models.CharField(max_length=200, null=True, blank=True) + CapacityFemale = models.IntegerField(null=True, blank=True) + EpidemiologicCode = models.CharField(max_length=200, null=True, blank=True) + RequestCode = models.CharField(max_length=200, null=True, blank=True) + RequestDate = models.CharField(max_length=200, null=True, blank=True) + RequestDateFa = models.CharField(max_length=200, null=True, blank=True) + RequestCount = models.IntegerField(null=True, blank=True) + DeliverDate = models.CharField(max_length=200, null=True, blank=True) + DeliverDateFa = models.CharField(max_length=200, null=True, blank=True) + UnionName = models.CharField(max_length=200, null=True, blank=True) + PersonTypeId = models.IntegerField(null=True, blank=True) + PersonType = models.IntegerField(null=True, blank=True) + PersonTypeName = models.CharField(max_length=200, null=True, blank=True) + PersonFullName = models.CharField(max_length=200, null=True, blank=True) + NationalCode = models.CharField(max_length=200, null=True, blank=True) + InteractType = models.IntegerField(null=True, blank=True) + InteractTypeName = models.CharField(max_length=200, null=True, blank=True) + UnionTypeId = models.IntegerField(null=True, blank=True) + UnionTypeName = models.CharField(max_length=200, null=True, blank=True) + SendDate = models.CharField(max_length=200, null=True, blank=True) + SendDateFa = models.CharField(max_length=200, null=True, blank=True) + ChickCountSum = models.IntegerField(null=True, blank=True) + CalculatedDate = models.CharField(max_length=200, null=True, blank=True) + CalculatedDateFa = models.CharField(max_length=200, null=True, blank=True) + PartIdCode = models.CharField(max_length=200, null=True, blank=True) + CertId = models.CharField(max_length=200, null=True, blank=True) + StartDate = models.CharField(max_length=200, null=True, blank=True) + StartDateFa = models.CharField(max_length=200, null=True, blank=True) + EndDate = models.CharField(max_length=200, null=True, blank=True) + EndDateFa = models.CharField(max_length=200, null=True, blank=True) + RemainCredit = models.IntegerField(null=True, blank=True) + StrRemainCredit = models.CharField(max_length=200, null=True, blank=True) + ShowStatus = models.CharField(max_length=200, null=True, blank=True) + ValidStatus = models.CharField(max_length=200, null=True, blank=True) + ValidStatusName = models.CharField(max_length=200, null=True, blank=True) + RegDate = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsi = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsiWithTime = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsiOnlyTime = models.CharField(max_length=200, null=True, blank=True) + HatchingId = models.CharField(max_length=200, null=True, blank=True) + StringId = models.CharField(max_length=200, null=True, blank=True) + IsPersisted = models.BooleanField(null=True, blank=True) + AllowInsert = models.BooleanField(null=True, blank=True) + AllowUpdate = models.BooleanField(null=True, blank=True) + ModalCss = models.CharField(max_length=200, null=True, blank=True) + GridContainerParametersModel = models.CharField(max_length=200, null=True, blank=True) + MenuUserAccess = models.CharField(max_length=200, null=True, blank=True) + MenuUserAccessId = models.IntegerField(null=True, blank=True) + LogTableName = models.CharField(max_length=200, null=True, blank=True) + LogTableAlias = models.CharField(max_length=200, null=True, blank=True) + PageTitle = models.CharField(max_length=200, null=True, blank=True) + Evacuation = models.IntegerField(default=0) + Age = models.IntegerField(null=True) + KillingAve = models.IntegerField(default=0) + Period = models.IntegerField(default=1) + LeftOver = models.IntegerField(null=True) + samasat_discharge_percentage = models.IntegerField(default=0) + GoodSum = models.IntegerField(default=0) + + def save(self, *args, **kwargs): + if hasattr(self, 'PedigreeName') and self.PedigreeName in correction_dict: + self.PedigreeName = correction_dict[self.PedigreeName] + try: + date1 = AllProductsTransport.objects.filter(hatching__id=self.id, trash=False, product='جوجه یک روزه گوشتی').order_by('date').first().date + date = datetime.datetime(year=date1.year, month=date1.month, day=date1.day, hour=10, + minute=1, + second=1) + except: + hatching_date = self.SendDateFa.split('/') + date = convert_to_miladi( + year=int(hatching_date[0]), + month=int(hatching_date[1]), + day=int(hatching_date[2]) + ) + self.Date = date + self.Age = (datetime.datetime.now().date() - self.Date.date()).days + 1 + if self.ProvinceName and self.ProvinceName not in search_province_list: + self.ProvinceName = correct_province(self.ProvinceName) + if self.CityName and self.CityName not in search_city_list: + self.CityName = correct_city(self.CityName, self.ProvinceName) + self.ChickCountSum = self.GoodSum + super(Hatching, self).save(*args, **kwargs) + + +class TransportingDetail(BaseModel): + hatching = models.ForeignKey( + Hatching, + on_delete=models.CASCADE, + related_name="transport_hatching", + null=True + ) + BroilerFlockRequestId = models.IntegerField(null=True, blank=True) + TrackingCode = models.CharField(max_length=200, null=True) + DesCertId = models.CharField(max_length=200, null=True) + IssueDate = models.CharField(max_length=200, null=True) + IssueDatePersian = models.CharField(max_length=200, null=True) + GoodCode = models.IntegerField(null=True) + GoodName = models.CharField(max_length=200, null=True) + GoodAmount = models.IntegerField(null=True) + TrackingStatus = models.IntegerField(null=True) + TrackingStatusDescription = models.CharField(max_length=200, null=True) + TakhlieDate = models.CharField(max_length=200, null=True) + TakhlieDatePersian = models.CharField(max_length=200, null=True) + SourcePartIdCode = models.CharField(max_length=200, null=True) + SourceUnitPartIdCode = models.CharField(max_length=200, null=True) + SourceUnitName = models.CharField(max_length=200, null=True) + SourceCertId = models.CharField(max_length=200, null=True) + ResideDate = models.CharField(max_length=200, null=True) + ResideDatePersian = models.CharField(max_length=200, null=True) + PedigreeName = models.CharField(max_length=200, null=True) + DesUnitName = models.CharField(max_length=200, null=True) + DesPartIdCode = models.CharField(max_length=200, null=True) + HealthPermitId = models.IntegerField(null=True) + Province = models.CharField(max_length=200, null=True) + City = models.CharField(max_length=200, null=True) + Age = models.IntegerField(null=True) + Date = models.DateTimeField(null=True) + Out = models.BooleanField(default=False) + + def save(self, *args, **kwargs): + issue = self.IssueDatePersian.split('/') + date = convert_to_miladi( + year=int(issue[0]), + month=int(issue[1]), + day=int(issue[2]) + ) + self.Date = date + kill_house = KillHouse.objects.filter(PartIdCode=self.DesPartIdCode, trash=False).first() + if kill_house: + self.Province = kill_house.Province + self.City = kill_house.City + if self.Province and self.Province not in search_province_list: + self.Province = correct_province(self.Province) + if self.City and self.City not in search_city_list: + self.City = correct_city(self.City, self.Province) + super(TransportingDetail, self).save(*args, **kwargs) + + +class TransportingChickenDetail(BaseModel): + hatching = models.ForeignKey( + PoultryHatching, + on_delete=models.CASCADE, + related_name="transporting_hatching", + null=True + ) + TrackingCode = models.CharField(max_length=200, null=True) + DesCertId = models.CharField(max_length=200, null=True) + IssueDate = models.CharField(max_length=200, null=True) + IssueDatePersian = models.CharField(max_length=200, null=True) + issue_date = models.DateTimeField(null=True) + GoodCode = models.IntegerField(null=True) + GoodName = models.CharField(max_length=200, null=True) + GoodAmount = models.IntegerField(null=True) + TrackingStatus = models.IntegerField(null=True) + TrackingStatusDescription = models.CharField(max_length=200, null=True) + TakhlieDate = models.CharField(max_length=200, null=True) + TakhlieDatePersian = models.CharField(max_length=200, null=True) + SourcePartIdCode = models.CharField(max_length=200, null=True) + SourceUnitName = models.CharField(max_length=200, null=True) + SourceCertId = models.CharField(max_length=200, null=True) + ParentPartIdCode = models.CharField(max_length=200, null=True) + ParentUnitName = models.CharField(max_length=200, null=True) + CertId = models.CharField(max_length=200, null=True) + ResideDate = models.CharField(max_length=200, null=True) + ResideDatePersian = models.CharField(max_length=200, null=True) + reside_date = models.DateTimeField(null=True) + PedigreeName = models.CharField(max_length=200, null=True) + BroilerFlockRequestId = models.IntegerField(null=True) + SourceUnitPartIdCode = models.CharField(max_length=200, null=True) + DesUnitName = models.CharField(max_length=200, null=True) + DesPartIdCode = models.CharField(max_length=200, null=True) + HealthPermitId = models.IntegerField(null=True) + ProvinceId = models.CharField(max_length=200, null=True) + Province = models.CharField(max_length=200, null=True) + age = models.IntegerField(default=1) + + def save(self, *args, **kwargs): + Issue = self.IssueDatePersian.split('/') + date = convert_to_miladi( + year=int(Issue[0]), + month=int(Issue[1]), + day=int(Issue[2]) + ) + self.issue_date = date + + Reside = self.ResideDatePersian.split('/') + date = convert_to_miladi( + year=int(Reside[0]), + month=int(Reside[1]), + day=int(Reside[2]) + ) + self.reside_date = date + if self.hatching: + self.age = (self.issue_date.date() - self.hatching.Date.date()).days + 1 + super(TransportingChickenDetail, self).save(*args, **kwargs) + + +class KillHouse(BaseModel): + PartIdCode = models.CharField(max_length=250, null=True, blank=True) + UnitName = models.CharField(max_length=250, null=True, blank=True) + Province = models.CharField(max_length=250, null=True, blank=True) + City = models.CharField(max_length=250, null=True, blank=True) + ProvinceId = models.CharField(max_length=200, null=True, blank=True) + CityId = models.CharField(max_length=200, null=True, blank=True) + + def save(self, *args, **kwargs): + super(KillHouse, self).save(*args, **kwargs) + + +class ApkInfo(BaseModel): + info = models.JSONField(null=True) + download_link = models.CharField(max_length=700, null=True, blank=True) + + def save(self, *args, **kwargs): + super(ApkInfo, self).save(*args, **kwargs) + + +class TransportCarcassDetail(BaseModel): # بارهای لاشه + id_quarantineh = models.CharField(max_length=255, null=True, blank=True) # id + destination_prev = models.CharField(max_length=255, null=True, blank=True) # مقصد قبلی + destination_changed = models.CharField(max_length=255, null=True, blank=True) # تغییر مقصد + payment = models.CharField(max_length=255, null=True, blank=True) # پرداخت + tracking = models.CharField(max_length=255, null=True, blank=True, unique=True) # رهگیری + date = models.DateField(null=True, blank=True) # تاریخ + time = models.TimeField(null=True, blank=True) # ساعت + product = models.CharField(max_length=255, null=True, blank=True) # محصول + items = models.CharField(max_length=255, null=True, blank=True) # اقلام + quantity = models.FloatField(null=True, blank=True) # مقدار + unit = models.CharField(max_length=50, null=True, blank=True) # واحد + origin_province = models.CharField(max_length=255, null=True, blank=True) # استان مبدا + origin_city = models.CharField(max_length=255, null=True, blank=True) # شهرستان مبدا + origin = models.CharField(max_length=255, null=True, blank=True) # مبدا + destination_province = models.CharField(max_length=255, null=True, blank=True) # استان مقصد + destination_city = models.CharField(max_length=255, null=True, blank=True) # شهرستان مقصد + destination = models.CharField(max_length=255, null=True, blank=True) # مقصد + jihadi_origin = models.CharField(max_length=255, null=True, blank=True) # ش جهادی مبدا + jihadi_destination = models.CharField(max_length=255, null=True, blank=True) # ش جهادی مقصد + owner = models.CharField(max_length=255, null=True, blank=True) # مالک + car_tracking_code = models.CharField(max_length=255, null=True, blank=True) # کد رهگیری خودرو + driver_name = models.CharField(max_length=255, null=True, blank=True) # نام راننده + plate = models.CharField(max_length=50, null=True, blank=True) # پلاک + amount = models.DecimalField(max_digits=20, decimal_places=2, null=True, blank=True) # مبلغ + unloading = models.CharField(max_length=255, null=True, blank=True) # تخلیه + gross_weight = models.FloatField(null=True, blank=True) # وزن پر + tare_weight = models.FloatField(null=True, blank=True) # وزن خالی + net_weight = models.FloatField(null=True, blank=True) # وزن + scale_code = models.CharField(max_length=255, null=True, blank=True) # کد باسکول + scale_name = models.CharField(max_length=255, null=True, blank=True) # نام باسکول + scale_receipt = models.CharField(max_length=255, null=True, blank=True) # قبض باسکول + unloading_date = models.DateField(null=True, blank=True) # تاریخ تخلیه + out = models.BooleanField(default=False) # Out (True/False) + product_date = models.DateField(null=True, blank=True) # تاریخ + has_product_date = models.BooleanField(default=False) # دارای تاریخ + + def save(self, *args, **kwargs): + if self.origin_province: + self.origin_province = normalize_text(correct_province(self.origin_province)) + if self.origin_city: + self.origin_city = normalize_text(correct_city(self.origin_city, self.origin_province)) + + if self.destination_province: + self.destination_province = normalize_text(correct_province(self.destination_province)) + if self.destination_city: + self.destination_city = normalize_text(correct_city(self.destination_city, self.destination_province)) + if isinstance(self.product_date, str): + try: + self.product_date = datetime.datetime.strptime(self.product_date, '%Y-%m-%d').date() + except ValueError: + try: + self.product_date = datetime.datetime.strptime(self.product_date, '%Y/%m/%d').date() + except ValueError: + self.product_date = None + super(TransportCarcassDetail, self).save(*args, **kwargs) + + +class Guilds(BaseModel): + name = models.CharField(max_length=255, null=True, blank=True) + city = models.CharField(max_length=255, null=True, blank=True) + province = models.CharField(max_length=255, null=True, blank=True) + jihadi_code = models.CharField(max_length=255, null=True, blank=True) + is_steward = models.BooleanField(default=False) + + def save(self, *args, **kwargs): + if self.province: + self.province = normalize_text(correct_province(self.province)) + if self.city: + self.city = normalize_text(correct_city(self.city, self.province)) + super(Guilds, self).save(*args, **kwargs) + + +class Driver(BaseModel): + car_id = models.CharField(max_length=255, null=True, blank=True) + driver_name = models.CharField(max_length=255, null=True, blank=True) + owner_name = models.CharField(max_length=255, null=True, blank=True) + city = models.CharField(max_length=255, null=True, blank=True) + province = models.CharField(max_length=255, null=True, blank=True) + pelak = models.CharField(max_length=255, null=True, blank=True) + tracking_code = models.CharField(max_length=255, null=True, blank=True) + weight = models.IntegerField(null=True, blank=True) + car_type = models.CharField(max_length=255, null=True, blank=True) + expire_licence_date = models.DateField(null=True, blank=True) + health_permit = models.CharField(max_length=255, null=True, blank=True) + product = models.CharField(max_length=255, null=True, blank=True) + part_id_code = models.CharField(max_length=255, null=True, blank=True) + kill_house_name = models.CharField(max_length=255, null=True, blank=True) + + def save(self, *args, **kwargs): + if self.province: + self.province = normalize_text(correct_province(self.province)) + if self.city: + self.city = normalize_text(correct_city(self.city, self.province)) + super(Driver, self).save(*args, **kwargs) + + +class InquiryCredentials(BaseModel): + data = models.JSONField(null=True, blank=True) + numbers = models.JSONField(null=True, blank=True) + + def save(self, *args, **kwargs): + super(InquiryCredentials, self).save(*args, **kwargs) + + +class EvacuationDetail(BaseModel): # گزارشات تلفات جوجه ریزی + hatching = models.ForeignKey( + Hatching, + on_delete=models.CASCADE, + related_name="evacuation_details", + null=True, + blank=True + ) + PartIdCode = models.CharField(max_length=200, null=True, blank=True) + RequestId = models.CharField(max_length=200, null=True, blank=True) + MoReportId = models.CharField(max_length=200, null=True, blank=True) + ReportType = models.IntegerField(null=True, blank=True) + ReportTypeString = models.CharField(max_length=255, null=True, blank=True) + ReportDate = models.CharField(max_length=200, null=True, blank=True) + ReportDateShamsi = models.CharField(max_length=200, null=True, blank=True) + MoReason = models.TextField(null=True, blank=True) + MoDate = models.CharField(max_length=200, null=True, blank=True) + MoDateShamsi = models.CharField(max_length=200, null=True, blank=True) + MoStartDay = models.IntegerField(null=True, blank=True) + MoEndDay = models.IntegerField(null=True, blank=True) + MoReportSubId = models.CharField(max_length=200, null=True, blank=True) + ReportStatus = models.IntegerField(null=True, blank=True) + GoodCount = models.IntegerField(null=True, blank=True) + Message = models.TextField(null=True, blank=True) + ErrorCode = models.IntegerField(null=True, blank=True) + IsDeleted = models.BooleanField(default=False) + RegDate = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsi = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsiWithTime = models.CharField(max_length=200, null=True, blank=True) + RegDateShamsiOnlyTime = models.CharField(max_length=200, null=True, blank=True) + ExternalId = models.CharField(max_length=200, null=True, blank=True) + StringId = models.CharField(max_length=200, null=True, blank=True) + IsPersisted = models.BooleanField(default=False) + AllowInsert = models.BooleanField(default=False) + AllowUpdate = models.BooleanField(default=False) + ModalCss = models.CharField(max_length=255, null=True, blank=True) + GridContainerParametersModel = models.CharField(max_length=255, null=True, blank=True) + MenuUserAccess = models.CharField(max_length=255, null=True, blank=True) + MenuUserAccessId = models.IntegerField(null=True, blank=True) + LogTableName = models.CharField(max_length=255, null=True, blank=True) + LogTableAlias = models.CharField(max_length=255, null=True, blank=True) + PageTitle = models.CharField(max_length=255, null=True, blank=True) + + def save(self, *args, **kwargs): + def parse_dotnet_date(dotnet_string): + if not dotnet_string: + return None + try: + match = re.search(r'/Date\((\d+)\)/', str(dotnet_string)) + if match: + milliseconds = int(match.group(1)) + return datetime.datetime.utcfromtimestamp(milliseconds / 1000) + except (ValueError, TypeError): + pass + return None + + def parse_shamsi_date(shamsi_string): + if not shamsi_string: + return None + try: + parts = str(shamsi_string).split('/') + if len(parts) == 3: + year, month, day = map(int, parts) + return convert_to_miladi(year=year, month=month, day=day) + except (ValueError, TypeError): + pass + return None + + def parse_shamsi_with_time(value): + if not value: + return None + try: + text = str(value) + if '(' in text and ')' in text: + date_part, time_part = text.split('(') + date_part = date_part.strip() + time_part = time_part.replace(')', '').strip() + base_date = parse_shamsi_date(date_part) + if base_date: + hour, minute, second = map(int, time_part.split(':')) + return datetime.datetime( + year=base_date.year, + month=base_date.month, + day=base_date.day, + hour=hour, + minute=minute, + second=second + ) + except (ValueError, TypeError): + pass + return None + + def parse_time_only(value): + if not value: + return None + try: + hour, minute, second = map(int, value.split(':')) + return datetime.time(hour=hour, minute=minute, second=second) + except (ValueError, TypeError): + pass + return None + + dotnet_report = parse_dotnet_date(self.ReportDate) + if dotnet_report: + self.ReportDate = dotnet_report.strftime('%Y-%m-%d %H:%M:%S') + + dotnet_mo = parse_dotnet_date(self.MoDate) + if dotnet_mo: + self.MoDate = dotnet_mo.strftime('%Y-%m-%d %H:%M:%S') + + dotnet_reg = parse_dotnet_date(self.RegDate) + if dotnet_reg: + self.RegDate = dotnet_reg.strftime('%Y-%m-%d %H:%M:%S') + + shamsi_report = parse_shamsi_date(self.ReportDateShamsi) + if shamsi_report: + self.ReportDateShamsi = shamsi_report.strftime('%Y-%m-%d') + + shamsi_mo = parse_shamsi_date(self.MoDateShamsi) + if shamsi_mo: + self.MoDateShamsi = shamsi_mo.strftime('%Y-%m-%d') + + shamsi_reg = parse_shamsi_date(self.RegDateShamsi) + if shamsi_reg: + self.RegDateShamsi = shamsi_reg.strftime('%Y-%m-%d') + + shamsi_with_time = parse_shamsi_with_time(self.RegDateShamsiWithTime) + if shamsi_with_time: + self.RegDateShamsiWithTime = shamsi_with_time.strftime('%Y-%m-%d %H:%M:%S') + + time_only = parse_time_only(self.RegDateShamsiOnlyTime) + if time_only: + self.RegDateShamsiOnlyTime = time_only.strftime('%H:%M:%S') + + super(EvacuationDetail, self).save(*args, **kwargs) + + +class AllProductsTransport(BaseModel): # بارهای تمامی محصولات + hatching = models.ForeignKey( + Hatching, + on_delete=models.SET_NULL, + related_name="all_products_transports", + null=True, + blank=True + ) + record_id = models.CharField(max_length=255, null=True, blank=True) # id (نام تغییر یافته) + destination_prev = models.CharField(max_length=255, null=True, blank=True) # مقصد قبلی + destination_changed = models.CharField(max_length=255, null=True, blank=True) # تغییر مقصد + tracking = models.CharField(max_length=255, null=True, blank=True, unique=True) # کد رهگیری + date = models.DateField(null=True, blank=True) # تاریخ + product = models.CharField(max_length=255, null=True, blank=True) # محصول + items = models.CharField(max_length=255, null=True, blank=True) # اقلام + quantity = models.FloatField(null=True, blank=True) # مقدار + unit = models.CharField(max_length=50, null=True, blank=True) # واحد + origin_province = models.CharField(max_length=255, null=True, blank=True) # استان مبدا + origin_city = models.CharField(max_length=255, null=True, blank=True) # شهرستان مبدا + origin = models.CharField(max_length=255, null=True, blank=True) # مبدا + destination_province = models.CharField(max_length=255, null=True, blank=True) # استان مقصد + destination_city = models.CharField(max_length=255, null=True, blank=True) # شهرستان مقصد + destination = models.CharField(max_length=255, null=True, blank=True) # مقصد + jihadi_origin = models.CharField(max_length=255, null=True, blank=True) # ش جهادی مبدا + jihadi_destination = models.CharField(max_length=255, null=True, blank=True) # ش جهادی مقصد + owner = models.CharField(max_length=255, null=True, blank=True) # مالک + car_tracking_code = models.CharField(max_length=255, null=True, blank=True) # کد رهگیری خودرو + driver_name = models.CharField(max_length=255, null=True, blank=True) # نام راننده + gross_weight = models.FloatField(null=True, blank=True) # وزن پر + tare_weight = models.FloatField(null=True, blank=True) # وزن خالی + net_weight = models.FloatField(null=True, blank=True) # وزن + scale_code = models.CharField(max_length=255, null=True, blank=True) # کد باسکول + scale_name = models.CharField(max_length=255, null=True, blank=True) # نام باسکول + scale_receipt = models.CharField(max_length=255, null=True, blank=True) # قبض باسکول + unloading_date = models.DateField(null=True, blank=True) # تاریخ تخلیه + unloading = models.CharField(max_length=255, null=True, blank=True) # تخلیه + out = models.BooleanField(default=False) # Out (True/False) + + def save(self, *args, **kwargs): + # تصحیح استان/شهر مبدا + if self.origin_province: + self.origin_province = normalize_text(correct_province(self.origin_province)) + if self.origin_city: + self.origin_city = normalize_text(correct_city(self.origin_city, self.origin_province)) + + # تصحیح استان/شهر مقصد + if self.destination_province: + self.destination_province = normalize_text(correct_province(self.destination_province)) + if self.destination_city: + self.destination_city = normalize_text(correct_city(self.destination_city, self.destination_province)) + + # تنظیم out بر اساس تفاوت استان مبدا و مقصد + if self.origin_province and self.destination_province: + if self.origin_province != self.destination_province: + self.out = True + else: + self.out = False + + # تبدیل تاریخ‌ها از string به date در صورت نیاز + if isinstance(self.date, str): + try: + self.date = datetime.datetime.strptime(self.date, '%Y-%m-%d').date() + except ValueError: + try: + self.date = datetime.datetime.strptime(self.date, '%Y/%m/%d').date() + except ValueError: + self.date = None + + if isinstance(self.unloading_date, str): + try: + self.unloading_date = datetime.datetime.strptime(self.unloading_date, '%Y-%m-%d').date() + except ValueError: + try: + self.unloading_date = datetime.datetime.strptime(self.unloading_date, '%Y/%m/%d').date() + except ValueError: + self.unloading_date = None + + super(AllProductsTransport, self).save(*args, **kwargs) + + +class RasadyarAppInfo(BaseModel): + info = models.JSONField(null=True, blank=True) + file = models.CharField(max_length=700, null=True, blank=True) + + def save(self, *args, **kwargs): + super(RasadyarAppInfo, self).save(*args, **kwargs) + + diff --git a/app/scripts.py b/app/scripts.py new file mode 100644 index 0000000..f8f04a2 --- /dev/null +++ b/app/scripts.py @@ -0,0 +1,24 @@ +from rest_framework import status +from rest_framework.permissions import AllowAny +from rest_framework.response import Response + +from app.models import PoultryHatching, Poultry +from django.db import transaction +from django.views.decorators.csrf import csrf_exempt +from rest_framework.decorators import api_view, permission_classes + + +@api_view(['POST']) +@permission_classes([AllowAny]) +@csrf_exempt +def update_poultry_city_province(request): + hatchings = PoultryHatching.objects.select_related('poultry').only('poultry', 'LocationNameCity', + 'LocationNameProvince').filter( + poultry__isnull=False).order_by('id') + for hatching in hatchings: + hatching.poultry.LocationNameProvince = hatching.LocationNameProvince + hatching.poultry.LocationNameCity = hatching.LocationNameCity + hatching.poultry.save() + print(hatching.id) + return Response({'message': 'done'}, status=status.HTTP_200_OK) + # return Response({'message': len(hatchings)}, status=status.HTTP_200_OK) diff --git a/app/serializers.py b/app/serializers.py new file mode 100644 index 0000000..59d78e6 --- /dev/null +++ b/app/serializers.py @@ -0,0 +1,653 @@ +import datetime + +from django.db.models import Sum, Avg, Count, Q +from rest_framework import serializers + +from app.models import Poultry, PoultryHatching, TransportingChickenDetail, Hatching, TransportingDetail, KillHouse, \ + ApkInfo, TransportCarcassDetail, Driver, Guilds, InquiryCredentials, AllProductsTransport, EvacuationDetail, \ + RasadyarAppInfo +from authentication.models import Province, City +from helpers import build_calculation + + +class PoultrySerializer(serializers.ModelSerializer): + hatching = serializers.SerializerMethodField('get_hatching') + + class Meta: + model = Poultry + fields = ['FirstName', 'LastName', 'Mobile', 'UnitName', 'EpidemiologicCode', 'SystemCode', 'TrackingCode', + 'UnitIsActiveDescription', 'RegDateShamsi', 'LocationNameProvince', 'LocationNameCity', 'hatching'] + + def get_hatching(self, instance): + hatching = PoultryHatching.objects.filter(poultry=instance) + total_amount = build_calculation(queryset=hatching, column_name='BaseHatchingCount', aggregate_func=Sum) + EvacuationCount = build_calculation(queryset=hatching, column_name='EvacuationCount', aggregate_func=Sum) + LeftOver = build_calculation(queryset=hatching, column_name='LeftOver', aggregate_func=Sum) + + return { + "totalAmount": total_amount, + "losses": EvacuationCount, + "LeftOver": LeftOver, + } + + +# class TransportingForHatchingSerializer(serializers.ModelSerializer): +# class Meta: +# model = TransportingChickenDetail +# fields = '__all__' + + +class PoultryHatchingSerializer(serializers.ModelSerializer): + # bars = serializers.SerializerMethodField('get_bars') + age = serializers.SerializerMethodField('get_age') + + class Meta: + model = PoultryHatching + fields = '__all__' + + # def get_bars(self, obj): + # transports = TransportingChickenDetail.objects.filter(trash=False, hatching=obj) + # serializer = TransportingForHatchingSerializer(transports, many=True) + # return serializer.data + + def get_age(self, obj): + age = (datetime.datetime.now().date() - obj.Date.date()).days + 1 + return age + + +class HatchingsSerializer(serializers.ModelSerializer): + class Meta: + model = Hatching + fields = '__all__' + + +class TransportingChickenDetailSerializer(serializers.ModelSerializer): + hatching = PoultryHatchingSerializer(read_only=True) + killing_age = serializers.SerializerMethodField('get_killing_age') + + class Meta: + model = TransportingChickenDetail + fields = '__all__' + + def get_killing_age(self, obj): + age = (obj.reside_date.date() - obj.hatching.Date.date()).days + 1 + return age + + +class HatchingSerializer(serializers.ModelSerializer): + class Meta: + model = PoultryHatching + fields = '__all__' + + +class TransportingSerializer(serializers.ModelSerializer): + class Meta: + model = TransportingDetail + fields = '__all__' + + +class HatchingCalculationSerializer(serializers.ModelSerializer): + class Meta: + model = PoultryHatching + fields = ['EvacuationCount', 'LocationNameCity', 'LocationNameProvince', 'poultry'] + + +class PoultryInfoSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + + class Meta: + model = Poultry + fields = ['key', 'FirstName', 'LastName', 'Mobile', 'EpidemiologicCode', 'UnitId', 'SystemCode', 'UnitName', + 'UnitIsActive', + 'RegDateShamsi', 'info', 'LocationNameCity', 'LocationNameProvince', 'UserIsActiveDescription', + 'Province', 'City'] + + def get_info(self, obj): + hatchings = Hatching.objects.filter(poultry=obj, trash=False) + total_hatching = hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 0 + total_leftover = hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0 + total_evacuation = hatchings.aggregate(total=Sum('Evacuation'))['total'] or 0 + transports = TransportingDetail.objects.filter(hatching__in=hatchings, trash=False) + total_killing = transports.aggregate(total=Sum('GoodAmount'))['total'] or 0 + total_left_over_percent = round((total_leftover / total_hatching) * 100, 2) if total_hatching > 0 else 0 + total_evacuation_percent = round((total_evacuation / total_hatching) * 100, 2) if total_hatching > 0 else 0 + total_killing_percent = round((total_killing / total_hatching) * 100, 2) if total_hatching > 0 else 0 + + return { + "count_hatching": len(hatchings), + "total_hatching": total_hatching, + "total_leftover": total_leftover, + "total_evacuation": total_evacuation, + "total_left_over_percent": total_left_over_percent, + "total_evacuation_percent": total_evacuation_percent, + "total_killing_percent": total_killing_percent, + "total_killing": total_killing, + "cars_count": len(transports), + "total_cars": total_killing, + "capacity": hatchings.last().CapacityFemale if hatchings else 0, + } + + +class PoultryForHatchingDetailSerializer(serializers.ModelSerializer): + class Meta: + model = Poultry + fields = ['City', 'Province', 'FirstName', 'LastName', 'UnitName'] + + +class HatchingDetailSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + poultry = PoultryForHatchingDetailSerializer(read_only=True) + + class Meta: + model = Hatching + fields = ['Date', 'Age', 'KillingAve', 'info', 'CertId', + 'RequestCode', 'ChickCountSum', 'Period', 'CapacityFemale', 'LeftOver', 'Evacuation', + 'poultry', 'PedigreeName'] + + def get_info(self, obj): + capacity = obj.CapacityFemale if obj.CapacityFemale else 0 + transports = TransportingDetail.objects.filter(hatching=obj, trash=False) + average_slaughter_age = transports.aggregate(avg_age=Avg('Age'))['avg_age'] or 0 + load_volume = transports.aggregate(total=Sum('GoodAmount'))['total'] or 0 + percent_hatching_license = (capacity / obj.ChickCountSum) * 100 + + return { + "average_slaughter_age": average_slaughter_age, + "load_volume": load_volume, + "number_loads": len(transports), + "percent_hatching_license": round(percent_hatching_license, 2) + } + + +class HatchingForUpdateSerializer(serializers.ModelSerializer): + poultry = PoultryInfoSerializer(read_only=True) + EvacuationDetail = serializers.SerializerMethodField() + + class Meta: + model = Hatching + fields = '__all__' + + def get_EvacuationDetail(self, obj): + queryset = EvacuationDetail.objects.filter(hatching=obj, trash=False) + return EvacuationDetailSerializer(queryset, many=True).data + + +class PoultryDetailSerializerForTransport(serializers.ModelSerializer): + class Meta: + model = Poultry + fields = ['UnitId', 'PartIdCode', 'Province', 'City', 'UnitName', 'Mobile'] + + +class HatchingDetailSerializerForTransport(serializers.ModelSerializer): + poultry = PoultryDetailSerializerForTransport(read_only=True) + + class Meta: + model = Hatching + fields = ['PartIdCode', 'poultry', 'RequestCode', 'PedigreeName'] + + +class TransportingDetailSerializer(serializers.ModelSerializer): + hatching = HatchingDetailSerializerForTransport(read_only=True) + location_kill_house = serializers.SerializerMethodField('get_location_kill_house') + location_poultry = serializers.SerializerMethodField('get_location_poultry') + + class Meta: + model = TransportingDetail + fields = ['TrackingCode', 'hatching', 'ResideDatePersian', 'DesUnitName', 'DesPartIdCode', 'Province', 'City', + 'GoodAmount', + 'TrackingStatusDescription', 'SourceUnitName', 'Age', 'PedigreeName', 'Date', 'Out', + 'location_kill_house', + 'location_poultry'] + + def get_location_kill_house(self, obj): + resul = {} + province_kill_house = Province.objects.filter(name=obj.Province).first() + city_kill_house = City.objects.filter(name=obj.City).first() + if province_kill_house: + resul.update({ + "provinceLat": province_kill_house.Lat, + "provinceLng": province_kill_house.Lng + }) + if city_kill_house: + resul.update({ + "cityLat": city_kill_house.Lat, + "cityLng": city_kill_house.Lng + }) + return resul + + def get_location_poultry(self, obj): + resul = {} + if obj.hatching: + province_kill_house = Province.objects.filter(name=obj.hatching.ProvinceName).first() + city_kill_house = City.objects.filter(name=obj.hatching.CityName).first() + if province_kill_house: + resul.update({ + "provinceLat": province_kill_house.Lat, + "provinceLng": province_kill_house.Lng + }) + if city_kill_house: + resul.update({ + "cityLat": city_kill_house.Lat, + "cityLng": city_kill_house.Lng + }) + return resul + + +class KillHouseSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + + class Meta: + model = KillHouse + fields = '__all__' + + def get_info(self, obj): + # Use pre-computed cache if available (optimization to avoid N+1 queries) + info_cache = self.context.get('info_cache') + if info_cache and obj.PartIdCode in info_cache: + return info_cache[obj.PartIdCode] + + # Fallback to original query-based approach if cache not available + request = self.context.get('request') + date1 = request.GET.get('date1') or None + date2 = request.GET.get('date2') or None + + bars = TransportingDetail.objects.filter(DesPartIdCode=obj.PartIdCode, trash=False).only('GoodAmount', 'Out', 'Date') + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(Date__date__gte=date1, Date__date__lte=date2) + + aggregation = bars.aggregate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id') + ) + + all_products = AllProductsTransport.objects.filter( + jihadi_origin=obj.PartIdCode, + trash=False + ).only('quantity', 'out', 'date', 'unloading_date') + + if date1: + all_products = all_products.filter( + Q( + date__gte=date1, + date__lte=date2, + date__isnull=False + ) | + Q( + unloading_date__gte=date1, + unloading_date__lte=date2, + date__isnull=True + ) + ) + + all_products_aggregation = all_products.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id') + ) + + aggregation['total'] = (aggregation.get('total') or 0) + (all_products_aggregation.get('total') or 0) + aggregation['input_total'] = (aggregation.get('input_total') or 0) + (all_products_aggregation.get('input_total') or 0) + aggregation['output_total'] = (aggregation.get('output_total') or 0) + (all_products_aggregation.get('output_total') or 0) + aggregation['input_count'] = (aggregation.get('input_count') or 0) + (all_products_aggregation.get('input_count') or 0) + aggregation['output_count'] = (aggregation.get('output_count') or 0) + (all_products_aggregation.get('output_count') or 0) + aggregation['total_count'] = (aggregation.get('total_count') or 0) + (all_products_aggregation.get('total_count') or 0) + + total_count = aggregation['total_count'] or 0 + total_bars_quantity = aggregation['total'] or 0 + total_input_bars_quantity = aggregation['input_total'] or 0 + total_output_bars_quantity = aggregation['output_total'] or 0 + input_bars_count = aggregation['input_count'] or 0 + output_bars_count = aggregation['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 + + return { + "bars": total_count, + "total_bars_quantity": total_bars_quantity, + "input_bars": input_bars_count, + "total_input_bars_quantity": total_input_bars_quantity, + "total_input_bars_percent": total_input_bars_percent, + "output_bars": output_bars_count, + "total_output_bars_quantity": total_output_bars_quantity, + "total_output_bars_percent": total_output_bars_percent, + } + + +class TransportingDetailForUpdateSerializer(serializers.ModelSerializer): + hatching = HatchingDetailSerializerForTransport(read_only=True) + + class Meta: + model = TransportingDetail + fields = '__all__' + + +class HatchingAnalysisSerializer(serializers.ModelSerializer): + class Meta: + model = Hatching + fields = ['CityName', 'ProvinceName', 'PedigreeName'] + + +class HatchingAnalysisSerializerTwo(serializers.ModelSerializer): + class Meta: + model = Hatching + fields = ['CityName', 'ProvinceName'] + + +class TransportingReportDashboard(serializers.ModelSerializer): + class Meta: + model = TransportingDetail + fields = ['age', 'Province', 'City'] + + +class TransportingForClearanceCodeSerializer(serializers.ModelSerializer): + hatching = HatchingDetailSerializerForTransport(read_only=True) + + class Meta: + model = TransportingDetail + fields = '__all__' + + +class ApkInfoSerializer(serializers.ModelSerializer): + class Meta: + model = ApkInfo + fields = ['key', 'info', 'download_link'] + + +class TransportCarcassDetailSerializer(serializers.ModelSerializer): + class Meta: + model = TransportCarcassDetail + fields = '__all__' + + +class DriverSerializer(serializers.ModelSerializer): + class Meta: + model = Driver + fields = '__all__' + + +class KillHouseForTransportCarcassSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + + class Meta: + model = KillHouse + fields = '__all__' + + def get_info(self, obj): + bars_dict = self.context.get('bars_dict', {}) + buy_dict = self.context.get('buy_dict', {}) + + bars_data = bars_dict.get(obj.PartIdCode, {}) + buy_data = buy_dict.get(obj.PartIdCode, {}) + + total_count = bars_data.get('total_count', 0) or 0 + total_bars_quantity = bars_data.get('total', 0) or 0 + total_input_bars_quantity = bars_data.get('input_total', 0) or 0 + total_output_bars_quantity = bars_data.get('output_total', 0) or 0 + input_bars_count = bars_data.get('input_count', 0) or 0 + output_bars_count = bars_data.get('output_count', 0) or 0 + + buy_input_total = buy_data.get('input_total', 0) or 0 + buy_output_total = buy_data.get('output_total', 0) or 0 + buy_input_count = buy_data.get('input_count', 0) or 0 + buy_output_count = buy_data.get('output_count', 0) or 0 + + if total_count > 0 and (total_input_bars_quantity + total_output_bars_quantity) > 0: + total_input_bars_percent = round( + (total_input_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + total_output_bars_percent = round( + (total_output_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return { + "role": 'کشتارگاه', + "bars": int(total_count), + "total_bars_wight": int(total_bars_quantity), + "input_bars": int(input_bars_count), + "total_input_bars_wight": int(total_input_bars_quantity), + "total_input_buy_bars_wight": int(((buy_input_total) * 2.5) * 0.75), + "total_input_bars_percent": total_input_bars_percent, + "output_bars": int(output_bars_count), + "total_output_bars_wight": int(total_output_bars_quantity), + "total_output_buy_bars_wight": int(((buy_output_total) * 2.5) * 0.75), + "total_output_bars_percent": total_output_bars_percent, + "total_ware_house": int(((buy_input_total * 2.5) * 0.75) + ((buy_output_total * 2.5) * 0.75)), + "total_input_buy_bars_count": int(buy_input_count), + "total_output_buy_bars_count": int(buy_output_count), + } + + +class StewardForTransportCarcassSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField() + + class Meta: + model = Guilds + fields = '__all__' + + def get_info(self, obj): + bars_dict = self.context.get('bars_dict', {}) + row = bars_dict.get(obj.jihadi_code, {}) + + total_count = row.get('total_count', 0) or 0 + total_bars_quantity = row.get('total', 0) or 0 + total_input_bars_quantity = row.get('input_total', 0) or 0 + total_output_bars_quantity = row.get('output_total', 0) or 0 + input_bars_count = row.get('input_count', 0) or 0 + output_bars_count = row.get('output_count', 0) or 0 + total_input_buy_bars_wight = row.get('total_input_buy_bars_wight', 0) or 0 + total_output_buy_bars_wight = row.get('total_output_buy_bars_wight', 0) or 0 + total_input_buy_bars_count = row.get('total_input_buy_bars_count', 0) or 0 + total_output_buy_bars_count = row.get('total_output_buy_bars_count', 0) or 0 + total_ware_house = total_input_buy_bars_wight + total_output_buy_bars_wight + + if total_count > 0: + total_input_bars_percent = round( + (total_input_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + total_output_bars_percent = round( + (total_output_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return { + "role": 'مباشر', + "bars": int(total_count), + "total_bars_wight": int(total_bars_quantity), + "input_bars": int(input_bars_count), + "total_input_bars_wight": int(total_input_bars_quantity), + "total_input_buy_bars_wight": int(total_input_buy_bars_wight), + "total_input_bars_percent": total_input_bars_percent, + "output_bars": int(output_bars_count), + "total_output_bars_wight": int(total_output_bars_quantity), + "total_output_buy_bars_wight": int(total_output_buy_bars_wight), + "total_output_bars_percent": total_output_bars_percent, + "total_ware_house": int(total_ware_house), + "total_input_buy_bars_count": int(total_input_buy_bars_count), + "total_output_buy_bars_count": int(total_output_buy_bars_count), + } + + +class GuildsForTransportCarcassSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + + class Meta: + model = Guilds + fields = '__all__' + + def get_info(self, obj): + bars_dict = self.context.get('bars_dict', {}) + data = bars_dict.get(obj.jihadi_code, None) + + if not data: + return { + "role": 'صنف', + "total_input_buy_bars_wight": 0, + "total_output_buy_bars_wight": 0, + "total_ware_house": 0, + "total_input_buy_bars_percent": 0, + "total_output_buy_bars_percent": 0, + "total_input_buy_bars_count": 0, + "total_output_buy_bars_count": 0, + } + + total_input = data['total_input_buy_bars_wight'] or 0 + total_output = data['total_output_buy_bars_wight'] or 0 + total_wh = data['total_ware_house'] or 0 + total_count = data['total_count'] or 0 + + if total_count > 0 and total_wh > 0: + total_input_percent = round((total_input / total_wh) * 100, 1) + total_output_percent = round((total_output / total_wh) * 100, 1) + else: + total_input_percent = 0 + total_output_percent = 0 + + return { + "role": 'صنف', + "total_input_buy_bars_wight": int(total_input), + "total_output_buy_bars_wight": int(total_output), + "total_ware_house": int(total_wh), + "total_input_buy_bars_percent": total_input_percent, + "total_output_buy_bars_percent": total_output_percent, + "total_input_buy_bars_count": int(data['total_count_input_buy'] or 0), + "total_output_buy_bars_count": int(data['total_count_output_buy'] or 0), + } + + +class KillHouseForTransportCarcassForRassadyaarSerializer(serializers.ModelSerializer): + info = serializers.SerializerMethodField('get_info') + + class Meta: + model = KillHouse + fields = '__all__' + + def get_info(self, obj): + bars_dict = self.context.get('bars_dict', {}) + buy_dict = self.context.get('buy_dict', {}) + + bars_data = bars_dict.get(obj.PartIdCode, {}) + buy_data = buy_dict.get(obj.PartIdCode, {}) + + total_count = bars_data.get('total_count', 0) or 0 + total_bars_quantity = bars_data.get('total', 0) or 0 + total_input_bars_quantity = bars_data.get('input_total', 0) or 0 + total_output_bars_quantity = bars_data.get('output_total', 0) or 0 + input_bars_count = bars_data.get('input_count', 0) or 0 + output_bars_count = bars_data.get('output_count', 0) or 0 + + buy_input_total = buy_data.get('input_total', 0) or 0 + buy_output_total = buy_data.get('output_total', 0) or 0 + buy_input_count = buy_data.get('input_count', 0) or 0 + buy_output_count = buy_data.get('output_count', 0) or 0 + + if total_count > 0 and (total_input_bars_quantity + total_output_bars_quantity) > 0: + total_input_bars_percent = round( + (total_input_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + total_output_bars_percent = round( + (total_output_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1 + ) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return { + "bars": int(total_count), + "total_bars_wight": int(total_bars_quantity), + "input_bars": int(input_bars_count), + "total_input_bars_wight": int(total_input_bars_quantity), + "total_input_buy_bars_wight": int(buy_input_total), + "total_input_bars_percent": total_input_bars_percent, + "output_bars": int(output_bars_count), + "total_output_bars_wight": int(total_output_bars_quantity), + "total_output_buy_bars_wight": int(buy_output_total), + "total_output_bars_percent": total_output_bars_percent, + "total_ware_house": int(buy_input_total) + int(buy_output_total), + "total_input_buy_bars_count": int(buy_input_count), + "total_output_buy_bars_count": int(buy_output_count), + } + + +class InquiryCredentialsSerializer(serializers.ModelSerializer): + class Meta: + model = InquiryCredentials + fields = '__all__' + + +class AllProductsTransportSerializer(serializers.ModelSerializer): + hatching = HatchingDetailSerializerForTransport(read_only=True) + + class Meta: + model = AllProductsTransport + fields = '__all__' + + +class EvacuationDetailSerializer(serializers.ModelSerializer): + class Meta: + model = EvacuationDetail + fields = '__all__' + + +class RasadyarAppInfoSerializer(serializers.ModelSerializer): + class Meta: + model = RasadyarAppInfo + fields = '__all__' + +class AllProductsTransportCustomSerializer(serializers.ModelSerializer): + location_origin = serializers.SerializerMethodField('get_location_origin') + location_destination = serializers.SerializerMethodField('get_location_destination') + + class Meta: + model = AllProductsTransport + fields = '__all__' + + def get_location_origin(self, obj): + resul = {} + province_origin = Province.objects.filter(name=obj.origin_province).first() + city_origin = City.objects.filter(name=obj.origin_city).first() + if province_origin: + resul.update({ + "provinceLat": province_origin.Lat, + "provinceLng": province_origin.Lng + }) + if city_origin: + resul.update({ + "cityLat": city_origin.Lat, + "cityLng": city_origin.Lng + }) + return resul + + def get_location_destination(self, obj): + resul = {} + province_destination = Province.objects.filter(name=obj.destination_province).first() + city_destination = City.objects.filter(name=obj.destination_city).first() + if province_destination: + resul.update({ + "provinceLat": province_destination.Lat, + "provinceLng": province_destination.Lng + }) + if city_destination: + resul.update({ + "cityLat": city_destination.Lat, + "cityLng": city_destination.Lng + }) + return resul diff --git a/app/tests.py b/app/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/app/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/app/urls.py b/app/urls.py new file mode 100644 index 0000000..137bbd6 --- /dev/null +++ b/app/urls.py @@ -0,0 +1,239 @@ +from django.urls import include, path +from rest_framework.routers import DefaultRouter +from app import views as app_views +from app.excel_processing import transporting_detail_excel, total_killhouse_excel, hatching_excel, all_hatching_excel, \ + all_send_different_bar_excel, transport_carcass_detail_excel, guilds_transport_carcass_detail_excel +from app.helper import get_bar_info, test_city, api_get_hatching_permit_code +from app.scripts import update_poultry_city_province +from app.views import get_transport_to_kill, add_kill_house, update_hatching, get_breeds, dashboard_total_kill_house, \ + send_different_bar, send_different_bar_with_licence_number, all_province_detail_for_map, \ + 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_all_products_transport_dashboard_by_code, get_all_products_transport_products_by_code, \ + get_all_products_transport_provinces_by_code + +router = DefaultRouter() + +router.register( + r'poultry', + app_views.PoultryViewSet, + basename="poultry" +) + +router.register( + r'poultry-dashboard', + app_views.PoultryDashboardViewSet, + basename="poultry-dashboard" +) +router.register( + r'hatching', + app_views.PoultryHatchingViewSet, + basename="hatching" +) + +router.register( + r'hatchings-dashboard', + app_views.HatchingDashboardViewSet, + basename="hatchings-dashboard" +) + +router.register( + r'hatchings', + app_views.HatchingsViewSet, + basename="hatchings" +) + +router.register( + r'hatchings-custom', + app_views.HatchingsCustomViewSet, + basename="hatchings-custom" +) + +router.register( + r'hatching-pedigreename', + app_views.PoultryHatchingForUpdatePedigreeNameViewSet, + basename="hatching-pedigreename" +) + +router.register( + r'transporting', + app_views.TransportingChickenDetailViewSet, + basename="transporting" +) + +router.register( + r'transporting-dashboard', + app_views.TransportingDashboardViewSet, + basename="transporting-dashboard" +) + +router.register( + r'transporting-detail', + app_views.TransportingDetailViewSet, + basename="transporting-detail" +) + +router.register( + r'transporting-detail-custom', + app_views.TransportingDetailCustomViewSet, + basename="transporting-detail-custom" +) + +router.register( + r'hatching-dashboard', + app_views.PoultryHatchingDashboardViewSet, + basename="hatching-dashboard" +) + +router.register( + r'hatching-filtering', + app_views.HatchingViewSet, + basename="hatching-filtering" +) + +router.register( + r'hatching-calculating', + app_views.HatchingCalculationsViewSet, + basename="hatching-calculating" +) + +router.register( + r'poultry-info', + app_views.PoultryInfoViewSet, + basename="poultry-info" +) + +router.register( + r'total-killhouse', + app_views.TotalKillHousesViewSet, + basename="total-killhouse" +) + +router.register( + r'hatching-analysis-pedigree', + app_views.HatchingAnalysisPedigreeViewSet, + basename="hatching-analysis-pedigree" +) + +router.register( + r'hatching-analysis-province', + app_views.HatchingAnalysisProvinceView, + basename="hatching-analysis-province" +) + +router.register( + r'hatchings-analysis-overview', + app_views.HatchingAnalysisOverviewViewSet, + basename="hatchings-analysis-overview" +) + +router.register( + r'transporting-report-dashboard', + app_views.TransportingReportDashboardViewSet, + basename="transporting-report-dashboard" +) + +router.register( + r'transporting-analysis-dashboard', + app_views.TransportingAnalysisViewSet, + basename="transporting-analysis-dashboard" +) +router.register( + r'api_send_different_bar', + app_views.ApiSendDifferentBar, + basename="api_send_different_bar" +) +router.register( + r'api_send_different_bar-from-hatching', + app_views.ApiSendDifferentBarFromHatching, + basename="api_send_different_bar-from-hatching" +) + +router.register( + r'apk-info', + app_views.ApkInfoViewSet, + basename="apk-info" +) +router.register( + r'transport-carcass-detail', + app_views.TransportCarcassDetailViewSet, + basename="transport-carcass-detail" +) +router.register( + r'driver', + app_views.DriveViewSet, + basename="driver" +) +router.register( + r'guilds-transport-carcass-detail', + app_views.GuildsTransportCarcassViewSet, + basename="guilds-transport-carcass-detail" +) + +router.register( + r'inquiry_credentials', + app_views.InquiryCredentialsViewSet, + basename="inquiry_credentials" +) + +router.register( + r'all-products-transport', + app_views.AllProductsTransportViewSet, + basename="all-products-transport" +) + +router.register( + r'evacuation-detail', + app_views.EvacuationDetailViewSet, + basename="evacuation-detail" +) + +router.register( + r'rasadyar-app-info', + app_views.RasadyarAppInfoViewSet, + basename="rasadyar-app-info" +) + + + +urlpatterns = [ + path('', include(router.urls)), + path('get-transport-to-kill/', get_transport_to_kill), + path('add_kill_house/', add_kill_house), + path('update_hatching/', update_hatching), + path('get_breeds/', get_breeds), + path('get_bar_info/', get_bar_info), + path('transporting_detail_excel/', transporting_detail_excel), + path('total_killhouse_excel/', total_killhouse_excel), + path('hatching_excel/', hatching_excel), + path('all_hatching_excel/', all_hatching_excel), + path('dashboard_total_kill_house/', dashboard_total_kill_house), + path('test_city/', test_city), + path('send_different_bar/', send_different_bar), + path('all_send_different_bar_excel/', all_send_different_bar_excel), + path('send_different_bar_with_licence_number/', send_different_bar_with_licence_number), + path('all_province_detail_for_map/', all_province_detail_for_map), + path('dashboard_province_detail_for_map/', dashboard_province_detail_for_map), + path('transport-carcass-dashboard/', TransportCarcassDashboardView.as_view()), + path('guilds-transport-carcass-dashboard/', GuildsTransportCarcassDashboardView.as_view()), + path('all-products-transport-dashboard/', AllProductsTransportDashboardView.as_view()), + path('all-products-transport-products/', AllProductsTransportProductsListView.as_view()), + path('update_product_date/', update_product_date), + path('transport-carcass-detail-excel/', transport_carcass_detail_excel), + path('guilds-transport-carcass-detail-excel/', guilds_transport_carcass_detail_excel), + path('send_transport_carcass_detail_for_rasadyaar/', send_transport_carcass_detail_for_rasadyaar), + path('delete_free_bar_from_rasadyaar/', delete_free_bar_from_rasadyaar), + path('fix_number/', fix_number), + path('get-evacuation-detail-by-request-code/', get_evacuation_detail_by_request_code), + path('get-evacuation-details-by-request-codes/', get_evacuation_details_by_request_codes), + path('api/get-hatching-permit-code/', api_get_hatching_permit_code), + path('evacuation-report-type-summary/', evacuation_report_type_summary), + path('get-all-products-transport-by-code/', get_all_products_transport_by_code), + path('get-all-products-transport-dashboard-by-code/', get_all_products_transport_dashboard_by_code), + 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), + + +] diff --git a/app/views.py b/app/views.py new file mode 100644 index 0000000..32b5df7 --- /dev/null +++ b/app/views.py @@ -0,0 +1,5891 @@ +import datetime +import json +import random +import string +from this import d +import uuid +from collections import defaultdict +from io import BytesIO + +import boto3 +import jdatetime +import openpyxl +import requests +from bs4 import BeautifulSoup +from django.db.models import Sum, Count, Avg, Q, Min, Max, Prefetch, F +from django.http import HttpResponse +from django.views.decorators.csrf import csrf_exempt +from rest_framework import viewsets, status +from rest_framework.decorators import api_view, permission_classes +from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from rest_framework.views import APIView + +from app.cityandprovince import iranprovince, irancity +from app.filtersets import PoultryFilterSet, PoultryHatchingFilterSet, TransportingChickenDetailFilterSet, \ + PoultryInfoFilterSet, HatchingCalculationsFilterSet, HatchingsFilterSet, TransportingDetailFilterSet, \ + KillHouseFilterSet, TransportingDetailCustomFilterSet, CustomHatchingsFilterSet, TransportCarcassDetailFilterSet, \ + DriverFilterSet, GuildsFilterSet, AllProductsTransportFilterSet +from app.helper import SSLAdapter, get_hatching_permit_code +from app.models import Poultry, PoultryHatching, TransportingChickenDetail, Hatching, TransportingDetail, KillHouse, \ + ApkInfo, TransportCarcassDetail, Guilds, Driver, InquiryCredentials, AllProductsTransport, EvacuationDetail, \ + RasadyarAppInfo +from app.serializers import PoultrySerializer, PoultryHatchingSerializer, TransportingChickenDetailSerializer, \ + HatchingSerializer, HatchingCalculationSerializer, PoultryInfoSerializer, HatchingsSerializer, \ + HatchingDetailSerializer, HatchingForUpdateSerializer, TransportingSerializer, TransportingDetailSerializer, \ + KillHouseSerializer, HatchingAnalysisSerializer, HatchingAnalysisSerializerTwo, TransportingReportDashboard, \ + TransportingForClearanceCodeSerializer, ApkInfoSerializer, TransportCarcassDetailSerializer, DriverSerializer, \ + KillHouseForTransportCarcassSerializer, StewardForTransportCarcassSerializer, \ + GuildsForTransportCarcassSerializer, KillHouseForTransportCarcassForRassadyaarSerializer, \ + TransportingDetailForUpdateSerializer, InquiryCredentialsSerializer, AllProductsTransportSerializer, \ + EvacuationDetailSerializer, RasadyarAppInfoSerializer, AllProductsTransportCustomSerializer +from authentication.models import Province +from helpers import CustomPagination, build_query, build_calculation, convert_to_miladi + + +class PoultryViewSet(viewsets.ModelViewSet): + queryset = Poultry.objects.all() + serializer_class = PoultrySerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = PoultryFilterSet + + def create(self, request, *args, **kwargs): + data = request.data.get('Data', []) + + for poultry in data: + registered_poultry = Poultry.objects.filter(UnitId=poultry['UnitId']).first() + if registered_poultry: + for key, value in poultry.items(): + setattr(registered_poultry, key, value) + registered_poultry.save() + else: + Poultry.objects.create(**poultry) + + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + def list(self, request, *args, **kwargs): + poultry = Poultry.objects.filter(trash=False) + value = request.GET.get('value') + if value: + poultry = poultry.filter( + build_query(self.filterset_class.Meta.fields, value) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(poultry) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(poultry, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +# class PoultryDashboardViewSet(viewsets.ModelViewSet): +# queryset = Poultry.objects.filter(trash=False).only('id', 'Province', 'City').order_by('id') +# serializer_class = PoultrySerializer +# permission_classes = [AllowAny] +# filterset_class = PoultryInfoFilterSet +# +# def list(self, request, *args, **kwargs): +# poultries = self.queryset.filter(Province__isnull=False) +# hatchings = Hatching.objects.filter(trash=False).order_by('id') +# search = request.GET.get('search') +# province = request.GET.get('province') +# city = request.GET.get('city') +# if province: +# poultries = poultries.filter(Province__icontains=province) +# hatchings = Hatching.objects.filter(ProvinceName=province, trash=False).only('CityName', +# 'ProvinceName').order_by('id') +# +# if city: +# poultries = poultries.filter(City__icontains=city) +# hatchings = Hatching.objects.filter(CityName=city, trash=False).order_by('id') +# +# if search: +# if search != 'undefined' and search.strip(): +# poultries = poultries.filter( +# build_query(self.filterset_class.Meta.fields, search) +# ) +# province = len(set(poultries.values_list('LocationIdProvince', flat=True))) +# city = len(set(poultries.values_list('LocationIdCity', flat=True))) +# active_hatchings = hatchings.filter(Age__lte=70, trash=False).order_by('id') +# bars = TransportingDetail.objects.filter(hatching__in=hatchings, trash=False).order_by('id') +# active_hatchings_bars = bars.filter(hatching__in=active_hatchings, trash=False).order_by('id') +# total_active_hatching_quantity = active_hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 0 +# total_active_hatching_evacuation = active_hatchings.aggregate(total=Sum('Evacuation'))['total'] or 0 +# total_active_hatching_killing_quantity = active_hatchings_bars.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# total_active_hatching_left_over = active_hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0 +# total_hatching_quantity = hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 0 +# total_hatching_evacuation = hatchings.aggregate(total=Sum('Evacuation'))['total'] or 0 +# total_hatching_killing_quantity = bars.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# total_hatching_left_over = hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0 +# +# result = { +# "poultry_count": poultries.count(), +# "total_hatching_count": hatchings.count(), +# "total_hatching_quantity": total_hatching_quantity, +# "total_hatching_evacuation": total_hatching_evacuation, +# "total_hatching_evacuation_percent": round((total_hatching_evacuation / total_hatching_quantity) * 100, 2), +# "total_hatching_killing_quantity": total_hatching_killing_quantity, +# "total_hatching_killing_quantity_percent": round( +# (total_hatching_killing_quantity / total_hatching_quantity) * 100, 2), +# "total_hatching_left_over": total_hatching_left_over, +# "total_hatching_left_over_percent": round( +# (total_hatching_left_over / total_hatching_quantity) * 100, 2), +# "total_hatching_killing_age": bars.aggregate(avg_age=Avg('Age'))['avg_age'] or 0, +# "province_count": province, +# "city_count": city, +# "total_active_hatching_count": active_hatchings.count(), +# "total_active_hatching_quantity": total_active_hatching_quantity, +# "total_active_hatching_evacuation": total_active_hatching_evacuation, +# "total_active_hatching_evacuation_percent": round( +# (total_active_hatching_evacuation / total_active_hatching_quantity) * 100, 2), +# "total_active_hatching_bars": active_hatchings_bars.count(), +# "total_active_hatching_killing_quantity": total_active_hatching_killing_quantity, +# "total_active_hatching_killing_quantity_percent": round( +# (total_active_hatching_killing_quantity / total_active_hatching_quantity) * 100, 2), +# "total_active_hatching_killing_age": active_hatchings_bars.aggregate(avg_age=Avg('Age'))['avg_age'] or 0, +# "total_active_hatching_left_over": active_hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0, +# "total_active_hatching_left_over_percent": round( +# (total_active_hatching_left_over / total_active_hatching_quantity) * 100, 2), +# # "hatching_killing_persent": active_hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0, +# +# } +# return Response(result, status=status.HTTP_200_OK) + + +class PoultryDashboardViewSet(viewsets.ModelViewSet): + queryset = Poultry.objects.filter(trash=False).only( + 'id', 'Province', 'City', 'LocationIdProvince', 'LocationIdCity' + ).order_by('id') + + serializer_class = PoultrySerializer + permission_classes = [AllowAny] + filterset_class = PoultryInfoFilterSet + + def _optimized_db_hits(self, request): + + province = request.GET.get('province') + city = request.GET.get('city') + search = request.GET.get('search') + + base_poultries = self.queryset.filter(Province__isnull=False) + base_hatchings = Hatching.objects.filter(trash=False) + + if province: + base_poultries = base_poultries.filter(Province__icontains=province) + base_hatchings = base_hatchings.filter(ProvinceName=province) + + if city: + base_poultries = base_poultries.filter(City__icontains=city) + base_hatchings = base_hatchings.filter(CityName=city) + + if search and search != 'undefined' and search.strip(): + base_poultries = base_poultries.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + hatchings_data = base_hatchings.aggregate( + total_count=Count('id'), + total_quantity=Sum('ChickCountSum'), + total_evacuation=Sum('Evacuation'), + total_left_over=Sum('LeftOver'), + active_count=Count('id', filter=Q(Age__lte=70)), + active_quantity=Sum('ChickCountSum', filter=Q(Age__lte=70)), + active_evacuation=Sum('Evacuation', filter=Q(Age__lte=70)), + active_left_over=Sum('LeftOver', filter=Q(Age__lte=70)), + active_ready_left_over=Sum('LeftOver', filter=Q(Age__gte=40, Age__lte=70)), + + ) + + transporting_data = TransportingDetail.objects.filter( + hatching__in=base_hatchings, + trash=False + ).aggregate( + total_killing=Sum('GoodAmount'), + total_killing_age=Avg('Age'), + active_killing=Sum('GoodAmount', filter=Q(hatching__Age__lte=70)), + active_killing_age=Avg('Age', filter=Q(hatching__Age__lte=70)), + ) + + location_stats = base_poultries.aggregate( + province_count=Count('LocationIdProvince', distinct=True), + city_count=Count('LocationIdCity', distinct=True), + ) + + return { + 'poultry_count': base_poultries.count(), + **hatchings_data, + **transporting_data, + **location_stats, + 'active_bars_count': base_hatchings.filter(Age__lte=70).count(), + } + + def list(self, request, *args, **kwargs): + try: + data = self._optimized_db_hits(request) + + total_quantity = data.get('total_quantity', 0) or 1 + active_quantity = data.get('active_quantity', 0) or 1 + + result = { + "poultry_count": data['poultry_count'], + "province_count": data['province_count'], + "city_count": data['city_count'], + + "total_hatching_count": data['total_count'], + "total_hatching_quantity": data['total_quantity'], + "total_hatching_evacuation": data['total_evacuation'], + "total_hatching_evacuation_percent": round((data['total_evacuation'] / total_quantity) * 100, 2), + "total_hatching_killing_quantity": data['total_killing'], + "total_hatching_killing_quantity_percent": round((data['total_killing'] / total_quantity) * 100, 2), + "total_hatching_left_over": data['total_left_over'], + "total_hatching_left_over_percent": round((data['total_left_over'] / total_quantity) * 100, 2), + "total_hatching_killing_age": data['total_killing_age'], + + "total_active_hatching_count": data['active_count'], + "total_active_hatching_quantity": data['active_quantity'], + "total_active_hatching_evacuation": data['active_evacuation'], + "total_active_hatching_evacuation_percent": round((data['active_evacuation'] / active_quantity) * 100, + 2), + "total_active_hatching_bars": data['active_bars_count'], + "total_active_hatching_killing_quantity": data['active_killing'], + "total_active_hatching_killing_quantity_percent": round( + (data['active_killing'] / active_quantity) * 100, 2), + "total_active_hatching_killing_age": data['active_killing_age'], + "total_active_hatching_left_over": data['active_left_over'], + "total_active_hatching_left_over_percent": round((data['active_left_over'] / active_quantity) * 100, 2), + "total_ready_active_hatching_left_over": data['active_ready_left_over'], + "total_ready_hatching_left_over_percent": round( + (data['active_ready_left_over'] / data['active_left_over']) * 100, 2), + } + + return Response(result, status=status.HTTP_200_OK) + + except Exception as e: + return Response( + {"error": "خطا در پردازش داده‌ها", "details": str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def all_province_detail_for_map(request): + provinces = list(Province.objects.values_list('name', flat=True)) + + hatchings = Hatching.objects.filter( + Age__gte=1, + Age__lte=65, + trash=False, + ProvinceName__in=provinces + ).values('ProvinceName').annotate( + total_quantity=Sum('ChickCountSum'), + total_left_over=Sum('LeftOver') + ) + + active_hatchings = hatchings.filter( + Age__gte=30, + Age__lte=65 + ).values('ProvinceName').annotate( + total_left_over=Sum('LeftOver') + ) + + transportings = TransportingDetail.objects.filter( + hatching__in=Hatching.objects.filter( + Age__gte=1, + Age__lte=65, + trash=False, + ProvinceName__in=provinces + ), + trash=False + ).values('hatching__ProvinceName').annotate( + total_killing=Sum('GoodAmount') + ) + + hatching_dict = {h['ProvinceName']: h for h in hatchings} + active_hatching_dict = {h['ProvinceName']: h for h in active_hatchings} + transporting_dict = {t['hatching__ProvinceName']: t for t in transportings} + + results = [] + for province in provinces: + h_data = hatching_dict.get(province, {'total_quantity': 0, 'total_left_over': 0}) + a_h_data = active_hatching_dict.get(province, {'total_left_over': 0}) + t_data = transporting_dict.get(province, {'total_killing': 0}) + + total_quantity = h_data['total_quantity'] or 0 + total_left = h_data['total_left_over'] or 0 + total_active_left = a_h_data['total_left_over'] or 0 + + results.append({ + "total_quantity": total_quantity, + "total_left_over": total_left, + "total_killed_quantity": t_data['total_killing'] or 0, + "total_hatching_left_over_percent": round( + (total_left / total_quantity * 100), + ) if total_quantity > 0 else 0, + "province_name": province, + "total_active_left": total_active_left, + "total_active_left_percent": round( + (total_active_left / total_quantity * 100), + ) if total_quantity > 0 else 0, + }) + + sorted_results = sorted( + results, + key=lambda x: x['total_quantity'], + reverse=True + ) + + return Response(sorted_results) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def dashboard_province_detail_for_map(request): + total_hatching = Hatching.objects.filter( + Age__gte=1, + Age__lte=65, + trash=False + ).aggregate( + total_quantity=Sum('ChickCountSum'), + total_left_over=Sum('LeftOver') + ) + + total_active = Hatching.objects.filter( + Age__gte=30, + Age__lte=65, + trash=False + ).aggregate( + total_active_left=Sum('LeftOver') + ) + + total_transporting = TransportingDetail.objects.filter( + hatching__in=Hatching.objects.filter( + Age__gte=1, + Age__lte=65, + trash=False + ), + trash=False + ).aggregate( + total_killing=Sum('GoodAmount') + ) + + total_quantity = total_hatching['total_quantity'] or 0 + total_left = total_hatching['total_left_over'] or 0 + total_active_left = total_active['total_active_left'] or 0 + left_over_percent = round((total_left / total_quantity * 100)) if total_quantity > 0 else 0 + total_active_left_percent = round((total_active_left / total_quantity * 100)) if total_quantity > 0 else 0 + + result = { + "total_quantity": total_quantity, + "total_left_over": total_left, + "total_killed_quantity": total_transporting['total_killing'] or 0, + "total_hatching_left_over_percent": left_over_percent, + "total_active_left": total_active_left, + "total_active_left_percent": total_active_left_percent, + } + + return Response(result) + +# class HatchingDashboardViewSet(viewsets.ModelViewSet): +# queryset = Hatching.objects.filter(trash=False).only('KillingAve', 'LeftOver', 'ProvinceName', 'CityName', +# 'SystemCode').order_by( +# 'id') +# serializer_class = HatchingSerializer +# permission_classes = [AllowAny] +# filterset_class = HatchingsFilterSet +# +# def list(self, request, *args, **kwargs): +# system_code = request.GET.get('system_code') +# search = request.GET.get('search') +# leftover = request.GET.get('leftover') +# province = request.GET.get('province') +# city = request.GET.get('city') +# killing_age = request.GET.get('killing_age') +# +# hatchings = self.queryset +# date1 = self.request.GET.get('date1') +# date2 = self.request.GET.get('date2') +# if date1 and date2: +# date1 = datetime.datetime.strptime(str(self.request.GET['date1']), '%Y-%m-%d').date() +# +# date2 = datetime.datetime.strptime(str(self.request.GET['date2']), '%Y-%m-%d').date() +# +# hatchings = hatchings.filter(Date__date__gte=date1, Date__date__lte=date2, trash=False) +# +# if killing_age: +# hatchings = hatchings.filter(KillingAve=int(killing_age), trash=False) +# if leftover: +# hatchings = hatchings.filter(LeftOver__gt=0, trash=False) +# +# if province: +# hatchings = hatchings.filter(ProvinceName=province) +# +# if system_code: +# hatchings = hatchings.filter(SystemCode=system_code) +# +# if city: +# hatchings = hatchings.filter(CityName=city) +# +# +# +# if search: +# if search != 'undefined' and search.strip(): +# hatchings = hatchings.filter( +# build_query(self.filterset_class.Meta.fields, search) +# ) +# active_hatchings = hatchings.filter(Age__lte=70, trash=False).order_by('id') +# bars = TransportingDetail.objects.filter(hatching__in=hatchings, trash=False).order_by('id') +# active_hatchings_bars = bars.filter(hatching__in=active_hatchings, trash=False).order_by('id') +# total_hatching_quantity = hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 0 +# total_hatching_evacuation = hatchings.aggregate(total=Sum('Evacuation'))['total'] or 0 +# total_hatching_killing_quantity = bars.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# total_hatching_left_over = hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0 +# total_active_hatching_quantity = active_hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 0 +# total_active_hatching_evacuation = active_hatchings.aggregate(total=Sum('Evacuation'))['total'] or 0 +# total_active_hatching_killing_quantity = active_hatchings_bars.aggregate(total=Sum('GoodAmount'))[ +# 'total'] or 0 +# total_active_hatching_left_over = active_hatchings.aggregate(total=Sum('LeftOver'))['total'] or 0 +# +# result = { +# "total_hatching_count": hatchings.count(), +# "total_hatching_quantity": total_hatching_quantity, +# "total_hatching_evacuation": total_hatching_evacuation, +# "total_hatching_evacuation_percent": round((total_hatching_evacuation / total_hatching_quantity) * 100, 2) if total_hatching_quantity > 0 else 0, +# "total_hatching_killing_quantity": total_hatching_killing_quantity, +# "total_hatching_killing_quantity_percent": round( +# (total_hatching_killing_quantity / total_hatching_quantity) * 100, 2) if total_hatching_quantity > 0 else 0, +# "total_hatching_left_over": total_hatching_left_over, +# "total_hatching_left_over_percent": round((total_hatching_left_over / total_hatching_quantity) * 100, 2) if total_hatching_quantity > 0 else 0, +# "total_hatching_killing_age": bars.aggregate(avg_age=Avg('Age'))['avg_age'] or 0, +# "total_hatching_bars": active_hatchings_bars.count(), +# "total_active_hatching_count": active_hatchings.count(), +# "total_active_hatching_quantity": total_active_hatching_quantity, +# "total_active_hatching_evacuation": total_active_hatching_evacuation, +# "total_active_hatching_evacuation_percent": round( +# (total_active_hatching_evacuation / total_active_hatching_quantity) * 100, 2) if total_active_hatching_quantity > 0 else 0, +# "total_active_hatching_bars": active_hatchings_bars.count(), +# "total_active_hatching_killing_quantity": total_active_hatching_killing_quantity, +# "total_active_hatching_killing_quantity_percent": round( +# (total_active_hatching_killing_quantity / total_active_hatching_quantity) * 100, 2) if total_active_hatching_quantity > 0 else 0, +# "total_active_hatching_left_over": total_active_hatching_left_over, +# "total_active_hatching_left_over_percent": round( +# (total_active_hatching_left_over / total_active_hatching_quantity) * 100, 2) if total_active_hatching_quantity > 0 else 0, +# "total_active_hatching_killing_age": active_hatchings_bars.aggregate(avg_age=Avg('Age'))['avg_age'] or 0, +# "least_age": active_hatchings.order_by('Age').first().Age if active_hatchings else 0, +# "most_age": active_hatchings.order_by('Age').last().Age if active_hatchings else 0, +# +# } +# return Response(result, status=status.HTTP_200_OK) + + +class HatchingDashboardViewSet(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False).only( + 'id', 'KillingAve', 'LeftOver', 'ProvinceName', 'CityName', + 'SystemCode', 'Date', 'Age', 'ChickCountSum', 'Evacuation' + ).order_by('id') + serializer_class = HatchingSerializer + permission_classes = [AllowAny] + filterset_class = HatchingsFilterSet + + def _apply_filters(self, queryset, request): + system_code = request.GET.get('system_code') + search = request.GET.get('search') + leftover = request.GET.get('leftover') + province = request.GET.get('province') + city = request.GET.get('city') + killing_age = request.GET.get('killing_age') + name = request.GET.get('name') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + if date1 and date2: + try: + date1 = datetime.datetime.strptime(date1, '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(date2, '%Y-%m-%d').date() + queryset = queryset.filter(Date__date__range=[date1, date2]) + except ValueError: + pass + + if killing_age: + queryset = queryset.filter(KillingAve=int(killing_age)) + if leftover: + queryset = queryset.filter(LeftOver__gt=0) + if province: + queryset = queryset.filter(ProvinceName=province) + if system_code: + queryset = queryset.filter(SystemCode=system_code) + if city: + queryset = queryset.filter(CityName=city) + if name: + poultry = Poultry.objects.filter( + Q(UserName__contains=name) | Q(FirstName__contains=name) | Q(LastName__contains=name) | Q( + Mobile__contains=name) | Q(UnitName__contains=name) + , trash=False).first() + queryset = queryset.filter(poultry=poultry) + if search and search != 'undefined' and search.strip(): + queryset = queryset.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + return queryset + + def _calculate_metrics(self, hatchings): + + hatchings = hatchings.prefetch_related( + Prefetch('transportingdetail_set', + queryset=TransportingDetail.objects.filter(trash=False)) + ) + + active_hatchings = hatchings.filter(Age__lte=70) + + main_stats = hatchings.aggregate( + total_count=Count('id'), + total_quantity=Sum('ChickCountSum'), + total_evacuation=Sum('Evacuation'), + total_left_over=Sum('LeftOver'), + active_count=Count('id', filter=Q(Age__lte=70)), + active_quantity=Sum('ChickCountSum', filter=Q(Age__lte=70)), + active_evacuation=Sum('Evacuation', filter=Q(Age__lte=70)), + active_left_over=Sum('LeftOver', filter=Q(Age__lte=70)), + active_ready_left_over=Sum('LeftOver', filter=Q(Age__gte=40, Age__lte=70)), + + ) + + bars_stats = TransportingDetail.objects.filter( + hatching__in=hatchings, + trash=False + ).aggregate( + total_killing=Sum('GoodAmount'), + avg_killing_age=Avg('Age'), + active_killing=Sum('GoodAmount', filter=Q(hatching__Age__lte=70)), + active_avg_age=Avg('Age', filter=Q(hatching__Age__lte=70)), + active_bars_count=Count('id'), + min_age=Min('Age'), + max_age=Max('Age') + ) + + return {**main_stats, **bars_stats} + + def list(self, request, *args, **kwargs): + # try: + filtered_hatchings = self._apply_filters(self.queryset, request) + + metrics = self._calculate_metrics(filtered_hatchings) + + total_quantity = metrics.get('total_quantity', 0) or 1 + active_quantity = metrics.get('active_quantity', 0) or 1 + if filtered_hatchings and filtered_hatchings.first().poultry: + poultry_name = filtered_hatchings.first().poultry.UnitName + poultry_mobile = filtered_hatchings.first().poultry.Mobile + poultry_firstName = filtered_hatchings.first().poultry.FirstName + poultry_lastName = filtered_hatchings.first().poultry.LastName + poultry_userName = filtered_hatchings.first().poultry.UserName + else: + poultry_name = '' + poultry_mobile = '' + poultry_firstName = '' + poultry_lastName = '' + poultry_userName = '' + result = { + "poultry_name": poultry_name, + "poultry_mobile": poultry_mobile, + "poultry_firstName": poultry_firstName, + "poultry_lastName": poultry_lastName, + "poultry_userName": poultry_userName, + "total_hatching_count": metrics['total_count'] if metrics['total_count'] else 0, + "total_hatching_quantity": metrics['total_quantity'] if metrics['total_quantity'] else 0, + "total_hatching_evacuation": metrics['total_evacuation'] if metrics['total_evacuation'] else 0, + "total_hatching_evacuation_percent": round((metrics['total_evacuation'] / total_quantity) * 100, 2) if + metrics['total_evacuation'] else 0, + "total_hatching_killing_quantity": metrics['total_killing'] if metrics['total_killing'] else 0, + "total_hatching_killing_quantity_percent": round((metrics['total_killing'] / total_quantity) * 100, 2) if + metrics['total_killing'] else 0, + "total_hatching_left_over": metrics['total_left_over'] if metrics['total_killing'] else 0, + "total_hatching_left_over_percent": round((metrics['total_left_over'] / total_quantity) * 100, 2) if + metrics['total_left_over'] else 0, + "total_hatching_killing_age": metrics['avg_killing_age'] if metrics['avg_killing_age'] else 0, + "total_hatching_bars": metrics.get('active_bars_count', 0), + + "total_active_hatching_count": metrics['active_count'] if metrics['active_count'] else 0, + "total_active_hatching_quantity": metrics['active_quantity'] if metrics['active_quantity'] else 0, + "total_active_hatching_evacuation": metrics['active_evacuation'] if metrics['active_evacuation'] else 0, + "total_active_hatching_evacuation_percent": round( + (metrics['active_evacuation'] / active_quantity) * 100, 2) if metrics['active_evacuation'] else 0, + "total_active_hatching_bars": metrics.get('active_bars_count', 0), + "total_active_hatching_killing_quantity": metrics['active_killing'] if metrics['active_killing'] else 0, + "total_active_hatching_killing_quantity_percent": round( + (metrics['active_killing'] / active_quantity) * 100, 2) if metrics['active_killing'] else 0, + "total_active_hatching_left_over": metrics['active_left_over'] if metrics['active_left_over'] else 0, + "total_active_hatching_left_over_percent": round((metrics['active_left_over'] / active_quantity) * 100, + 2) if metrics['active_left_over'] else 0, + "total_ready_active_hatching_left_over": metrics['active_ready_left_over'] if metrics[ + 'active_ready_left_over'] else 0, + "total_ready_hatching_left_over_percent": round( + (metrics['active_ready_left_over'] / metrics['active_left_over']) * 100, + 2) if metrics['active_ready_left_over'] else 0, + "total_active_hatching_killing_age": metrics['active_avg_age'] or 0, + "least_age": metrics.get('min_age', 0), + "most_age": metrics.get('max_age', 0), + } + + return Response(result, status=status.HTTP_200_OK) + + # except Exception as e: + # return Response( + # {"error": str(e)}, + # status=status.HTTP_500_INTERNAL_SERVER_ERROR + # ) + + +class PoultryHatchingDashboardViewSet(viewsets.ModelViewSet): + queryset = PoultryHatching.objects.all() + serializer_class = PoultryHatchingSerializer + permission_classes = [AllowAny] + filterset_class = PoultryHatchingFilterSet + + def list(self, request, *args, **kwargs): + hatchings = PoultryHatching.objects.filter(trash=False).order_by('Date') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + hatchings = hatchings.filter(Date__date__gte=date1, Date__date__lte=date2) + search = request.GET.get('search') + if search: + if search != 'undefined' and search.strip(): + hatchings = hatchings.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + poultry = Poultry.objects.filter(pk__in=hatchings.values_list('poultry', flat=True), trash=False) + transports = TransportingChickenDetail.objects.filter(hatching__isnull=False, trash=False) + hatching_quantity = hatchings.aggregate(total=Sum('HatchingCount'))['total'] or 0 + evacuation_count = hatchings.aggregate(total=Sum('EvacuationCount'))['total'] or 0 + bars_quantity = transports.aggregate(total=Sum('GoodAmount'))['total'] or 0 + result = { + "poultry": len(poultry), + "hatchings": len(hatchings), + "hatching_quantity": hatching_quantity, + "evacuation_count": evacuation_count, + "hatching_remain_quantity": hatching_quantity - evacuation_count, + "bars": len(transports), + "bars_quantity": bars_quantity, + + } + + return Response(result, status=status.HTTP_200_OK) + + +class PoultryHatchingViewSet(viewsets.ModelViewSet): + queryset = PoultryHatching.objects.all() + serializer_class = PoultryHatchingSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = PoultryHatchingFilterSet + + def create(self, request, *args, **kwargs): + data = request.data['Data'] + request.data.pop('Data') + for hatching_data in data: + registered_hatching = PoultryHatching.objects.filter(DesCertId=hatching_data['DesCertId']).first() + if registered_hatching: + for key, value in hatching_data.items(): + setattr(registered_hatching, key, value) + registered_hatching.save() + + else: + hatching = PoultryHatching.objects.create(**hatching_data) + poultry = Poultry.objects.filter(UnitId=hatching_data['UnitId']).first() + if poultry: + hatching.poultry = poultry + hatching.save() + + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + def list(self, request, *args, **kwargs): + hatchings = PoultryHatching.objects.filter(trash=False).order_by('Date') + # hatchings = PoultryHatching.objects.filter( + # pk__in=TransportingChickenDetail.objects.filter(trash=False).values_list('hatching', flat=True), + # trash=False).order_by('Date') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + hatchings = hatchings.filter(Date__date__gte=date1, Date__date__lte=date2) + + search = request.GET.get('search') + if search: + if search != 'undefined' and search.strip(): + hatchings = hatchings.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(hatchings) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(hatchings, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class HatchingsViewSet(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False) + serializer_class = HatchingsSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = HatchingsFilterSet + + def set_filters(self): + filters = {} + system_code = self.request.GET.get('system_code') + city = self.request.GET.get('city') + province = self.request.GET.get('province') + age = self.request.GET.get('age') + killing_age = self.request.GET.get('killing_age') + date1 = self.request.GET.get('date1') + date2 = self.request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(self.request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(self.request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + + if killing_age: + filters['KillingAve'] = int(killing_age) + if system_code: + filters['SystemCode'] = system_code + if age: + filters['Age__exact'] = age + if city: + filters['CityName__icontains'] = city + if province: + filters['ProvinceName__icontains'] = province + + return filters + + def create(self, request, *args, **kwargs): + BREED_STANDARDIZATION = { + 'آربراکرز (آ��لاس)': 'آربراکرز (آپلاس)', + 'آربراک��ز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربر��کرز (آپلاس)': 'آربراکرز (آپلاس)', + 'را��': 'راس', + 'ر��س': 'راس', + '��اس': 'راس', + 'آ��ین': 'آرین', + 'آر��ن': 'آرین', + 'ایندین ریو��': 'ایندین ریور', + 'ایند��ن ریور': 'ایندین ریور', + 'ک��ب': 'کاب' + } + if int(request.data['GoodSum']) > 0: + bars = request.data.get('Transports', []) + if 'Transports' in request.data: + request.data.pop('Transports') + evacuation_details = request.data.get('EvacuationDetail', []) + if 'EvacuationDetail' in request.data: + request.data.pop('EvacuationDetail') + + hatching = Hatching.objects.filter(RequestCode=request.data['RequestCode']).first() + print({'1': request.data['ProvinceName']}) + if hatching: + for key, value in request.data.items(): + setattr(hatching, key, value) + hatching.save() + + else: + poultry = Poultry.objects.filter(SystemCode=request.data['SystemCode']).first() + hatchings = Hatching.objects.filter(poultry=poultry).order_by('id').last() + period = hatchings.Period + 1 if hatchings else 1 + request.data['Period'] = period + hatching = Hatching.objects.create(**request.data) + hatching.ArchiveDate = hatching.Date + datetime.timedelta(days=76) + + if poultry: + hatching.poultry = poultry + hatching.save() + allowed_evacuation_fields = { + 'PartIdCode', 'RequestId', 'MoReportId', 'ReportType', 'ReportTypeString', + 'ReportDate', 'ReportDateShamsi', 'MoReason', 'MoDate', 'MoDateShamsi', + 'MoStartDay', 'MoEndDay', 'MoReportSubId', 'ReportStatus', 'GoodCount', + 'Message', 'ErrorCode', 'IsDeleted', 'RegDate', 'RegDateShamsi', + 'RegDateShamsiWithTime', 'RegDateShamsiOnlyTime', 'ExternalId', 'StringId', + 'IsPersisted', 'AllowInsert', 'AllowUpdate', 'ModalCss', + 'GridContainerParametersModel', 'MenuUserAccess', 'MenuUserAccessId', + 'LogTableName', 'LogTableAlias', 'PageTitle' + } + + if evacuation_details: + cleaned_payload = [] + external_ids = [] + for evacuation_data in evacuation_details: + clean_data = { + k: v for k, v in evacuation_data.items() + if k in allowed_evacuation_fields or k == 'Id' + } + external_id = clean_data.pop('Id', None) + if external_id is not None: + clean_data['ExternalId'] = external_id + external_ids.append(external_id) + cleaned_payload.append((external_id, clean_data)) + + existing_map = {} + if external_ids: + existing_qs = EvacuationDetail.objects.filter( + ExternalId__in=external_ids, + trash=False + ) + existing_map = {ev.ExternalId: ev for ev in existing_qs} + + bulk_create = [] + for external_id, clean_data in cleaned_payload: + if external_id: + evacuation = existing_map.get(external_id) + if evacuation and 'GoodCount' in clean_data: + evacuation.GoodCount = clean_data['GoodCount'] + evacuation.hatching = hatching + evacuation.save(update_fields=['GoodCount', 'hatching']) + continue + clean_data['hatching'] = hatching + bulk_create.append(EvacuationDetail(**clean_data)) + + if bulk_create: + EvacuationDetail.objects.bulk_create(bulk_create) + + if bars: + for transport_data in bars: + transport = TransportingDetail.objects.filter( + TrackingCode=transport_data['TrackingCode']).first() + if transport: + for key, value in transport_data.items(): + setattr(transport, key, value) + transport.save() + + else: + transport = TransportingDetail.objects.create(**transport_data) + kill_house = KillHouse.objects.filter(PartIdCode=transport.DesPartIdCode, trash=False).first() + transport.hatching = hatching + if kill_house: + transport.Province = kill_house.Province + transport.City = kill_house.City + if hatching.poultry.LocationIdProvince != kill_house.ProvinceId: + transport.Out = True + transport.save() + transport.Age = (transport.Date.date() - transport.hatching.Date.date()).days + 1 + transport.save() + bars = TransportingDetail.objects.filter(trash=False, hatching=hatching) + bars_quantity = bars.filter(TrackingStatusDescription='تایید تخلیه').aggregate(total=Sum('GoodAmount'))[ + 'total'] or 0 + ave_age = int(bars.aggregate(avg_age=Avg('Age'))[ + 'avg_age'] or 0) + hatching.LeftOver = hatching.ChickCountSum - (hatching.Evacuation + bars_quantity) if ( + hatching.ChickCountSum - ( + hatching.Evacuation + bars_quantity)) > 0 else 0 + print({'2': hatching.ProvinceName}) + if hatching.PedigreeName in BREED_STANDARDIZATION: + hatching.PedigreeName = BREED_STANDARDIZATION[hatching.PedigreeName] + hatching.KillingAve = ave_age + hatching.samasat_discharge_percentage = int( + ((hatching.Evacuation + bars_quantity) / hatching.ChickCountSum) * 100) + hatching.save() + else: + print('تعداد حمل صفر است') + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + def list(self, request, *args, **kwargs): + state = self.request.GET.get('state') + hatchings = Hatching.objects.filter(**self.set_filters()) + if state: + if state == 'pending': + hatchings = hatchings.filter(Age__lte=70) + + else: + hatchings = hatchings.filter(Age__gt=70) + + search = request.GET.get('search') + if search: + if search != 'undefined' and search.strip(): + hatchings = hatchings.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(hatchings) + if page is not None: + serializer = HatchingDetailSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = HatchingDetailSerializer(hatchings, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class HatchingsCustomViewSet(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False) + serializer_class = HatchingsSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = CustomHatchingsFilterSet + + def create(self, request, *args, **kwargs): + BREED_STANDARDIZATION = { + 'آربراکرز (آ��لاس)': 'آربراکرز (آپلاس)', + 'آربراک��ز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربر��کرز (آپلاس)': 'آربراکرز (آپلاس)', + 'را��': 'راس', + 'ر��س': 'راس', + '��اس': 'راس', + 'آ��ین': 'آرین', + 'آر��ن': 'آرین', + 'ایندین ریو��': 'ایندین ریور', + 'ایند��ن ریور': 'ایندین ریور', + 'ک��ب': 'کاب' + } + + bars = request.data.get('Transports', []) + if 'Transports' in request.data: + request.data.pop('Transports') + + evacuation_details = request.data.get('EvacuationDetail', []) + if 'EvacuationDetail' in request.data: + request.data.pop('EvacuationDetail') + + hatching = Hatching.objects.filter(RequestCode=request.data['RequestCode']).first() + if hatching: + for key, value in request.data.items(): + setattr(hatching, key, value) + hatching.save() + + else: + poultry = Poultry.objects.filter(SystemCode=request.data['SystemCode']).first() + hatchings = Hatching.objects.filter(poultry=poultry).order_by('id').last() + period = hatchings.Period + 1 if hatchings else 1 + request.data['Period'] = period + hatching = Hatching.objects.create(**request.data) + hatching.ArchiveDate = hatching.Date + datetime.timedelta(days=76) + + if poultry: + hatching.poultry = poultry + hatching.save() + + allowed_evacuation_fields = { + 'PartIdCode', 'RequestId', 'MoReportId', 'ReportType', 'ReportTypeString', + 'ReportDate', 'ReportDateShamsi', 'MoReason', 'MoDate', 'MoDateShamsi', + 'MoStartDay', 'MoEndDay', 'MoReportSubId', 'ReportStatus', 'GoodCount', + 'Message', 'ErrorCode', 'IsDeleted', 'RegDate', 'RegDateShamsi', + 'RegDateShamsiWithTime', 'RegDateShamsiOnlyTime', 'ExternalId', 'StringId', + 'IsPersisted', 'AllowInsert', 'AllowUpdate', 'ModalCss', + 'GridContainerParametersModel', 'MenuUserAccess', 'MenuUserAccessId', + 'LogTableName', 'LogTableAlias', 'PageTitle' + } + + if evacuation_details: + cleaned_payload = [] + external_ids = [] + for evacuation_data in evacuation_details: + clean_data = { + k: v for k, v in evacuation_data.items() + if k in allowed_evacuation_fields or k == 'Id' + } + external_id = clean_data.pop('Id', None) + if external_id is not None: + clean_data['ExternalId'] = external_id + external_ids.append(external_id) + cleaned_payload.append((external_id, clean_data)) + + existing_map = {} + if external_ids: + existing_qs = EvacuationDetail.objects.filter( + ExternalId__in=external_ids, + ) + existing_map = {ev.ExternalId: ev for ev in existing_qs} + + bulk_create = [] + for external_id, clean_data in cleaned_payload: + if external_id and external_id in existing_map: + evacuation = existing_map[external_id] + for key, value in clean_data.items(): + setattr(evacuation, key, value) + evacuation.hatching = hatching + evacuation.save() + else: + clean_data['hatching'] = hatching + bulk_create.append(EvacuationDetail(**clean_data)) + + if bulk_create: + EvacuationDetail.objects.bulk_create(bulk_create) + + if bars: + for transport_data in bars: + transport = TransportingDetail.objects.filter( + TrackingCode=transport_data['TrackingCode']).first() + if transport: + for key, value in transport_data.items(): + setattr(transport, key, value) + transport.save() + + else: + transport = TransportingDetail.objects.create(**transport_data) + kill_house = KillHouse.objects.filter(PartIdCode=transport.DesPartIdCode, trash=False).first() + transport.hatching = hatching + if kill_house: + transport.Province = kill_house.Province + transport.City = kill_house.City + if hatching.poultry.LocationIdProvince != kill_house.ProvinceId: + transport.Out = True + transport.save() + transport.Age = (transport.Date.date() - transport.hatching.Date.date()).days + 1 + transport.save() + bars = TransportingDetail.objects.filter(trash=False, hatching=hatching) + bars_quantity = bars.aggregate(total=Sum('GoodAmount'))['total'] or 0 + ave_age = int(bars.aggregate(avg_age=Avg('Age'))[ + 'avg_age'] or 0) + hatching.LeftOver = hatching.ChickCountSum - (hatching.Evacuation + bars_quantity) if ( + hatching.ChickCountSum - ( + hatching.Evacuation + bars_quantity)) > 0 else 0 + + if hatching.PedigreeName in BREED_STANDARDIZATION: + hatching.PedigreeName = BREED_STANDARDIZATION[hatching.PedigreeName] + hatching.KillingAve = ave_age + hatching.save() + + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + def list(self, request, *args, **kwargs): + queryset = self.filter_queryset(self.get_queryset()) + page_size = request.query_params.get('page_size') + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(queryset) + if page is not None: + serializer = HatchingDetailSerializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = HatchingDetailSerializer(queryset, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class PoultryHatchingForUpdatePedigreeNameViewSet(viewsets.ModelViewSet): + queryset = PoultryHatching.objects.all() + serializer_class = PoultryHatchingSerializer + permission_classes = [AllowAny] + + def create(self, request, *args, **kwargs): + data = request.data['Data'] + request.data.pop('Data') + for hatching_data in data: + hatching = PoultryHatching.objects.filter(PartIdCode=hatching_data['PartIdCode']).first() + if hatching: + if hatching.PedigreeName: + hatching.PedigreeName = 'ترکیبی' + else: + hatching.PedigreeName = hatching_data['PedigreeName'] + + hatching.save() + + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + +class TransportingChickenDetailViewSet(viewsets.ModelViewSet): + queryset = TransportingChickenDetail.objects.all() + serializer_class = TransportingChickenDetailSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportingChickenDetailFilterSet + + def create(self, request, *args, **kwargs): + data = request.data['Data'] + request.data.pop('Data') + for transport_data in data: + transport = TransportingChickenDetail.objects.filter(TrackingCode=transport_data['TrackingCode']).first() + if transport: + for key, value in transport_data.items(): + setattr(transport, key, value) + transport.save() + + else: + transport = TransportingChickenDetail.objects.create(**transport_data) + hatching = PoultryHatching.objects.filter(DesCertId=transport_data['CertId']).first() + if hatching: + transport.hatching = hatching + transport.save() + + return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) + + def list(self, request, *args, **kwargs): + transports = TransportingChickenDetail.objects.filter(hatching__isnull=False, trash=False).order_by( + '-issue_date') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + transports = transports.filter(reside_date__date__gte=date1, reside_date__date__lte=date2) + search = request.GET.get('search') + if search: + if search != 'undefined' and search.strip(): + transports = transports.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(transports) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(transports, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class HatchingViewSet(viewsets.ModelViewSet): + queryset = PoultryHatching.objects.all() + serializer_class = HatchingSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + + def list(self, request, *args, **kwargs): + hatchings = PoultryHatching.objects.filter(trash=False) + city = request.GET.get('city') + province = request.GET.get('province') + age = request.GET.get('age') + filters = {} + if age: + filters['HatchingAge__exact'] = age + if city: + filters['LocationNameCity__icontains'] = city + if province: + filters['LocationNameProvince__icontains'] = province + hatchings = hatchings.filter(**filters) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(hatchings) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(hatchings, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +# class TransportingDashboardViewSet(viewsets.ModelViewSet): +# queryset = TransportingDetail.objects.filter(trash=False).only('id').order_by('id') +# serializer_class = TransportingSerializer +# permission_classes = [AllowAny] +# filterset_class = TransportingDetailFilterSet +# +# def list(self, request, *args, **kwargs): +# bars = self.queryset +# filters = {} +# RequestCode = request.GET.get('RequestCode') +# date1 = request.GET.get('date1') +# date2 = request.GET.get('date2') +# city = request.GET.get('city') +# search = request.GET.get('search') +# province = request.GET.get('province') +# if date1 and date2: +# date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() +# +# date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() +# filters['Date__date__gte'] = date1 +# filters['Date_date__lte'] = date2 +# if city: +# filters['City__icontains'] = city +# +# if province: +# filters['Province__icontains'] = province +# +# if RequestCode: +# filters['hatching__RequestCode'] = RequestCode +# +# +# bars = bars.filter(**filters) +# +# if search: +# if search != 'undefined' and search.strip(): +# bars = bars.filter( +# build_query(self.filterset_class.Meta.fields, search) +# ) +# bar_quantity = bars.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# total_bar_killing_age = bars.aggregate(avg_age=Avg('Age'))['avg_age'] or 0 +# input_bar = bars.filter(Out=False) +# input_bar__percent = input_bar.count() / bars.count() * 100 +# input_bar_quantity = input_bar.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# output_bar = bars.filter(Out=True) +# output_bar_quantity = output_bar.aggregate(total=Sum('GoodAmount'))['total'] or 0 +# output_bar_percent = output_bar.count() / bars.count() * 100 +# result = { +# "bar_count": bars.count(), +# "bar_quantity": bar_quantity, +# "total_bar_killing_age": total_bar_killing_age, +# "input_bar_count": input_bar.count(), +# "input_bar_quantity": input_bar_quantity, +# "input_bar_percent": input_bar__percent, +# "output_bar": output_bar.count(), +# "output_bar_quantity": output_bar_quantity, +# "output_bar_percent": output_bar_percent, +# +# } +# return Response(result, status=status.HTTP_200_OK) + +class TransportingDashboardViewSet(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False) + serializer_class = TransportingSerializer + permission_classes = [AllowAny] + filterset_class = TransportingDetailFilterSet + + def _apply_filters(self, queryset, request): + filters = {} + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + try: + date1 = datetime.datetime.strptime(date1, '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(date2, '%Y-%m-%d').date() + filters['Date__date__range'] = [date1, date2] + except ValueError: + pass + + if city := request.GET.get('city'): + filters['City__icontains'] = city + if province := request.GET.get('province'): + if province == 'undefined': + province = None + filters['hatching__poultry__Province__icontains'] = province + if RequestCode := request.GET.get('RequestCode'): + filters['hatching__RequestCode'] = RequestCode + + if DesPartIdCode := request.GET.get('PartIdCode'): + filters['DesPartIdCode'] = DesPartIdCode + + queryset = queryset.filter(**filters) + + if search := request.GET.get('search'): + if search != 'undefined' and search.strip(): + queryset = queryset.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + return queryset + + def _apply_filters_all_products(self, queryset, request): + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + try: + date1 = datetime.datetime.strptime(date1, '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(date2, '%Y-%m-%d').date() + queryset = queryset.filter( + date__gte=date1, + date__lte=date2, + date__isnull=False + + ) + except ValueError: + pass + + if city := request.GET.get('city'): + queryset = queryset.filter(destination_city__icontains=city) + if province := request.GET.get('province'): + if province == 'undefined': + province = None + if province: + queryset = queryset.filter(destination_province__icontains=province) + if RequestCode := request.GET.get('RequestCode'): + queryset = queryset.filter(hatching__RequestCode=RequestCode) + + if DesPartIdCode := request.GET.get('PartIdCode'): + queryset = queryset.filter(jihadi_destination=DesPartIdCode) + + if search := request.GET.get('search'): + if search != 'undefined' and search.strip(): + queryset = queryset.filter( + build_query(AllProductsTransportFilterSet.Meta.fields, search) + ) + + return queryset + + def _calculate_metrics(self, queryset, all_products_queryset): + stats = queryset.aggregate( + total_count=Count('id'), + total_quantity=Sum('GoodAmount'), + avg_age=Avg('Age'), + input_count=Count('id', filter=Q(Out=False)), + input_quantity=Sum('GoodAmount', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + output_quantity=Sum('GoodAmount', filter=Q(Out=True)), + ) + + all_products_stats = all_products_queryset.aggregate( + total_count=Count('id'), + total_quantity=Sum('quantity'), + input_count=Count('id', filter=Q(out=False)), + input_quantity=Sum('quantity', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + output_quantity=Sum('quantity', filter=Q(out=True)), + ) + + stats['total_count'] = (stats.get('total_count') or 0) + (all_products_stats.get('total_count') or 0) + stats['total_quantity'] = (stats.get('total_quantity') or 0) + (all_products_stats.get('total_quantity') or 0) + stats['input_count'] = (stats.get('input_count') or 0) + (all_products_stats.get('input_count') or 0) + stats['input_quantity'] = (stats.get('input_quantity') or 0) + (all_products_stats.get('input_quantity') or 0) + stats['output_count'] = (stats.get('output_count') or 0) + (all_products_stats.get('output_count') or 0) + stats['output_quantity'] = (stats.get('output_quantity') or 0) + (all_products_stats.get('output_quantity') or 0) + + total_count = stats['total_count'] or 1 + stats.update({ + 'input_percent': (stats['input_count'] / total_count) * 100, + 'output_percent': (stats['output_count'] / total_count) * 100, + }) + + return stats + + def list(self, request, *args, **kwargs): + try: + filtered_bars = self._apply_filters(self.queryset, request) + + query_all_products = AllProductsTransport.objects.filter( + trash=False, + product='مرغ زنده -جهت كشتار' + ) + filtered_all_products = self._apply_filters_all_products(query_all_products, request) + + metrics = self._calculate_metrics(filtered_bars, filtered_all_products) + + result = { + "bar_count": metrics['total_count'], + "bar_quantity": metrics['total_quantity'] or 0, + "total_bar_killing_age": metrics['avg_age'] or 0, + "input_bar_count": metrics['input_count'], + "input_bar_quantity": metrics['input_quantity'] or 0, + "input_bar_percent": round(metrics['input_percent'], 2), + "output_bar": metrics['output_count'], + "output_bar_quantity": metrics['output_quantity'] or 0, + "output_bar_percent": round(metrics['output_percent'], 2), + } + + return Response(result, status=status.HTTP_200_OK) + + except Exception as e: + return Response( + {"error": str(e)}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR + ) + + +class TransportingDetailViewSet(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False) + serializer_class = TransportingDetailSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportingDetailFilterSet + + def list(self, request, *args, **kwargs): + filters = {} + PartIdCode = request.GET.get('PartIdCode') + RequestCode = request.GET.get('RequestCode') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + city = request.GET.get('city') + province = request.GET.get('province') + if province == 'undefined': + province = None + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + if city: + filters['City__icontains'] = city + + if province: + # filters['Province__icontains'] = province + filters['hatching__poultry__Province__icontains'] = province + + if PartIdCode: + filters['DesPartIdCode'] = PartIdCode + + if RequestCode: + filters['hatching__RequestCode'] = RequestCode + + search = request.GET.get('search') + transports = TransportingDetail.objects.filter(**filters, trash=False).order_by("-Date") + + # Query برای AllProductsTransport با product='مرغ زنده -جهت كشتار' + query_all_products = AllProductsTransport.objects.filter( + 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( + build_query(self.filterset_class.Meta.fields, search) + ) + # اعمال search روی AllProductsTransport + 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: + if isinstance(obj.Date, datetime.datetime): + return obj.Date.date() + elif isinstance(obj.Date, datetime.date): + return obj.Date + elif hasattr(obj, 'date') and obj.date: + return obj.date + 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] + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + paginator = self.pagination_class() + page = paginator.paginate_queryset(sorted_objects, request) + + if page is not None: + serialized_data = [] + for obj in page: + if hasattr(obj, 'Date'): # TransportingDetail + serializer = TransportingDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: # AllProductsTransport + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + date_value = obj.date if obj.date else obj.unloading_date + if date_value: + data['Date'] = datetime.datetime.combine(date_value, datetime.time.min) if isinstance(date_value, datetime.date) else date_value + else: + data['Date'] = None + data['DesPartIdCode'] = obj.jihadi_destination + data['TrackingCode'] = obj.tracking + data['GoodAmount'] = obj.quantity + data['DesUnitName'] = obj.destination + data['Province'] = obj.destination_province + data['City'] = obj.destination_city + data['Out'] = obj.out + serialized_data.append(data) + return paginator.get_paginated_response(serialized_data) + + serialized_data = [] + for obj in sorted_objects: + if hasattr(obj, 'Date'): # TransportingDetail + serializer = TransportingDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: # AllProductsTransport + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + date_value = obj.date if obj.date else obj.unloading_date + if date_value: + data['Date'] = datetime.datetime.combine(date_value, datetime.time.min) if isinstance(date_value, datetime.date) else date_value + else: + data['Date'] = None + data['DesPartIdCode'] = obj.jihadi_destination + data['TrackingCode'] = obj.tracking + data['GoodAmount'] = obj.quantity + data['DesUnitName'] = obj.destination + data['Province'] = obj.destination_province + data['City'] = obj.destination_city + data['Out'] = obj.out + serialized_data.append(data) + return Response(serialized_data, status=status.HTTP_200_OK) + + +class HatchingCalculationsViewSet(viewsets.ModelViewSet): + queryset = PoultryHatching.objects.all() + serializer_class = HatchingCalculationSerializer + permission_classes = [AllowAny] + filterset_class = HatchingCalculationsFilterSet + + def list(self, request, *args, **kwargs): + city = request.GET.get('city') + province = request.GET.get('province') + value = request.GET.get('value') + filters = {'trash': False} + if city: + filters['LocationNameCity__in'] = [city] + if province: + filters['LocationNameProvince__in'] = [province] + + hatching_dict = PoultryHatching.objects.filter(**filters) + if value: + hatching_dict = hatching_dict.filter( + build_query(self.filterset_class.Meta.fields, value) + ) + total_evacuation = build_calculation(queryset=hatching_dict, column_name='EvacuationCount', aggregate_func=Sum) + total_poultry_hatching = build_calculation(queryset=hatching_dict, column_name='HatchingCount', + aggregate_func=Sum) + total_poultry = hatching_dict.values('poultry').distinct().count() + total_leftover = build_calculation(queryset=hatching_dict, column_name='LeftOver', aggregate_func=Sum) + + return Response({"evacuation_sum": total_evacuation, "hatching_count": total_poultry_hatching, + "total_poultry": total_poultry, "leftover": total_leftover + }, + status=status.HTTP_200_OK) + + +class PoultryInfoViewSet(viewsets.ModelViewSet): + queryset = Poultry.objects.all() + serializer_class = PoultryInfoSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = PoultryInfoFilterSet + + def list(self, request, *args, **kwargs): + poultry = Poultry.objects.filter(trash=False).order_by('id') + search = request.GET.get('search') + leftover = request.GET.get('leftover') + province = request.GET.get('province') + city = request.GET.get('city') + if leftover: + poultry = poultry.filter( + pk__in=Hatching.objects.filter(LeftOver__gt=0, trash=False).values_list('poultry', + flat=True)) + + if province: + poultry = poultry.filter(LocationNameProvince__icontains=province) + + if city: + poultry = poultry.filter(LocationNameCity__icontains=city) + + if search: + if search != 'undefined' and search.strip(): + poultry = poultry.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(poultry) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(poultry, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class TotalKillHousesViewSet(viewsets.ModelViewSet): + queryset = KillHouse.objects.filter(trash=False).only('id', 'PartIdCode', 'UnitName', 'Province', 'City').order_by('id') + serializer_class = KillHouseSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = KillHouseFilterSet + + def list(self, request, *args, **kwargs): + search = request.GET.get('search') + filters = {"trash": False} + if province := request.GET.get('province'): + filters['Province'] = province + + if city := request.GET.get('city'): + filters['City'] = city + + if kill_houses_name := request.GET.get('name'): + filters['UnitName'] = kill_houses_name + + kill_houses = self.queryset.filter(**filters) + + if search: + if search != 'undefined' and search.strip(): + kill_houses = kill_houses.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + 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, + 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)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + 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, + "input_bars": input_bars_count, + "total_input_bars_quantity": total_input_bars_quantity, + "total_input_bars_percent": total_input_bars_percent, + "output_bars": output_bars_count, + "total_output_bars_quantity": total_output_bars_quantity, + "total_output_bars_percent": total_output_bars_percent, + } + + if page is not None: + serializer = self.get_serializer(page, many=True, context={'request': request, 'info_cache': info_cache}) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(kill_houses, many=True, context={'request': request, 'info_cache': info_cache}) + return Response(serializer.data, status=status.HTTP_200_OK) + + +class HatchingAnalysisPedigreeViewSet(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False, poultry__isnull=False, PedigreeName__isnull=False) + serializer_class = HatchingAnalysisSerializer + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + filters = {} + pedigree = request.GET.get('pedigree') + city = request.GET.get('city') + province = request.GET.get('province') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + state = request.GET.get('state') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + if city: + filters['CityName__icontains'] = city + + if province: + filters['ProvinceName__icontains'] = province + + if pedigree: + filters['PedigreeName__icontains'] = pedigree + + if state == 'active': + filters['Age__lte'] = 70 + else: + pass + + hatchings = self.queryset.filter(**filters) + pedigree_name_poultry = hatchings.values('PedigreeName').annotate( + poultry_count=Count('poultry', distinct=True)).order_by('-poultry_count') + + pedigree_name_hatching_count = hatchings.values('PedigreeName').annotate( + chick_count=Count('ChickCountSum')).order_by( + '-chick_count') + pedigree_name_hatching_sum = hatchings.values('PedigreeName').annotate( + chick_sum=Sum('ChickCountSum')).order_by( + '-chick_sum') + pedigree_name_leftover = hatchings.values('PedigreeName').annotate(left_over=Sum('LeftOver')).order_by( + '-left_over') + + pedigree_name_pedigree = hatchings.values('PedigreeName').annotate(pedigree_name=Sum('id')).order_by( + '-pedigree_name') + + pedigree_name_average_age = hatchings.values( + 'PedigreeName').annotate(average_age=Avg('KillingAve')).order_by('-average_age') + for item in pedigree_name_average_age: + item['average_age'] = int(item['average_age']) if item['average_age'] is not None else 0 + + pedigree_name_active_hatching_count = hatchings.filter(Age__lte=70).values('PedigreeName').annotate( + chick_count=Count('ChickCountSum')).order_by( + '-chick_count') + + pedigree_name_active_hatching_sum = hatchings.filter(Age__lte=70).values('PedigreeName').annotate( + chick_count=Sum('ChickCountSum')).order_by( + '-chick_count') + hatchings_by_province = hatchings.values('ProvinceName', 'PedigreeName').annotate( + hatching_sum=Sum('ChickCountSum')).order_by('ProvinceName', '-hatching_sum') + provinces_dict = defaultdict(lambda: {'total_sum': 0, 'breeds': []}) + + for h in hatchings_by_province: + province = h['ProvinceName'] + pedigree = h['PedigreeName'] + hatching_sum = h['hatching_sum'] + + provinces_dict[province]['breeds'].append({ + 'pedigree': pedigree, + 'hatching_sum': hatching_sum + }) + provinces_dict[province]['total_sum'] += hatching_sum + + province_result = [ + { + 'province': province, + 'hatching_sum_all': values['total_sum'], + 'breeds': values['breeds'] + } + for province, values in provinces_dict.items() + ] + + pedigree_name_evacuation_sum = hatchings.values('PedigreeName').annotate( + evacuation=Sum('Evacuation')).order_by( + '-evacuation') + pedigree_name_bars_sum = hatchings.values('PedigreeName').annotate( + count_bars=Sum('transport_hatching__GoodAmount')).order_by( + '-count_bars') + + evacuation_dict = { + item['PedigreeName']: item['evacuation'] or 0 + for item in pedigree_name_evacuation_sum + } + hatching_dict = { + item['PedigreeName']: item['chick_sum'] or 0 + for item in pedigree_name_hatching_sum + } + total_hatching = hatchings.aggregate(total=Sum('ChickCountSum'))['total'] or 1 + + evacuation_hatching_percent = [] + for item in pedigree_name_bars_sum: + pedigree = item['PedigreeName'] + evacuation_sum = evacuation_dict.get(pedigree, 0) + hatching_sum = hatching_dict.get(pedigree, 1) + + percent_by_pedigree = round((evacuation_sum / hatching_sum) * 100, 2) + percent_by_total = round((evacuation_sum / total_hatching) * 100, 2) + + evacuation_hatching_percent.append({ + "pedigree_name": pedigree, + "pedigree": percent_by_pedigree, + "total": percent_by_total + }) + + result = { + "pedigree_name_poultry": pedigree_name_poultry, + "pedigree_name_hatching_count": pedigree_name_hatching_count, + "pedigree_name_hatching_sum": pedigree_name_hatching_sum, + "pedigree_name_leftover": pedigree_name_leftover, + "pedigree_name_pedigree": pedigree_name_pedigree, + "pedigree_name_average_age": pedigree_name_average_age, + "pedigree_name_active_hatching_count": pedigree_name_active_hatching_count, + "pedigree_name_active_hatching_sum": pedigree_name_active_hatching_sum, + "province_result": province_result, + "pedigree_name_evacuation_sum": pedigree_name_evacuation_sum, + "pedigree_name_bars_sum": pedigree_name_bars_sum, + "pedigree_evacuation_hatching_percent": evacuation_hatching_percent, + } + return Response(result, status=status.HTTP_200_OK) + + +class HatchingAnalysisProvinceView(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False, poultry__isnull=False) + serializer_class = HatchingAnalysisSerializerTwo + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + filters = {} + state = request.GET.get('state') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + + if state == 'active': + filters['Age__lte'] = 70 + else: + pass + + hatchings = self.queryset.filter(**filters) + province_sum_transporting = hatchings.filter(transport_hatching__GoodAmount__isnull=False).values( + 'ProvinceName').annotate( + good_amount=Sum('transport_hatching__GoodAmount')).order_by( + '-good_amount') + + province_hatching_sum = hatchings.values('ProvinceName').annotate( + chick_sum=Sum('ChickCountSum')).order_by( + '-chick_sum') + + province_name_leftover = hatchings.values('ProvinceName').annotate(left_over=Sum('LeftOver')).order_by( + '-left_over') + + province_name_average_age = hatchings.values( + 'ProvinceName').annotate(average_age=Avg('KillingAve')).order_by('-average_age') + + province_name_poultry = hatchings.values('ProvinceName').annotate( + poultry_count=Count('poultry', distinct=True)).order_by('-poultry_count') + + for item in province_name_average_age: + item['average_age'] = int(item['average_age']) if item['average_age'] is not None else 0 + + province_data = hatchings.values('ProvinceName').annotate( + total_evacuation=Sum('Evacuation'), + total_chicks=Sum('ChickCountSum') + ).order_by('-ProvinceName') + province_evacuation_hatching_percent = [] + + for item in province_data: + total_chicks = item['total_chicks'] + total_evacuation = item['total_evacuation'] + + if total_chicks: + percent = round((total_evacuation / total_chicks) * 100, 2) + else: + percent = 0 + + province_evacuation_hatching_percent.append({ + 'ProvinceName': item['ProvinceName'], + 'evacuation_hatching': percent + }) + + result = { + "province_sum_transporting": province_sum_transporting, + "province_hatching_sum": province_hatching_sum, + "province_name_poultry": province_name_poultry, + "province_name_leftover": province_name_leftover, + "province_name_average_age": province_name_average_age, + "province_evacuation_hatching_percent": province_evacuation_hatching_percent + } + return Response(result, status=status.HTTP_200_OK) + + +class TransportingReportDashboardViewSet(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False, Province__isnull=False).select_related('hatching') + serializer_class = TransportingReportDashboard + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + filters = {} + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + location = request.GET.get('location') + + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + transports = self.queryset.filter(**filters) + if location: + transports = transports.filter( + Q(City__icontains=location) | Q(Province__icontains=location) + ) + + average_age_killing = transports.aggregate(average_age=Avg('Age'))['average_age'] + + minimum_maximum_age_killing = transports.filter(Age__lte=70, Age__gte=0).aggregate(minimum_age=Min('Age'), + maximum_age=Max('Age')) + active_hatching = \ + transports.filter(Age__lte=70, Age__gte=0).aggregate(good_count=Sum('hatching__ChickCountSum'))[ + 'good_count'] or 0 + + average_age_killing_province = transports.values( + 'Province').annotate(average_age=Avg('Age')).order_by('-average_age') + + for age in average_age_killing_province: + age['average_age'] = int(age['average_age']) if age['average_age'] is not None else 0 + + hatching_killing_province = transports.values( + 'Province').annotate( + chick_sum=Sum('hatching__ChickCountSum')).order_by( + '-chick_sum') + + country_hatching = transports.aggregate( + good_count=Sum('hatching__ChickCountSum') + )['good_count'] or 0 + + killing_name_hatching = transports.filter(DesUnitName__isnull=False).values( + 'DesUnitName').annotate( + good_amount=Sum('GoodAmount')).order_by( + '-good_amount')[:15] + + maximum_killing_province = transports.values( + 'Province').annotate(sum_killing=Sum('GoodAmount')).order_by('-sum_killing').first() + + result = { + 'average_age_killing': int(average_age_killing) if average_age_killing is not None else 0, + 'minimum_maximum_age_killing': minimum_maximum_age_killing, + 'average_age_killing_province': average_age_killing_province, + 'hatching_killing_province': hatching_killing_province, + 'killing_name_hatching': killing_name_hatching, + 'active_hatching': active_hatching, + 'country_hatching': country_hatching, + 'transport_car_count': transports.count(), + 'maximum_killing_province': maximum_killing_province, + } + return Response(result, status=status.HTTP_200_OK) + + +class TransportingAnalysisViewSet(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False, Province__isnull=False) + serializer_class = TransportingSerializer + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + qs = self.queryset + + total_killing_province = qs.values('Province').annotate(total_good_amount=Sum('GoodAmount')) + total_killing_dict = {item['Province']: item['total_good_amount'] for item in total_killing_province} + + total_good_amount_in_and_out = qs.values('Province', 'DesUnitName').annotate( + total_good_amount=Sum('GoodAmount') + ) + + total_max_amount = {} + total_min_amount = {} + max_unit_name_in_and_out = {} + min_unit_name_in_and_out = {} + for item in total_good_amount_in_and_out: + province = item['Province'] + amount = item['total_good_amount'] + unit_name = item['DesUnitName'] + if province not in total_max_amount or amount > total_max_amount[province]: + total_max_amount[province] = amount + max_unit_name_in_and_out[province] = unit_name + + if province not in total_min_amount or amount < total_min_amount[province]: + total_min_amount[province] = amount + min_unit_name_in_and_out[province] = unit_name + + all_data = qs.filter(Out=True).values('Province', 'DesUnitName').annotate( + total_good_amount=Sum('GoodAmount') + ) + + unit_lookup = {} + for item in all_data: + province = item['Province'] + unit_name = item['DesUnitName'] + total_good_amount = item['total_good_amount'] + + if province not in unit_lookup: + unit_lookup[province] = [] + + unit_lookup[province].append({ + 'unit_name': unit_name, + 'total_good_amount': total_good_amount + }) + + result = [] + for province in total_killing_dict.keys(): + out_units = unit_lookup.get(province, []) + if out_units: + max_unit = max(out_units, key=lambda x: x['total_good_amount']) + min_unit = min(out_units, key=lambda x: x['total_good_amount']) + max_unit_name = max_unit['unit_name'] + max_unit_amount = max_unit['total_good_amount'] + min_unit_name = min_unit['unit_name'] + min_unit_amount = min_unit['total_good_amount'] + else: + max_unit_name = None + max_unit_amount = 0 + min_unit_name = None + min_unit_amount = 0 + + result.append({ + "province": province, + "max_out_province_slaughterhouse": max_unit_name, + "max_out_amount": max_unit_amount, + "min_out_province_slaughterhouse": min_unit_name, + "min_out_amount": min_unit_amount, + "total_killing_province": total_killing_dict.get(province, 0), + "total_max_amount": total_max_amount.get(province, 0), + "total_min_amount": total_min_amount.get(province, 0), + "total_max_amount_unit_name": max_unit_name_in_and_out.get(province), + "total_min_amount_unit_name": min_unit_name_in_and_out.get(province), + }) + + return Response(result, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def get_transport_to_kill(request): + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + filters = {"trash": False} + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['issue_date__date__gte'] = date1 + filters['issue_date__date__lte'] = date2 + transports = TransportingChickenDetail.objects.filter(**filters) + total_amount = build_calculation(queryset=transports, column_name='GoodAmount', aggregate_func=Sum) + return Response({"total_amount": total_amount, + 'len_transports': transports.count() + }, status=status.HTTP_200_OK) + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def add_kill_house(request): + file = request.FILES['file'].read() + wb_obj = openpyxl.load_workbook(filename=BytesIO(file)) + sheet = wb_obj.active + list1 = [] + for i, row in enumerate(sheet.iter_rows(values_only=True)): + if i < 1 or row is None: + continue + PartIdCode = row[0] + UnitName = row[1] + City = row[2] + Province = row[3] + Province_id = row[4] + if not KillHouse.objects.filter(PartIdCode=PartIdCode, trash=False): + kill_house = KillHouse( + PartIdCode=PartIdCode, + UnitName=UnitName, + Province=Province.rstrip(), + City=City.rstrip(), + ProvinceId=Province_id + ) + kill_house.save() + + # print(date.date()) + # for kill in kill_req: + # if kill.poultry_name == poultry and kill.quantity== quantity and \ + # kill.live_weight== wieght and kill.date.date() ==date and kill.acceptor_rejector == accepterde: + # print(kill.id) + return HttpResponse(list1) + + +@api_view(["GET"]) +@permission_classes([AllowAny]) +@csrf_exempt +def update_hatching(request): + filters = {} + province = request.GET.get('province') + if province == 'ha': + filters['ProvinceName'] = 'همدان' + + elif province == 'ma': + filters['ProvinceName'] = 'مرکزی' + elif province == 'ku': + filters['ProvinceName'] = 'کردستان' + else: + return Response({'result':'شهر اشتباه است'}, status=status.HTTP_403_FORBIDDEN) + + hatching = Hatching.objects.filter(**filters, trash=False, Age__lte=150) + ser_data = HatchingForUpdateSerializer(hatching, many=True).data + return Response(ser_data, status=status.HTTP_200_OK) + + +@api_view(["GET"]) +@permission_classes([AllowAny]) +@csrf_exempt +def get_breeds(request): + BREED_STANDARDIZATION = { + 'آربراکرز (آ��لاس)': 'آربراکرز (آپلاس)', + 'آربراک��ز (آپلاس)': 'آربراکرز (آپلاس)', + 'آربر��کرز (آپلاس)': 'آربراکرز (آپلاس)', + 'را��': 'راس', + 'ر��س': 'راس', + '��اس': 'راس', + 'آ��ین': 'آرین', + 'آر��ن': 'آرین', + 'ایندین ریو��': 'ایندین ریور', + 'ایند��ن ریور': 'ایندین ریور', + 'ک��ب': 'کاب' + } + + hatchings = Hatching.objects.filter( + trash=False, + PedigreeName__in=list(BREED_STANDARDIZATION.keys()) + ).only('id', 'PedigreeName') + + updated_count = 0 + + for hatching in hatchings: + original_name = hatching.PedigreeName + + if original_name in BREED_STANDARDIZATION: + hatching.PedigreeName = BREED_STANDARDIZATION[original_name] + hatching.save(update_fields=['PedigreeName']) + updated_count += 1 + + return Response({ + 'status': 'success', + 'updated_records': updated_count, + 'skipped_records': len(hatchings) - updated_count, + 'message': f'Updated {updated_count} records. Skipped {len(hatchings) - updated_count}.' + }) + + +@api_view(["GET"]) +@permission_classes([AllowAny]) +@csrf_exempt +def dashboard_total_kill_house(request): + filterset_class = KillHouseFilterSet + search = request.GET.get('search') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + filters = {"trash": False} + + if province := request.GET.get('province'): + filters['Province'] = province + + if city := request.GET.get('city'): + filters['City'] = city + + if kill_houses_name := request.GET.get('name'): + filters['UnitName'] = kill_houses_name + + kill_houses = KillHouse.objects.filter(**filters).order_by('id') + + if search: + if search != 'undefined' and search.strip(): + kill_houses = kill_houses.filter( + 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, + "bars": 0, + "total_bars_quantity": 0, + "total_bars_output_count": 0, + "total_bars_input_count": 0, + "total_input_bars_quantity": 0, + "total_output_bars_quantity": 0, + "top_kill_house_name": None, + "top_kill_house_amount": None, + "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, + trash=False, + product='مرغ زنده -جهت كشتار' + ).only('jihadi_destination', 'quantity', 'out', 'date', 'unloading_date') + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(Date__date__gte=date1, Date__date__lte=date2) + all_products_transport = all_products_transport.filter( + 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} + for k, v in sorted(stats_dict.items(), key=lambda x: x[1], reverse=True) + ] + + top_kill_house_info = None + low_kill_house_info = None + if kill_house_stats: + top_stat = kill_house_stats[0] + low_stat = kill_house_stats[-1] + + # بهینه‌سازی: یک 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, + "amount": top_stat['total_amount'] + } + + if low_kill_house: + low_kill_house_info = { + "name": low_kill_house.UnitName, + "amount": low_stat['total_amount'] + } + + aggregation_bars = bars.aggregate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id') + ) + + total_count = (aggregation_bars['total_count'] or 0) + (aggregation_all_products['total_count'] or 0) + total_bars_quantity = (aggregation_bars['total'] or 0) + (aggregation_all_products['total'] or 0) + total_input_bars_quantity = (aggregation_bars['input_total'] or 0) + (aggregation_all_products['input_total'] or 0) + total_output_bars_quantity = (aggregation_bars['output_total'] or 0) + (aggregation_all_products['output_total'] or 0) + input_count = (aggregation_bars['input_count'] or 0) + (aggregation_all_products['input_count'] or 0) + output_count = (aggregation_bars['output_count'] or 0) + (aggregation_all_products['output_count'] or 0) + + return Response({ + "killHouseCount": len(part_id_codes), + "bars": total_count, + "total_bars_quantity": total_bars_quantity, + "total_bars_output_count": output_count, + "total_bars_input_count": input_count, + "total_input_bars_quantity": total_input_bars_quantity, + "total_output_bars_quantity": total_output_bars_quantity, + "top_kill_house_name": top_kill_house_info.get('name') if top_kill_house_info else None, + "top_kill_house_amount": top_kill_house_info.get('amount') if top_kill_house_info else None, + "low_kill_house_name": low_kill_house_info.get('name') if low_kill_house_info else None, + "low_kill_house_amount": low_kill_house_info.get('amount') if low_kill_house_info else None, + + }) + + +class HatchingAnalysisOverviewViewSet(viewsets.ModelViewSet): + queryset = Hatching.objects.filter(trash=False, poultry__isnull=False, PedigreeName__isnull=False, + + ) + serializer_class = HatchingAnalysisSerializer + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + filters = {} + pedigree = request.GET.get('pedigree') + city = request.GET.get('city') + province = request.GET.get('province') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + state = request.GET.get('state') + + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['Date__date__gte'] = date1 + filters['Date__date__lte'] = date2 + if city: + filters['CityName__icontains'] = city + if province: + filters['ProvinceName__icontains'] = province + if pedigree: + filters['PedigreeName__icontains'] = pedigree + if state == 'active': + filters['Age__lte'] = 70 + + hatchings = self.queryset.filter(**filters) + + kill_houses_overview = hatchings.filter(transport_hatching__DesUnitName__isnull=False).values( + 'transport_hatching__DesUnitName', 'PedigreeName' + ).annotate( + total_amount=Sum('transport_hatching__GoodAmount') + ).order_by('-total_amount') + + hatching_total_poultry_overview = hatchings.filter(poultry__UnitName__isnull=False).values('poultry__UnitName', + 'PedigreeName').annotate( + chick_count=Sum('ChickCountSum') + ).order_by('-chick_count') + + evacuation_total_poultry_overview = hatchings.filter(poultry__UnitName__isnull=False).values( + 'poultry__UnitName', 'PedigreeName').annotate( + evacuation=Sum('Evacuation') + ).order_by('-evacuation') + + kill_house_total = defaultdict(int) + kill_house_total_pedigrees = defaultdict(list) + hatching_total = defaultdict(int) + hatching_total_pedigrees = defaultdict(list) + evacuation_total = defaultdict(int) + evacuation_total_pedigrees = defaultdict(list) + + for item in kill_houses_overview: + kill_house_name = item['transport_hatching__DesUnitName'] + pedigree_name = item['PedigreeName'] + total_amount = item['total_amount'] or 0 + kill_house_total[kill_house_name] += total_amount + kill_house_total_pedigrees[kill_house_name].append({pedigree_name: total_amount}) + + max_kill_house_name = max(kill_house_total, key=kill_house_total.get) + min_kill_house_name = min(kill_house_total, key=kill_house_total.get) + + for data in hatching_total_poultry_overview: + poultry_unit_name = data['poultry__UnitName'] + pedigree_name = data['PedigreeName'] + chick_count_sum = data['chick_count'] or 0 + hatching_total[poultry_unit_name] += chick_count_sum + hatching_total_pedigrees[poultry_unit_name].append({pedigree_name: chick_count_sum}) + + max_poultry_unit_name = max(hatching_total, key=hatching_total.get) + min_poultry_unit_name = min(hatching_total, key=hatching_total.get) + + for info in evacuation_total_poultry_overview: + poultry_unit_name = info['poultry__UnitName'] + pedigree_name = info['PedigreeName'] + evacuation_sum = info['evacuation'] or 0 + evacuation_total[poultry_unit_name] += evacuation_sum + evacuation_total_pedigrees[poultry_unit_name].append({pedigree_name: evacuation_sum}) + + max_evacuation_total_poultry = max(evacuation_total, key=evacuation_total.get) + min_evacuation_total_poultry = min(evacuation_total, key=evacuation_total.get) + + overview = { + "kill_house": { + "max": { + "name": max_kill_house_name, + "total_amount": kill_house_total[max_kill_house_name], + "pedigrees": kill_house_total_pedigrees[max_kill_house_name] + }, + "min": { + "name": min_kill_house_name, + "total_amount": kill_house_total[min_kill_house_name], + "pedigrees": kill_house_total_pedigrees[min_kill_house_name] + } + }, + "hatching_poultry": { + "max": { + "name": max_poultry_unit_name, + "total_chick_count": hatching_total[max_poultry_unit_name], + "pedigrees": hatching_total_pedigrees[max_poultry_unit_name] + }, + "min": { + "name": min_poultry_unit_name, + "total_chick_count": hatching_total[min_poultry_unit_name], + "pedigrees": hatching_total_pedigrees[min_poultry_unit_name] + } + }, + "evacuation_poultry": { + "max": { + "name": max_evacuation_total_poultry, + "total_evacuation": evacuation_total[max_evacuation_total_poultry], + "pedigrees": evacuation_total_pedigrees[max_evacuation_total_poultry] + }, + "min": { + "name": min_evacuation_total_poultry, + "total_evacuation": evacuation_total[min_evacuation_total_poultry], + "pedigrees": evacuation_total_pedigrees[min_evacuation_total_poultry] + } + } + } + + result = { + "overview": overview + } + return Response(result, status=status.HTTP_200_OK) + + +class TransportingDetailCustomViewSet(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False) + serializer_class = TransportingDetailSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportingDetailCustomFilterSet + + def list(self, request, *args, **kwargs): + transports = self.filter_queryset(self.get_queryset()) + search = request.GET.get('search') + if search: + if search != 'undefined' and search.strip(): + transports = transports.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(transports) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(transports, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([AllowAny]) +@csrf_exempt +def send_different_bar(request): + filters = {'trash': False} + filters_province = {'trash': False} + filters_bar = {'trash': False} + province = request.GET.get('province') + if province: + if province == 'ha': + filters['poultry__LocationNameProvince'] = 'همدان' + filters_province['poultry__Province'] = 'همدان' + elif province == 'ma': + filters['poultry__LocationNameProvince'] = 'مرکزی' + filters_province['poultry__Province'] = 'مرکزی' + elif province == 'ku': + filters['poultry__LocationNameProvince'] = 'کردستان' + filters_province['poultry__Province'] = 'کردستان' + else: + filters['poultry__LocationNameProvince'] = 'بوشهر' + filters_province['poultry__Province'] = 'بوشهر' + + if request.GET.get('date1') != 'None': + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + filters_bar['Date__date__gte'] = date1 + filters_bar['Date__date__lte'] = date2 + + poultry = Hatching.objects.filter(Q(**filters) | Q(**filters_province)) + bar = TransportingDetail.objects.filter(**filters_bar, hatching__in=poultry, TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری' + )).exclude( + TrackingCode__in=request.data + ).order_by('-Date') + quarantine_code = bar.values_list('TrackingCode', flat=True).distinct() + bar = bar.filter(TrackingCode__in=quarantine_code).order_by('-Date') + ser_data = TransportingForClearanceCodeSerializer(bar, many=True).data + return Response(ser_data) + + +class ApiSendDifferentBar(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False) + serializer_class = TransportingForClearanceCodeSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportingDetailFilterSet + + def list(self, request, *args, **kwargs): + filters = {'trash': False} + filters_bar = {'trash': False} + province = request.GET.get('province') + if province == 'ha': + filters['poultry__LocationNameProvince'] = 'همدان' + elif province == 'ma': + filters['poultry__LocationNameProvince'] = 'مرکزی' + elif province == 'ku': + filters['poultry__LocationNameProvince'] = 'کردستان' + else: + filters['poultry__LocationNameProvince'] = 'بوشهر' + if request.GET.get('date1') != 'None': + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + filters_bar['Date__date__gte'] = date1 + filters_bar['Date__date__lte'] = date2 + + poultry = Hatching.objects.filter(**filters) + bar = TransportingDetail.objects.filter(**filters_bar, hatching__in=poultry, TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری' + )).exclude( + TrackingCode__in=request.data + ).order_by('-Date') + quarantine_code = bar.values_list('TrackingCode', flat=True).distinct() + bar = bar.filter(TrackingCode__in=quarantine_code).order_by('-Date') + search = request.GET.get('search') + value = request.GET.get('value') + if search: + if search != 'undefined' and value.strip(): + bar = bar.filter( + build_query(self.filterset_class.Meta.fields, value) + ) + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(bar) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + ser_data = TransportingForClearanceCodeSerializer(bar, many=True).data + return Response(ser_data) + + +class ApkInfoViewSet(viewsets.ModelViewSet): + queryset = ApkInfo.objects.filter(trash=False) + serializer_class = ApkInfoSerializer + permission_classes = [AllowAny] + + def get_object(self): + return self.queryset.first() + + def list(self, request, *args, **kwargs): + instance = ApkInfo.objects.filter(trash=False).first() + serializer = self.serializer_class(instance) + return Response(serializer.data, status=status.HTTP_200_OK) + + def update(self, request, *args, **kwargs): + instance = ApkInfo.objects.filter(trash=False).first() + serializer = self.serializer_class(instance, data=request.data, partial=True) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + + +RASADYAR_ENDPOINT = 'https://s3.rasadyar.com' +RASADYAR_BUCKET_NAME = 'rasadyar' +RASADYAR_ACCESS_KEY = "zG3ewsbYsTqCmuws" +RASADYAR_SECRET_KEY = 'RInUMB78zlQZp6CNf8+sRoSh2cNDHcGQhXrLnTJ1AuI=' + + +def upload_to_liara(image, name): + s3 = boto3.client( + 's3', + endpoint_url=RASADYAR_ENDPOINT, + aws_access_key_id=RASADYAR_ACCESS_KEY, + aws_secret_access_key=RASADYAR_SECRET_KEY + ) + s3.upload_fileobj( + image, + RASADYAR_BUCKET_NAME, + name, + ExtraArgs={'ACL': 'public-read'} + ) + return f"{RASADYAR_ENDPOINT}/{RASADYAR_BUCKET_NAME}/{name}" + + +class RasadyarAppInfoViewSet(viewsets.ModelViewSet): + queryset = RasadyarAppInfo.objects.filter(trash=False) + serializer_class = RasadyarAppInfoSerializer + permission_classes = [AllowAny] + + def get_object(self): + return self.queryset.first() + + def list(self, request, *args, **kwargs): + instance = RasadyarAppInfo.objects.filter(trash=False).first() + if not instance: + instance = RasadyarAppInfo.objects.create() + serializer = self.serializer_class(instance) + return Response(serializer.data, status=status.HTTP_200_OK) + + def create(self, request, *args, **kwargs): + instance = RasadyarAppInfo.objects.filter(trash=False).first() + if not instance: + instance = RasadyarAppInfo() + + if 'file' in request.FILES: + ran = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15)) + + file_obj = request.FILES.get('file') + file_name = file_obj.name + file_extension = file_name.split('.')[-1] if '.' in file_name else '' + file_name = f"{ran}.{file_extension}" + file_url = upload_to_liara(file_obj, file_name) + instance.file = file_url + if 'info' in request.data: + info_data = request.data.get('info') + if isinstance(info_data, str): + try: + instance.info = json.loads(info_data) + except json.JSONDecodeError: + instance.info = info_data + else: + instance.info = info_data + + instance.save() + serializer = self.serializer_class(instance) + return Response(serializer.data, status=status.HTTP_201_CREATED) + + def update(self, request, *args, **kwargs): + instance = RasadyarAppInfo.objects.filter(trash=False).first() + if not instance: + instance = RasadyarAppInfo() + + if 'file' in request.FILES: + 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 + + if 'info' in request.data: + info_data = request.data.get('info') + if isinstance(info_data, str): + try: + instance.info = json.loads(info_data) + except json.JSONDecodeError: + instance.info = info_data + else: + instance.info = info_data + + instance.save() + serializer = self.serializer_class(instance) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([AllowAny]) +@csrf_exempt +def send_different_bar_with_licence_number(request): + filters_bar = {'trash': False} + if request.GET.get('date1') != 'None': + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + filters_bar['Date__date__gte'] = date1 + filters_bar['Date__date__lte'] = date2 + + hatching = Hatching.objects.filter(RequestCode=request.GET['licence_number']) + + bar = TransportingDetail.objects.filter(**filters_bar, hatching__in=hatching, TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری' + )).order_by('-Date') + ser_data = TransportingForClearanceCodeSerializer(bar, many=True).data + return Response(ser_data) + + +class TransportCarcassDetailViewSet(viewsets.ModelViewSet): + queryset = TransportCarcassDetail.objects.filter(trash=False) + serializer_class = TransportCarcassDetailSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportCarcassDetailFilterSet + + def list(self, request, *args, **kwargs): + search = request.GET.get('search') + + type_role = request.GET.get('role') + province = request.GET.get('province') + + if province == 'undefined': + province = None + if 'code' in request.GET: + 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, + product='گوشت مرغ تازه', + jihadi_origin=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() + query_carcass = query_carcass.filter( + Q( + product_date__gte=date1, + product_date__lte=date2, + product_date__isnull=False + ) | + Q( + date__gte=date1, + date__lte=date2, + product_date__isnull=True + ) + ) + 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( + build_query(self.filterset_class.Meta.fields, search) + ) + # اعمال search روی AllProductsTransport + 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: + return obj.product_date + elif hasattr(obj, 'date') and obj.date: + return obj.date + 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] + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + # Pagination روی list + paginator = self.pagination_class() + page = paginator.paginate_queryset(sorted_objects, request) + + if page is not None: + # Serialize هر object با serializer مناسب + serialized_data = [] + for obj in page: + if hasattr(obj, 'product_date'): # TransportCarcassDetail + serializer = TransportCarcassDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: # AllProductsTransport + # تبدیل به dict و اضافه کردن فیلدهای مشترک + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + # اضافه کردن فیلدهای مشابه TransportCarcassDetail برای سازگاری + data['product_date'] = obj.date + data['id_quarantineh'] = obj.record_id + serialized_data.append(data) + return paginator.get_paginated_response(serialized_data) + + # اگر pagination نبود + serialized_data = [] + for obj in sorted_objects: + if hasattr(obj, 'product_date'): # TransportCarcassDetail + serializer = TransportCarcassDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: # AllProductsTransport + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + data['product_date'] = obj.date + data['id_quarantineh'] = obj.record_id + serialized_data.append(data) + return Response(serialized_data, status=status.HTTP_200_OK) + if type_role: + if type_role == 'KillHouse': + filters_kill_house = {} + if province: + filters_kill_house['Province'] = province + + kill_house_filterset_class = KillHouseFilterSet + kill_house = KillHouse.objects.filter(**filters_kill_house).order_by('id') + + if search and search != 'undefined' and search.strip(): + kill_house = kill_house.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + bars = TransportCarcassDetail.objects.filter(trash=False) + buy_bars = TransportingDetail.objects.filter(trash=False, Date__date__gte='2025-03-21', + TrackingStatusDescription__in=("تایید تخلیه",'بارگیری')) + all_products_transport_carcass = AllProductsTransport.objects.filter(trash=False, product='گوشت مرغ تازه',jihadi_origin__in=kill_house.values_list('PartIdCode', flat=True)) + all_products_transport = AllProductsTransport.objects.filter(trash=False, product='مرغ زنده -جهت كشتار',jihadi_destination__in=kill_house.values_list('PartIdCode', flat=True)) + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(Q(product_date__gte=date1, product_date__lte=date2, product_date__isnull=False) | + Q(date__gte=date1, date__lte=date2, product_date__isnull=True)) + all_products_transport_carcass = all_products_transport_carcass.filter( + date__gte=date1, date__lte=date2, date__isnull=False + ) + date_1_for_buy_bars = date1 - datetime.timedelta(days=1) + date_2_for_buy_bars = date2 - datetime.timedelta(days=1) + buy_bars = buy_bars.filter(Date__date__gte=date_1_for_buy_bars, Date__date__lte=date_2_for_buy_bars) + all_products_transport = all_products_transport.filter( + date__gte=date_1_for_buy_bars, date__lte=date_2_for_buy_bars, date__isnull=False + ) + + + bars_summary = bars.values('jihadi_origin').annotate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + all_products_transport_carcass_summary = all_products_transport_carcass.values('jihadi_origin').annotate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + buy_summary = buy_bars.values('DesPartIdCode').annotate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id'), + ) + + all_products_transport_summary = all_products_transport.values('jihadi_destination').annotate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + # ادغام bars_summary و all_products_transport_carcass_summary + bars_dict = {row['jihadi_origin']: row for row in bars_summary if row.get('jihadi_origin')} + for row in all_products_transport_carcass_summary: + key = row.get('jihadi_origin') + if not key: + continue + if key in bars_dict: + bars_dict[key]['total'] = (bars_dict[key].get('total', 0) or 0) + (row.get('total', 0) or 0) + bars_dict[key]['input_total'] = (bars_dict[key].get('input_total', 0) or 0) + (row.get('input_total', 0) or 0) + bars_dict[key]['output_total'] = (bars_dict[key].get('output_total', 0) or 0) + (row.get('output_total', 0) or 0) + bars_dict[key]['input_count'] = (bars_dict[key].get('input_count', 0) or 0) + (row.get('input_count', 0) or 0) + bars_dict[key]['output_count'] = (bars_dict[key].get('output_count', 0) or 0) + (row.get('output_count', 0) or 0) + bars_dict[key]['total_count'] = (bars_dict[key].get('total_count', 0) or 0) + (row.get('total_count', 0) or 0) + else: + bars_dict[key] = row + + # ادغام buy_summary و all_products_transport_summary + buy_dict = {row['DesPartIdCode']: row for row in buy_summary if row.get('DesPartIdCode')} + for row in all_products_transport_summary: + key = row.get('jihadi_destination') # jihadi_destination همان DesPartIdCode است + if not key: + continue + if key in buy_dict: + buy_dict[key]['total'] = (buy_dict[key].get('total', 0) or 0) + (row.get('total', 0) or 0) + buy_dict[key]['input_total'] = (buy_dict[key].get('input_total', 0) or 0) + (row.get('input_total', 0) or 0) + buy_dict[key]['output_total'] = (buy_dict[key].get('output_total', 0) or 0) + (row.get('output_total', 0) or 0) + buy_dict[key]['input_count'] = (buy_dict[key].get('input_count', 0) or 0) + (row.get('input_count', 0) or 0) + buy_dict[key]['output_count'] = (buy_dict[key].get('output_count', 0) or 0) + (row.get('output_count', 0) or 0) + buy_dict[key]['total_count'] = (buy_dict[key].get('total_count', 0) or 0) + (row.get('total_count', 0) or 0) + else: + # تبدیل jihadi_destination به DesPartIdCode برای سازگاری + buy_dict[key] = { + 'DesPartIdCode': key, + 'total': row.get('total', 0) or 0, + 'input_total': row.get('input_total', 0) or 0, + 'output_total': row.get('output_total', 0) or 0, + 'input_count': row.get('input_count', 0) or 0, + 'output_count': row.get('output_count', 0) or 0, + 'total_count': row.get('total_count', 0) or 0, + } + + kill_house = list(kill_house) + kill_house.sort( + key=lambda kh: (bars_dict.get(kh.PartIdCode, {}) or {}).get('total', 0) or 0, + reverse=True + ) + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(kill_house) + if page is not None: + serializer = KillHouseForTransportCarcassSerializer( + page, many=True, context={'request': request, 'bars_dict': bars_dict, 'buy_dict': buy_dict} + ) + return self.get_paginated_response(serializer.data) + + serializer = KillHouseForTransportCarcassSerializer( + kill_house, many=True, context={'request': request, 'bars_dict': bars_dict, 'buy_dict': buy_dict} + ) + return Response(serializer.data, status=status.HTTP_200_OK) + + + else: + filters_steward = {} + if province: + filters_steward['province'] = province + + steward_filterset_class = GuildsFilterSet + steward = Guilds.objects.filter(**filters_steward, trash=False, is_steward=True).order_by('id') + + if search and search != 'undefined' and search.strip(): + steward = steward.filter( + build_query(steward_filterset_class.Meta.fields, search) + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + bars = TransportCarcassDetail.objects.filter(trash=False).order_by('-product_date') + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + + + bars_summary = bars.values('jihadi_origin', 'jihadi_destination').annotate( + total=Sum('quantity', filter=Q(jihadi_origin=F('jihadi_origin'))), + input_total=Sum('quantity', filter=Q(out=False, jihadi_origin=F('jihadi_origin'))), + output_total=Sum('quantity', filter=Q(out=True, jihadi_origin=F('jihadi_origin'))), + input_count=Count('id', filter=Q(out=False, jihadi_origin=F('jihadi_origin'))), + output_count=Count('id', filter=Q(out=True, jihadi_origin=F('jihadi_origin'))), + total_count=Count('id', filter=Q(jihadi_origin=F('jihadi_origin'))), + + total_input_buy_bars_wight=Sum('quantity', + filter=Q(out=False, jihadi_destination=F('jihadi_destination'))), + total_input_buy_bars_count=Count('id', + filter=Q(out=False, jihadi_destination=F('jihadi_destination'))), + total_output_buy_bars_wight=Sum('quantity', + filter=Q(out=True, jihadi_destination=F('jihadi_destination'))), + total_output_buy_bars_count=Count('id', + filter=Q(out=True, jihadi_destination=F('jihadi_destination'))), + ) + + bars_dict = {} + for row in bars_summary: + code = row['jihadi_origin'] or row['jihadi_destination'] + if code: + bars_dict[code] = row + + steward = list(steward) + steward.sort( + key=lambda s: (bars_dict.get(s.jihadi_code, {}) or {}).get('total', 0) or 0, + reverse=True + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(steward) + if page is not None: + serializer = StewardForTransportCarcassSerializer( + page, many=True, context={'request': request, 'bars_dict': bars_dict} + ) + return self.get_paginated_response(serializer.data) + + serializer = StewardForTransportCarcassSerializer( + steward, many=True, context={'request': request, 'bars_dict': bars_dict} + ) + return Response(serializer.data, status=status.HTTP_200_OK) + + return Response('ok', status=status.HTTP_200_OK) + + def create(self, request, *args, **kwargs): + file = request.FILES['file'].read() + wb_obj = openpyxl.load_workbook(filename=BytesIO(file)) + sheet = wb_obj.active + + # گرفتن مقادیر اولیه برای چک کردن وجود داشتن + kill_house_code = set( + KillHouse.objects.only('PartIdCode').values_list('PartIdCode', flat=True) + ) + steward_jihadi_code = set( + Guilds.objects.filter(trash=False, is_steward=True).values_list('jihadi_code', flat=True) + ) + + headers = [str(cell).strip() for cell in next(sheet.iter_rows(values_only=True))] + + field_map = { + "id": "id_quarantineh", + "مقصد قبلی": "destination_prev", + "تغییر مقصد": "destination_changed", + "پرداخت": "payment", + "رهگیری": "tracking", + "تاریخ": "date", + "ساعت": "time", + "محصول": "product", + "اقلام": "items", + "مقدار": "quantity", + "واحد": "unit", + "استان مبدا": "origin_province", + "شهرستان مبدا": "origin_city", + "مبدا": "origin", + "استان مقصد": "destination_province", + "شهرستان مقصد": "destination_city", + "مقصد": "destination", + "ش جهادی مبدا": "jihadi_origin", + "ش جهادی مقصد": "jihadi_destination", + "مالک": "owner", + "کد رهگیری خودرو": "car_tracking_code", + "نام راننده": "driver_name", + "پلاک": "plate", + "مبلغ": "amount", + "تخلیه": "unloading", + "وزن پر": "gross_weight", + "وزن خالی": "tare_weight", + "وزن": "net_weight", + "کد باسکول": "scale_code", + "نام باسکول": "scale_name", + "قبض باسکول": "scale_receipt", + "تاریخ تخلیه": "unloading_date", + "Out": "out", + } + + out_flag = True if request.data.get('out') == 'true' else False + + bulk_guilds_create = [] + bulk_records_create = [] + record_updates = {} + + for row in sheet.iter_rows(min_row=2, values_only=True): + if not row: + continue + + row_data = dict(zip(headers, row)) + tracking_val = row_data.get("رهگیری") + if not tracking_val: + continue + + steward_code = row_data.get("ش جهادی مبدا") + guilds_code = row_data.get("ش جهادی مقصد") + + # گیلد مبدا + if steward_code and steward_code not in kill_house_code and steward_code not in steward_jihadi_code: + bulk_guilds_create.append(Guilds( + jihadi_code=steward_code, + name=row_data.get("مبدا"), + city=row_data.get("شهرستان مبدا"), + province=row_data.get("استان مبدا"), + is_steward=True + )) + steward_jihadi_code.add(steward_code) + + # گیلد مقصد + if guilds_code and guilds_code not in kill_house_code and guilds_code not in steward_jihadi_code: + bulk_guilds_create.append(Guilds( + jihadi_code=guilds_code, + name=row_data.get("مقصد"), + city=row_data.get("شهرستان مقصد"), + province=row_data.get("استان مقصد"), + is_steward=False + )) + steward_jihadi_code.add(guilds_code) + + record_data = {} + 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): + y, m, d = map(int, value.split("/")) + value = convert_to_miladi(y, m, d) + elif hasattr(value, "year"): + value = convert_to_miladi(value.year, value.month, value.day) + except: + value = None + + if model_field == "out": + record_data[model_field] = out_flag + else: + record_data[model_field] = value + + record_updates[tracking_val] = record_data + + # ذخیره گیلدها + if bulk_guilds_create: + Guilds.objects.bulk_create(bulk_guilds_create, ignore_conflicts=True) + + # بررسی رکوردهای موجود + existing_trackings = set( + TransportCarcassDetail.objects.filter( + tracking__in=record_updates.keys() + ).values_list('tracking', flat=True) + ) + + for tracking_val, data in record_updates.items(): + data["out"] = out_flag + if tracking_val in existing_trackings: + TransportCarcassDetail.objects.filter(tracking=tracking_val).update(**data) + else: + data["tracking"] = tracking_val + bulk_records_create.append(TransportCarcassDetail(**data)) + + if bulk_records_create: + TransportCarcassDetail.objects.bulk_create(bulk_records_create) + + return Response({'result': 'ok'}, status=status.HTTP_201_CREATED) + + +class DriveViewSet(viewsets.ModelViewSet): + queryset = Driver.objects.filter(trash=False) + serializer_class = DriverSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = DriverFilterSet + + def list(self, request, *args, **kwargs): + if 'code' in request.GET: + query = self.queryset.filter(tracking_code__regex=r'^\d{7}$').only('tracking_code').values_list('tracking_code',flat=True).distinct() + return Response({'codes':query}, status=status.HTTP_200_OK) + if 'all' in request.GET: + query = self.queryset.filter(tracking_code__regex=r'^\d{7}$',trash=False,pelak__isnull=False).order_by('part_id_code') + serializer = self.serializer_class(query, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + filters = {} + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + city = request.GET.get('city') + province = request.GET.get('province') + if province == 'undefined': + province = None + if date1 and date2: + date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() + + date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() + filters['date__gte'] = date1 + filters['date__lte'] = date2 + + search = request.GET.get('search') + transports = self.queryset.filter(**filters).order_by("-date") + + if search: + if search != 'undefined' and search.strip(): + transports = transports.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(transports) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(transports, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def create(self, request, *args, **kwargs): + file = request.FILES['file'].read() + wb_obj = openpyxl.load_workbook(filename=BytesIO(file)) + sheet = wb_obj.active + headers = [str(cell).strip() for cell in next(sheet.iter_rows(values_only=True))] + + field_map = { + "کد رهگیری خودرو": "tracking_code", + # "استان مقصد": "province", + # "شهرستان مقصد": "city", + # "محصول": "product", + "مقصد": "kill_house_name", + "ش جهادی مقصد": "part_id_code", + + } + created_list = [] + + for row in sheet.iter_rows(min_row=2, values_only=True): + if row is None: + continue + + row_data = dict(zip(headers, row)) + driver_name = row_data.get("نام راننده") + + record_data = {} + for col_name, model_field in field_map.items(): + if col_name in row_data: + value = row_data[col_name] + + record_data[model_field] = value + + obj, created = Driver.objects.update_or_create( + driver_name=driver_name, + defaults=record_data, + ) + + created_list.append({ + "driver_name": obj.driver_name, + }) + + return Response({'result':'ok'},status=status.HTTP_201_CREATED) + + def update(self, request, *args, **kwargs): + tracking_code = request.data.get('tracking_code') + + driver = Driver.objects.filter( + tracking_code=tracking_code, + ).first() + if driver: + date_str = request.data.get('expire_licence_date') + expire_date = None + if date_str and isinstance(date_str, str): + try: + parts = [int(x) for x in date_str.split("/")] + if len(parts) == 3: + expire_date = convert_to_miladi(parts[0], parts[1], parts[2]) + except (ValueError, IndexError) as e: + pass + update_fields = [ + 'car_id', 'driver_name', 'owner_name', 'pelak', + 'weight', 'car_type', 'health_permit' + ] + + for field in update_fields: + if field in request.data: + setattr(driver, field, request.data[field]) + + if expire_date is not None: + driver.expire_licence_date = expire_date + + driver.save() + + return Response({'result':'ok'},status=status.HTTP_200_OK) + + +class TransportCarcassDashboardView(APIView): + permission_classes = [AllowAny] + + def get(self,request): + search = request.GET.get('search') + + type_role = request.GET.get('role') + province = request.GET.get('province') + + if province == 'undefined': + province = None + date1 = request.GET.get('date1') or None + date2 = request.GET.get('date2') or None + if type_role: + if type_role == 'KillHouse': + filters_kill_house = {} + if province: + filters_kill_house['Province'] = province + kill_house_filterset_class = KillHouseFilterSet + kill_house = KillHouse.objects.filter(**filters_kill_house).order_by('id') + if search: + if search != 'undefined' and search.strip(): + kill_house = kill_house.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + kill_house = kill_house.values_list('PartIdCode',flat=True) + bars = TransportCarcassDetail.objects.filter(jihadi_origin__in=kill_house, trash=False) + buy_bars = TransportingDetail.objects.filter(DesPartIdCode__in=kill_house, + trash=False,Date__date__gte='2025-03-21', + TrackingStatusDescription__in=("تایید تخلیه",'بارگیری')).only( + 'GoodAmount', 'Out') + all_products_transport_carcass = AllProductsTransport.objects.filter( + trash=False, + product='گوشت مرغ تازه', + jihadi_origin__in=kill_house + ) + all_products_transport = AllProductsTransport.objects.filter( + trash=False, + product='مرغ زنده -جهت كشتار', + jihadi_destination__in=kill_house + ) + + if date1: + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = bars.filter(Q(product_date__gte=date1, product_date__lte=date2, product_date__isnull=False) | + Q(date__gte=date1, date__lte=date2, product_date__isnull=True)) + all_products_transport_carcass = all_products_transport_carcass.filter( + date__gte=date1, date__lte=date2, date__isnull=False + ) + date_1_for_buy_bars = date1 - datetime.timedelta(days=1) + date_2_for_buy_bars = date2 - datetime.timedelta(days=1) + buy_bars = buy_bars.filter(Date__date__gte=date_1_for_buy_bars, Date__date__lte=date_2_for_buy_bars) + all_products_transport = all_products_transport.filter( + date__gte=date_1_for_buy_bars, date__lte=date_2_for_buy_bars, date__isnull=False + ) + + aggregation = bars.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + + ) + all_products_transport_carcass_aggregation = all_products_transport_carcass.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + buy_aggregation = buy_bars.aggregate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + output_count=Count('id', filter=Q(Out=True)), + total_count=Count('id') + ) + all_products_transport_aggregation = all_products_transport.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + # ادغام aggregation‌ها + aggregation['total'] = (aggregation.get('total') or 0) + (all_products_transport_carcass_aggregation.get('total') or 0) + aggregation['input_total'] = (aggregation.get('input_total') or 0) + (all_products_transport_carcass_aggregation.get('input_total') or 0) + aggregation['output_total'] = (aggregation.get('output_total') or 0) + (all_products_transport_carcass_aggregation.get('output_total') or 0) + aggregation['input_count'] = (aggregation.get('input_count') or 0) + (all_products_transport_carcass_aggregation.get('input_count') or 0) + aggregation['output_count'] = (aggregation.get('output_count') or 0) + (all_products_transport_carcass_aggregation.get('output_count') or 0) + aggregation['total_count'] = (aggregation.get('total_count') or 0) + (all_products_transport_carcass_aggregation.get('total_count') or 0) + + buy_aggregation['total'] = (buy_aggregation.get('total') or 0) + (all_products_transport_aggregation.get('total') or 0) + buy_aggregation['input_total'] = (buy_aggregation.get('input_total') or 0) + (all_products_transport_aggregation.get('input_total') or 0) + buy_aggregation['output_total'] = (buy_aggregation.get('output_total') or 0) + (all_products_transport_aggregation.get('output_total') or 0) + buy_aggregation['input_count'] = (buy_aggregation.get('input_count') or 0) + (all_products_transport_aggregation.get('input_count') or 0) + buy_aggregation['output_count'] = (buy_aggregation.get('output_count') or 0) + (all_products_transport_aggregation.get('output_count') or 0) + buy_aggregation['total_count'] = (buy_aggregation.get('total_count') or 0) + (all_products_transport_aggregation.get('total_count') or 0) + + total_count = aggregation['total_count'] or 0 + total_bars_quantity = aggregation['total'] or 0 + total_input_bars_quantity = aggregation['input_total'] or 0 + total_output_bars_quantity = aggregation['output_total'] or 0 + input_bars_count = aggregation['input_count'] or 0 + output_bars_count = aggregation['output_count'] or 0 + + + if total_count > 0: + total_input_bars_percent = round( + (total_input_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, 1) + total_output_bars_percent = round( + (total_output_bars_quantity / (total_input_bars_quantity + total_output_bars_quantity)) * 100, + 1) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return Response({ + "role": 'کشتارگاه', + "product": 'مرغ گرم', + "bars": int(total_count), + "total_bars_wight": int(total_bars_quantity), + "input_bars": int(input_bars_count), + "total_input_bars_wight": int(total_input_bars_quantity), + "total_input_buy_bars_wight": int(((buy_aggregation['input_total'] or 0) * 2.5) *0.75), + "total_input_bars_percent": total_input_bars_percent, + "output_bars": int(output_bars_count), + "total_output_bars_wight": int(total_output_bars_quantity), + "total_output_buy_bars_wight": int(((buy_aggregation['output_total'] or 0) * 2.5) *0.75), + "total_output_bars_percent": total_output_bars_percent, + "total_ware_house": int((((buy_aggregation['input_total'] or 0) * 2.5) *0.75) + (((buy_aggregation['output_total'] or 0) * 2.5) *0.75)), + "total_input_buy_bars_count": buy_aggregation['input_count'] or 0, + "total_output_buy_bars_count": buy_aggregation['output_count'] or 0, + "total_count_kill_house": len(kill_house), + "last_update": self._get_last_update_date_for_dashboard(bars, all_products_transport_carcass), + + }) + + + else: + filters_steward = {} + if province: + filters_steward['province'] = province + steward = Guilds.objects.filter(**filters_steward,trash=False, is_steward=True).order_by('id') + steward_filterset_class = GuildsFilterSet + if search: + if search != 'undefined' and search.strip(): + steward = steward.filter( + build_query(steward_filterset_class.Meta.fields, search) + ) + steward = steward.values_list('jihadi_code',flat=True) + date1 = request.GET.get('date1') or None + date2 = request.GET.get('date2') or None + + bars = TransportCarcassDetail.objects.filter( + Q(jihadi_origin__in=steward) | Q(jihadi_destination__in=steward) + , trash=False).order_by('-modify_date') + all_products_transport_steward = AllProductsTransport.objects.filter( + trash=False, + product='گوشت مرغ تازه', + ).filter( + Q(jihadi_origin__in=steward) | Q(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() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + all_products_transport_steward = all_products_transport_steward.filter( + date__gte=date1, date__lte=date2, date__isnull=False + ) + + aggregation = bars.aggregate( + total=Sum('quantity', filter=Q(jihadi_origin__in=steward)), + input_total=Sum('quantity', filter=Q(out=False, jihadi_origin__in=steward)), + output_total=Sum('quantity', filter=Q(out=True, jihadi_origin__in=steward)), + input_count=Count('id', filter=Q(out=False, jihadi_origin__in=steward)), + output_count=Count('id', filter=Q(out=True, jihadi_origin__in=steward)), + total_count=Count('id', filter=Q(jihadi_origin__in=steward)), + total_input_buy_bars_wight=Sum('quantity', filter=Q(jihadi_destination__in=steward, out=False)), + total_input_buy_bars_count=Count('id', filter=Q(jihadi_destination__in=steward, out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(jihadi_destination__in=steward, out=True)), + total_output_buy_bars_count=Count('id', filter=Q(jihadi_destination__in=steward, out=True)), + total_ware_house=Sum('quantity', filter=Q(jihadi_origin__in=steward)), + + ) + all_products_transport_steward_aggregation = all_products_transport_steward.aggregate( + total=Sum('quantity', filter=Q(jihadi_origin__in=steward)), + input_total=Sum('quantity', filter=Q(out=False, jihadi_origin__in=steward)), + output_total=Sum('quantity', filter=Q(out=True, jihadi_origin__in=steward)), + input_count=Count('id', filter=Q(out=False, jihadi_origin__in=steward)), + output_count=Count('id', filter=Q(out=True, jihadi_origin__in=steward)), + total_count=Count('id', filter=Q(jihadi_origin__in=steward)), + total_input_buy_bars_wight=Sum('quantity', filter=Q(jihadi_destination__in=steward, out=False)), + total_input_buy_bars_count=Count('id', filter=Q(jihadi_destination__in=steward, out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(jihadi_destination__in=steward, out=True)), + total_output_buy_bars_count=Count('id', filter=Q(jihadi_destination__in=steward, out=True)), + total_ware_house=Sum('quantity', filter=Q(jihadi_origin__in=steward)), + ) + + # ادغام aggregation‌ها + aggregation['total'] = (aggregation.get('total') or 0) + (all_products_transport_steward_aggregation.get('total') or 0) + aggregation['input_total'] = (aggregation.get('input_total') or 0) + (all_products_transport_steward_aggregation.get('input_total') or 0) + aggregation['output_total'] = (aggregation.get('output_total') or 0) + (all_products_transport_steward_aggregation.get('output_total') or 0) + aggregation['input_count'] = (aggregation.get('input_count') or 0) + (all_products_transport_steward_aggregation.get('input_count') or 0) + aggregation['output_count'] = (aggregation.get('output_count') or 0) + (all_products_transport_steward_aggregation.get('output_count') or 0) + aggregation['total_count'] = (aggregation.get('total_count') or 0) + (all_products_transport_steward_aggregation.get('total_count') or 0) + aggregation['total_input_buy_bars_wight'] = (aggregation.get('total_input_buy_bars_wight') or 0) + (all_products_transport_steward_aggregation.get('total_input_buy_bars_wight') or 0) + aggregation['total_input_buy_bars_count'] = (aggregation.get('total_input_buy_bars_count') or 0) + (all_products_transport_steward_aggregation.get('total_input_buy_bars_count') or 0) + aggregation['total_output_buy_bars_wight'] = (aggregation.get('total_output_buy_bars_wight') or 0) + (all_products_transport_steward_aggregation.get('total_output_buy_bars_wight') or 0) + aggregation['total_output_buy_bars_count'] = (aggregation.get('total_output_buy_bars_count') or 0) + (all_products_transport_steward_aggregation.get('total_output_buy_bars_count') or 0) + aggregation['total_ware_house'] = (aggregation.get('total_ware_house') or 0) + (all_products_transport_steward_aggregation.get('total_ware_house') or 0) + + total_count = aggregation['total_count'] or 0 + total_bars_quantity = aggregation['total'] or 0 + total_input_bars_quantity = aggregation['input_total'] or 0 + total_output_bars_quantity = aggregation['output_total'] or 0 + input_bars_count = aggregation['input_count'] or 0 + output_bars_count = aggregation['output_count'] or 0 + total_input_buy_bars_wight = aggregation['total_input_buy_bars_wight'] or 0 + total_output_buy_bars_wight = aggregation['total_output_buy_bars_wight'] or 0 + total_ware_house = total_input_buy_bars_wight + total_output_buy_bars_wight + total_input_buy_bars_count = aggregation['total_input_buy_bars_count'] or 0 + total_output_buy_bars_count = aggregation['total_output_buy_bars_count'] or 0 + + if total_count > 0: + total_input_bars_percent = round((total_input_bars_quantity / (total_input_bars_quantity +total_output_bars_quantity) ) * 100, 1) + total_output_bars_percent = round((total_output_bars_quantity / (total_input_bars_quantity +total_output_bars_quantity)) * 100, 1) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return Response({ + "role": 'مباشر', + "product": 'گوشت مرغ تازه', + "bars": int(total_count), + "total_bars_wight": int(total_bars_quantity), + "input_bars": int(input_bars_count), + "total_input_bars_wight": int(total_input_bars_quantity), + "total_input_buy_bars_wight": int(total_input_buy_bars_wight), + "total_input_bars_percent": total_input_bars_percent, + "output_bars": int(output_bars_count), + "total_output_bars_wight": int(total_output_bars_quantity), + "total_output_buy_bars_wight": int(total_output_buy_bars_wight), + "total_output_bars_percent": total_output_bars_percent, + "total_ware_house": int(total_ware_house), + "total_count_steward": len(steward), + "last_update": self._get_last_update_date_for_dashboard(bars, all_products_transport_steward), + "total_input_buy_bars_count": int(total_input_buy_bars_count), + "total_output_buy_bars_count": int(total_output_buy_bars_count), + + }) + + 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 + + +class GuildsTransportCarcassViewSet(viewsets.ModelViewSet): + queryset = Guilds.objects.filter(trash=False) + serializer_class = GuildsForTransportCarcassSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportCarcassDetailFilterSet + + + def list(self, request, *args, **kwargs): + search = request.GET.get('search') + province = request.GET.get('province') + if province == 'undefined': + province = None + + if 'code' in request.GET: + 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, + 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() + query_carcass = query_carcass.filter( + Q( + product_date__gte=date1, + product_date__lte=date2, + product_date__isnull=False + ) | + Q( + date__gte=date1, + date__lte=date2, + product_date__isnull=True + ) + ) + query_all_products = query_all_products.filter( + 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) + ) + 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 + elif hasattr(obj, 'date') and obj.date: + return obj.date + 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] + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + paginator = self.pagination_class() + page = paginator.paginate_queryset(sorted_objects, request) + + if page is not None: + serialized_data = [] + for obj in page: + if hasattr(obj, 'product_date'): + serializer = TransportCarcassDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + data['product_date'] = obj.date + data['product'] = obj.product + data['quantity'] = obj.quantity + data['jihadi_destination'] = obj.jihadi_destination + serialized_data.append(data) + return paginator.get_paginated_response(serialized_data) + + serialized_data = [] + for obj in sorted_objects: + if hasattr(obj, 'product_date'): + serializer = TransportCarcassDetailSerializer(obj, context={'request': request}) + serialized_data.append(serializer.data) + else: + serializer = AllProductsTransportSerializer(obj, context={'request': request}) + data = serializer.data + data['product_date'] = obj.date + data['product'] = obj.product + data['quantity'] = obj.quantity + data['jihadi_destination'] = obj.jihadi_destination + serialized_data.append(data) + return Response(serialized_data, status=status.HTTP_200_OK) + + filters_steward = {} + if province: + filters_steward['province'] = province + + steward = Guilds.objects.filter(**filters_steward, trash=False, is_steward=False).order_by('id') + steward_filterset_class = GuildsFilterSet + if search and search != 'undefined' and search.strip(): + steward = steward.filter(build_query(steward_filterset_class.Meta.fields, search)) + + steward_jihadi_codes = list(steward.values_list('jihadi_code', flat=True)) + steward_jihadi_codes = [code for code in steward_jihadi_codes if code] + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + bars = TransportCarcassDetail.objects.filter( + trash=False, + jihadi_destination__in=steward_jihadi_codes + ).order_by('-product_date') + all_products_transport = AllProductsTransport.objects.filter( + 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() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + all_products_transport = all_products_transport.filter( + date__gte=date1, date__lte=date2, date__isnull=False + ) + + bars_summary = bars.values('jihadi_destination').annotate( + total_input_buy_bars_wight=Sum('quantity', filter=Q(out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(out=True)), + total_ware_house=Sum('quantity'), + total_count=Count('id'), + total_count_input_buy=Count('id', filter=Q(out=False)), + total_count_output_buy=Count('id', filter=Q(out=True)), + ) + + all_products_summary = all_products_transport.values('jihadi_destination').annotate( + total_input_buy_bars_wight=Sum('quantity', filter=Q(out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(out=True)), + total_ware_house=Sum('quantity'), + total_count=Count('id'), + total_count_input_buy=Count('id', filter=Q(out=False)), + total_count_output_buy=Count('id', filter=Q(out=True)), + ) + + bars_dict = {} + for row in bars_summary: + code = row['jihadi_destination'] + if code: + if code not in bars_dict: + bars_dict[code] = { + 'total_input_buy_bars_wight': 0, + 'total_output_buy_bars_wight': 0, + 'total_ware_house': 0, + 'total_count': 0, + 'total_count_input_buy': 0, + 'total_count_output_buy': 0, + } + bars_dict[code]['total_input_buy_bars_wight'] += row['total_input_buy_bars_wight'] or 0 + bars_dict[code]['total_output_buy_bars_wight'] += row['total_output_buy_bars_wight'] or 0 + bars_dict[code]['total_ware_house'] += row['total_ware_house'] or 0 + bars_dict[code]['total_count'] += row['total_count'] or 0 + bars_dict[code]['total_count_input_buy'] += row['total_count_input_buy'] or 0 + bars_dict[code]['total_count_output_buy'] += row['total_count_output_buy'] or 0 + + for row in all_products_summary: + code = row['jihadi_destination'] + if code: + if code not in bars_dict: + bars_dict[code] = { + 'total_input_buy_bars_wight': 0, + 'total_output_buy_bars_wight': 0, + 'total_ware_house': 0, + 'total_count': 0, + 'total_count_input_buy': 0, + 'total_count_output_buy': 0, + } + bars_dict[code]['total_input_buy_bars_wight'] += row['total_input_buy_bars_wight'] or 0 + bars_dict[code]['total_output_buy_bars_wight'] += row['total_output_buy_bars_wight'] or 0 + bars_dict[code]['total_ware_house'] += row['total_ware_house'] or 0 + bars_dict[code]['total_count'] += row['total_count'] or 0 + bars_dict[code]['total_count_input_buy'] += row['total_count_input_buy'] or 0 + bars_dict[code]['total_count_output_buy'] += row['total_count_output_buy'] or 0 + seen_jihadi_codes = set() + unique_stewards = [] + for st in steward: + 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 + ) + steward = unique_stewards + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(steward) + if page is not None: + serializer = self.serializer_class(page, many=True, context={'request': request, 'bars_dict': bars_dict}) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(steward, many=True, context={'request': request, 'bars_dict': bars_dict}) + return Response(serializer.data, status=status.HTTP_200_OK) + + + +class GuildsTransportCarcassDashboardView(APIView): + + permission_classes = [AllowAny] + def get(self,request): + search = request.GET.get('search') + + province = request.GET.get('province') + + if province == 'undefined': + province = None + + filters_steward = {} + if province: + filters_steward['province'] = province + steward = Guilds.objects.filter(**filters_steward,trash=False, is_steward=False).order_by('id') + steward_filterset_class = GuildsFilterSet + if search: + if search != 'undefined' and search.strip(): + steward = steward.filter( + build_query(steward_filterset_class.Meta.fields, search) + ) + steward = steward.values_list('jihadi_code', flat=True) + date1 = request.GET.get('date1') or None + date2 = request.GET.get('date2') or None + + bars = TransportCarcassDetail.objects.filter( + jihadi_destination__in=steward, + trash=False + ) + all_products_transport = AllProductsTransport.objects.filter( + trash=False, + 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() + bars = bars.filter(product_date__gte=date1, product_date__lte=date2) + all_products_transport = all_products_transport.filter( + date__gte=date1, date__lte=date2, date__isnull=False + ) + + aggregation = bars.aggregate( + total_input_buy_bars_wight=Sum('quantity', filter=Q(out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(out=True)), + total_ware_house=Sum('quantity'), + total_count=Count('id'), + total_count_input_buy=Count('id', filter=Q(out=False)), + total_count_output_buy=Count('id', filter=Q(out=True)), + last_update_carcass=Max('modify_date'), + ) + + all_products_aggregation = all_products_transport.aggregate( + total_input_buy_bars_wight=Sum('quantity', filter=Q(out=False)), + total_output_buy_bars_wight=Sum('quantity', filter=Q(out=True)), + total_ware_house=Sum('quantity'), + total_count=Count('id'), + total_count_input_buy=Count('id', filter=Q(out=False)), + total_count_output_buy=Count('id', filter=Q(out=True)), + last_update_all_products=Max('modify_date'), + ) + + total_input_buy_bars_wight = (aggregation['total_input_buy_bars_wight'] or 0) + (all_products_aggregation['total_input_buy_bars_wight'] or 0) + total_output_buy_bars_wight = (aggregation['total_output_buy_bars_wight'] or 0) + (all_products_aggregation['total_output_buy_bars_wight'] or 0) + total_ware_house = (aggregation['total_ware_house'] or 0) + (all_products_aggregation['total_ware_house'] or 0) + total_count = (aggregation['total_count'] or 0) + (all_products_aggregation['total_count'] or 0) + total_count_input_buy = (aggregation['total_count_input_buy'] or 0) + (all_products_aggregation['total_count_input_buy'] or 0) + total_count_output_buy = (aggregation['total_count_output_buy'] or 0) + (all_products_aggregation['total_count_output_buy'] or 0) + + last_update_carcass = aggregation.get('last_update_carcass') + last_update_all_products = all_products_aggregation.get('last_update_all_products') + last_update = None + if last_update_carcass and last_update_all_products: + last_update = max(last_update_carcass, last_update_all_products) + elif last_update_carcass: + last_update = last_update_carcass + elif last_update_all_products: + last_update = last_update_all_products + + if total_count > 0: + total_input_bars_percent = round((total_input_buy_bars_wight / total_ware_house) * 100, 1) + total_output_bars_percent = round((total_output_buy_bars_wight / total_ware_house) * 100, 1) + else: + total_input_bars_percent = 0 + total_output_bars_percent = 0 + + return Response({ + "role": 'صنف', + "product": 'گوشت مرغ تازه', + "total_input_buy_bars_wight": int(total_input_buy_bars_wight), + "total_output_buy_bars_wight": int(total_output_buy_bars_wight), + "total_ware_house": int(total_ware_house), + "total_input_buy_bars_percent": total_input_bars_percent, + "total_output_buy_bars_percent": total_output_bars_percent, + "total_count_guild": len(steward), + "last_update": last_update, + "total_input_buy_bars_count": int(total_count_input_buy), + "total_output_buy_bars_count": int(total_count_output_buy), + }) + + +class ApiSendDifferentBarFromHatching(viewsets.ModelViewSet): + queryset = TransportingDetail.objects.filter(trash=False) + serializer_class = TransportingForClearanceCodeSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = TransportingDetailFilterSet + + def list(self, request, *args, **kwargs): + filters = {'trash': False} + filters_bar = {'trash': False} + if request.GET.get('date1') != 'None': + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + filters_bar['Date__date__gte'] = date1 + filters_bar['Date__date__lte'] = date2 + + poultry = Hatching.objects.filter(**filters, PartIdCode=request.GET['licence_number']) + if poultry.exists(): + bar = TransportingDetail.objects.filter(**filters_bar, hatching__in=poultry, TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری' + )).exclude( + TrackingCode__in=request.data + ).order_by('-Date') + quarantine_code = bar.values_list('TrackingCode', flat=True).distinct() + bar = bar.filter(TrackingCode__in=quarantine_code).order_by('-Date') + search = request.GET.get('search') + value = request.GET.get('value') + if search: + if search != 'undefined' and value.strip(): + bar = bar.filter( + build_query(self.filterset_class.Meta.fields, value) + ) + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(bar) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + ser_data = TransportingForClearanceCodeSerializer(bar, many=True).data + return Response(ser_data) + return Response([]) + + +def fix_province(): + province_list = [p['name'] for p in iranprovince] + + wrong_records = TransportCarcassDetail.objects.filter( + ~Q(origin_province__in=province_list) | ~Q(destination_province__in=province_list), + trash=False + ) + + for record in wrong_records: + record.save() + + +def fix_city(): + province_list = [p['name'] for p in irancity] + + wrong_records = TransportCarcassDetail.objects.filter( + ~Q(origin_city__in=province_list) | ~Q(destination_city__in=province_list), + trash=False + ) + + for record in wrong_records: + record.save() + + +def update_product_date(request): + date1 = datetime.datetime.strptime(str(request.GET['date1']), + '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(request.GET['date2']), + '%Y-%m-%d').date() + bars = TransportCarcassDetail.objects.filter(trash=False, product_date__isnull=True, date__gte=date1,date__lte=date2, + has_product_date=False)[:1000] + for bar in bars: + quarantine = bar.tracking + session = requests.Session() + session.mount('https://', SSLAdapter()) + data = {'gid': str(quarantine)} + m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, + headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) + context = BeautifulSoup(m.text, 'html.parser') + try: + table = context.find_all('table') + if table[5:6]: + for i in table[5:6]: + row = i.find_all('tr') + for r in row[1:2]: + td = r.find('td') + shamsi_date =td.text.strip().split(':')[1] + year, month, day = map(int, shamsi_date.split('/')) + gregorian_date = jdatetime.date(year, month, day).togregorian() + bar.product_date = gregorian_date + bar.has_product_date = True + bar.save() + + + except: + bar.product_date=bar.date + bar.has_product_date = True + bar.save() + + return HttpResponse(len(bars)) + +def update_product_date_cron(): + bars = TransportCarcassDetail.objects.filter(trash=False, product_date__isnull=True, + has_product_date=False + ).order_by('-date')[:600] + for bar in bars: + quarantine = bar.tracking + session = requests.Session() + session.mount('https://', SSLAdapter()) + data = {'gid': str(quarantine)} + m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, + headers={ + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) + context = BeautifulSoup(m.text, 'html.parser') + bar.has_product_date=True + try: + table = context.find_all('table') + if table[5:6]: + for i in table[5:6]: + row = i.find_all('tr') + for r in row[1:2]: + td = r.find('td') + shamsi_date = td.text.strip().split(':')[1] + year, month, day = map(int, shamsi_date.split('/')) + gregorian_date = jdatetime.date(year, month, day).togregorian() + bar.product_date = gregorian_date + bar.has_product_date = True + bar.save() + + except: + bar.product_date = bar.date + bar.has_product_date = True + bar.save() + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def send_transport_carcass_detail_for_rasadyaar(request): + code = request.GET['code'] + code = code.split(',') + kill_house = KillHouse.objects.filter(trash=False,PartIdCode__in=code).order_by('id') + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + + date1 = datetime.datetime.strptime(str(date1), '%Y-%m-%d').date() + date2 = datetime.datetime.strptime(str(date2), '%Y-%m-%d').date() + bars = TransportCarcassDetail.objects.filter( + Q(product_date__gte=date1, product_date__lte=date2, product_date__isnull=False) | + Q(date__gte=date1, date__lte=date2, product_date__isnull=True), + trash=False + ).only('quantity','out','id','jihadi_origin','tracking') + date_1_for_buy_bars = date1 - datetime.timedelta(days=1) + date_2_for_buy_bars = date2 - datetime.timedelta(days=1) + buy_bars = TransportingDetail.objects.filter( + Date__date__gte=date_1_for_buy_bars, + Date__date__lte=date_2_for_buy_bars, + trash=False, + TrackingStatusDescription__in=("تایید تخلیه",'بارگیری') + ).only('GoodAmount','Out','id','DesPartIdCode','TrackingCode') + 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__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, + product='مرغ زنده -جهت كشتار' + ).exclude(tracking__in=all_track).only('quantity','out','id','jihadi_destination', 'tracking') + + bars_summary = bars.values('jihadi_origin').annotate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + buy_summary = buy_bars.values('DesPartIdCode').annotate( + total=Sum('GoodAmount'), + input_total=Sum('GoodAmount', filter=Q(Out=False)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_count=Count('id', filter=Q(Out=False)), + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + bars_dict = {} + for row in bars_summary: + key = row['jihadi_origin'] + if key: + if key not in bars_dict: + bars_dict[key] = { + 'total': 0, + 'input_total': 0, + 'output_total': 0, + 'input_count': 0, + 'output_count': 0, + 'total_count': 0, + } + bars_dict[key]['total'] += row['total'] or 0 + bars_dict[key]['input_total'] += row['input_total'] or 0 + bars_dict[key]['output_total'] += row['output_total'] or 0 + bars_dict[key]['input_count'] += row['input_count'] or 0 + bars_dict[key]['output_count'] += row['output_count'] or 0 + bars_dict[key]['total_count'] += row['total_count'] or 0 + + for row in all_products_carcass_summary: + key = row['jihadi_origin'] + if key: + if key not in bars_dict: + bars_dict[key] = { + 'total': 0, + 'input_total': 0, + 'output_total': 0, + 'input_count': 0, + 'output_count': 0, + 'total_count': 0, + } + bars_dict[key]['total'] += row['total'] or 0 + bars_dict[key]['input_total'] += row['input_total'] or 0 + bars_dict[key]['output_total'] += row['output_total'] or 0 + bars_dict[key]['input_count'] += row['input_count'] or 0 + bars_dict[key]['output_count'] += row['output_count'] or 0 + bars_dict[key]['total_count'] += row['total_count'] or 0 + + buy_dict = {} + for row in buy_summary: + key = row['DesPartIdCode'] + if key not in buy_dict: + buy_dict[key] = { + 'total': 0, + 'input_total': 0, + 'output_total': 0, + 'input_count': 0, + 'output_count': 0, + 'total_count': 0, + } + buy_dict[key]['total'] += row['total'] or 0 + buy_dict[key]['input_total'] += row['input_total'] or 0 + buy_dict[key]['output_total'] += row['output_total'] or 0 + 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: + if key not in buy_dict: + buy_dict[key] = { + 'total': 0, + 'input_total': 0, + 'output_total': 0, + 'input_count': 0, + 'output_count': 0, + 'total_count': 0, + } + buy_dict[key]['total'] += row['total'] or 0 + buy_dict[key]['input_total'] += row['input_total'] or 0 + buy_dict[key]['output_total'] += row['output_total'] or 0 + 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 + kill_house = list(kill_house) + kill_house.sort( + key=lambda kh: (bars_dict.get(kh.PartIdCode, {}) or {}).get('total', 0) or 0, + reverse=True + ) + + serializer = KillHouseForTransportCarcassForRassadyaarSerializer( + kill_house, many=True, context={'request': request, 'bars_dict': bars_dict, 'buy_dict': buy_dict} + ) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def delete_free_bar_from_rasadyaar(request): + code = request.data + code = dict(code)['code'] + bars = TransportingDetail.objects.filter(trash=False, Out=True, TrackingCode__in=code, + ).exclude(TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری')) + + ser_data = TransportingDetailForUpdateSerializer(bars, many=True).data + return Response(ser_data, status=status.HTTP_200_OK) + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def fix_number(request): + data = request.data + poultreis = Poultry.objects.filter(trash=False, PartIdCode__in=list(data.keys())) + result_list=[] + for k, v in data.items(): + poultry = poultreis.filter(PartIdCode=k).first() + if poultry and poultry.Mobile != v: + result_list.append({k:poultry.Mobile}) + + return Response(result_list) + + +@api_view(["POST"]) +@permission_classes([AllowAny]) +@csrf_exempt +def get_evacuation_detail_by_request_code(request): + request_code = request.data.get('RequestCode') + if not request_code: + return Response({'detail': 'RequestCode is required'}, status=status.HTTP_400_BAD_REQUEST) + + hatching = Hatching.objects.filter(RequestCode=request_code, trash=False).first() + if not hatching: + return Response([], status=status.HTTP_200_OK) + + evacuations = EvacuationDetail.objects.filter(hatching=hatching, trash=False).order_by('-create_date') + serializer = EvacuationDetailSerializer(evacuations, many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(['POST']) +@permission_classes([AllowAny]) +def get_evacuation_details_by_request_codes(request): + request_codes = request.data.get('codes', []) + if not request_codes or not isinstance(request_codes, list): + return Response({'detail': 'RequestCodes list is required'}, status=status.HTTP_400_BAD_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) + + +class InquiryCredentialsViewSet(viewsets.ModelViewSet): + queryset = InquiryCredentials.objects.all() + serializer_class = InquiryCredentialsSerializer + permission_classes = [AllowAny] + + def list(self, request, *args, **kwargs): + inquiry_credentials = InquiryCredentials.objects.filter(trash=False).first() + # inquiry_credentials, created = InquiryCredentials.objects.get_or_create(trash=False) + serializer = self.serializer_class(inquiry_credentials) + return Response(serializer.data, status=status.HTTP_200_OK) + + def update(self, request, *args, **kwargs): + inquiry_credentials = InquiryCredentials.objects.filter(trash=False).first() + serializer = self.serializer_class(inquiry_credentials, data=request.data, partial=True) + serializer.is_valid(raise_exception=True) + serializer.save() + return Response(serializer.data, status=status.HTTP_200_OK) + + +class EvacuationDetailViewSet(viewsets.ModelViewSet): + queryset = EvacuationDetail.objects.filter(trash=False) + serializer_class = EvacuationDetailSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + + 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) + if external_id is not None: + clean_data['ExternalId'] = external_id + evacuation = None + if external_id: + evacuation = EvacuationDetail.objects.filter( + ExternalId=external_id, + trash=False + ).first() + + if evacuation: + for key, value in clean_data.items(): + setattr(evacuation, key, value) + evacuation.hatching = hatching + evacuation.save() + total_updated += 1 + else: + clean_data['hatching'] = hatching + EvacuationDetail.objects.create(**clean_data) + total_created += 1 + + return Response({ + "result": "با موفقیت ثبت شد", + "created": total_created, + "updated": total_updated + }, status=status.HTTP_201_CREATED) + + 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) + + page = self.paginate_queryset(evacuations.order_by('-issue_date', '-create_date')) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(evacuations.order_by('-issue_date', '-create_date'), many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def evacuation_report_type_summary(request): + queryset = EvacuationDetail.objects.filter(trash=False).exclude( + ReportTypeString__isnull=True + ).exclude( + ReportTypeString='' + ) + + report_type_counter = queryset.values('ReportTypeString').annotate( + count=Count('id') + ) + + type_relations = defaultdict(set) + for item in queryset.values('ReportTypeString', 'ReportType').distinct(): + report_type_string = item['ReportTypeString'] + report_type_value = item['ReportType'] + if report_type_value is not None: + type_relations[report_type_string].add(report_type_value) + + report_types = [] + for entry in report_type_counter.order_by('-count', 'ReportTypeString'): + report_type_string = entry['ReportTypeString'] + associated_types = sorted(type_relations.get(report_type_string, [])) + report_types.append({ + "report_type_string": report_type_string, + "count": entry['count'], + "report_types": associated_types, + }) + + distinct_count = len(report_types) + mapping_is_unique = all(len(values) <= 1 for values in type_relations.values()) + + return Response({ + "total_report_types": distinct_count, + "report_types": report_types, + "report_type_matches_report_type_string": mapping_is_unique, + }, status=status.HTTP_200_OK) + + +class AllProductsTransportViewSet(viewsets.ModelViewSet): + queryset = AllProductsTransport.objects.filter(trash=False) + serializer_class = AllProductsTransportCustomSerializer + permission_classes = [AllowAny] + pagination_class = CustomPagination + filterset_class = AllProductsTransportFilterSet + + + def list(self, request, *args, **kwargs): + transports = self.filter_queryset(self.get_queryset()) + + product_type = request.GET.get('product_type') + destination_province = request.GET.get('destination_province') + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + search = request.GET.get('search') + + if product_type and product_type != 'undefined': + transports = transports.filter(product=product_type) + + if destination_province and destination_province != 'undefined': + transports = transports.filter(destination_province=destination_province) + + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d') + transports = transports.filter(date__gte=start_date, date__lte=end_date) + except ValueError: + pass + + if search: + if search != 'undefined' and search.strip(): + transports = transports.filter( + build_query(self.filterset_class.Meta.fields, search) + ) + + page_size = request.query_params.get('page_size', None) + if page_size: + self.pagination_class.page_size = int(page_size) + + page = self.paginate_queryset(transports.order_by('-date', '-create_date')) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.serializer_class(transports.order_by('-date', '-create_date'), many=True) + return Response(serializer.data, status=status.HTTP_200_OK) + + def create(self, request, *args, **kwargs): + if 'file' in request.FILES: + return self._import_from_excel(request) + data = request.data + if isinstance(data, list): + # Bulk create + created_objects = [] + for item in data: + tracking = item.get('tracking') + if tracking: + obj, created = AllProductsTransport.objects.update_or_create( + tracking=tracking, + defaults=item + ) + created_objects.append(obj) + serializer = self.get_serializer(created_objects, many=True) + return Response(serializer.data, status=status.HTTP_201_CREATED) + else: + # Single create + return super().create(request, *args, **kwargs) + + def _import_from_excel(self, request): + """Import data from Excel file""" + file = request.FILES['file'].read() + wb_obj = openpyxl.load_workbook(filename=BytesIO(file)) + sheet = wb_obj.active + + headers = [str(cell).strip() if cell else '' for cell in next(sheet.iter_rows(values_only=True))] + + field_map = { + "id": "record_id", + "مقصد قبلی": "destination_prev", + "تغییر مقصد": "destination_changed", + "کد رهگیری": "tracking", + "رهگیری": "tracking", + "تاریخ": "date", + "محصول": "product", + "اقلام": "items", + "مقدار": "quantity", + "واحد": "unit", + "استان مبدا": "origin_province", + "شهرستان مبدا": "origin_city", + "مبدا": "origin", + "استان مقصد": "destination_province", + "شهرستان مقصد": "destination_city", + "مقصد": "destination", + "ش جهادی مبدا": "jihadi_origin", + "ش جهادی مقصد": "jihadi_destination", + "مالک": "owner", + "کد رهگیری خودرو": "car_tracking_code", + "نام راننده": "driver_name", + "وزن پر": "gross_weight", + "وزن خالی": "tare_weight", + "وزن": "net_weight", + "کد باسکول": "scale_code", + "نام باسکول": "scale_name", + "قبض باسکول": "scale_receipt", + "تاریخ تخلیه": "unloading_date", + "تخلیه": "unloading", + } + + created_count = 0 + updated_count = 0 + skipped_count = 0 + + for row in sheet.iter_rows(min_row=2, values_only=True): + if not row or all(cell is None for cell in row): + 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("ش جهادی مبدا") + print(province_name) + if not tracking_val: + continue + + existing_record = AllProductsTransport.objects.filter(tracking=tracking_val, trash=False).first() + + unloading_val = row_data.get("تخلیه", "").strip() if row_data.get("تخلیه") else "" + if unloading_val in ["تخلیه.", "تخلیه"] and existing_record: + skipped_count += 1 + continue + + record_data = {} + 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): + if '/' in value: + parts = value.split('/') + if len(parts) == 3: + y, m, d = map(int, parts) + value = convert_to_miladi(y, m, d) + else: + value = datetime.datetime.strptime(value, '%Y-%m-%d').date() + elif hasattr(value, "year"): + 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): + value = float(value.replace(',', '')) + else: + 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): + value = float(value.replace(',', '')) + else: + value = float(value) + except (ValueError, TypeError): + value = None + + record_data[model_field] = value + + hatching_obj = None + try: + permit_map = get_hatching_permit_code(tracking_val) + permit_code = permit_map.get(str(tracking_val)) + if permit_code: + hatching_obj = Hatching.objects.filter(PartIdCode=jihadi_origin_code, trash=False).last() + except Exception: + pass + + if existing_record: + for key, value in record_data.items(): + setattr(existing_record, key, value) + if hatching_obj: + existing_record.hatching = hatching_obj + existing_record.save() + + if existing_record.destination_province and existing_record.origin_province: + if existing_record.destination_province != existing_record.origin_province: + existing_record.out = True + existing_record.save() + + updated_count += 1 + else: + record_data["tracking"] = tracking_val + new_record = AllProductsTransport(**record_data) + 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({ + 'result': 'ok', + 'created': created_count, + 'updated': updated_count, + 'skipped': skipped_count, + 'message': f'{created_count} رکورد جدید اضافه شد، {updated_count} رکورد به‌روزرسانی شد، {skipped_count} رکورد رد شد (تخلیه شده)' + }, status=status.HTTP_201_CREATED) + + +class AllProductsTransportDashboardView(APIView): + permission_classes = [AllowAny] + + def get(self, request): + role = request.GET.get('role') + province = request.GET.get('province') + search = request.GET.get('search') + product_type = request.GET.get('product_type') + date1 = request.GET.get('date1') or None + date2 = request.GET.get('date2') or None + + if province == 'undefined': + province = None + + queryset = AllProductsTransport.objects.filter(trash=False) + + if product_type and product_type != 'undefined': + queryset = queryset.filter(product=product_type) + + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + end_date = datetime.datetime.strptime(str(date2), '%Y-%m-%d') + queryset = queryset.filter(date__gte=start_date, date__lte=end_date) + except ValueError: + pass + destination_province = request.GET.get('destination_province') + kill_house_filterset_class = AllProductsTransportFilterSet + + if search and search != 'undefined' and search.strip(): + queryset = queryset.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + if role: + if role == 'KillHouse': + filters_kill_house = {} + if province: + filters_kill_house['Province'] = province + kill_house_filterset_class = AllProductsTransportFilterSet + kill_house = KillHouse.objects.filter(**filters_kill_house).order_by('id') + + if search and search != 'undefined' and search.strip(): + kill_house = kill_house.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + + kill_house_codes = kill_house.values_list('PartIdCode', flat=True) + bars = queryset.filter(jihadi_origin__in=kill_house_codes) + + if destination_province and destination_province != 'undefined': + bars = bars.filter(destination_province=destination_province) + + + aggregation = bars.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + total_count = aggregation['total_count'] or 0 + total_quantity = aggregation['total'] or 0 + input_quantity = aggregation['input_total'] or 0 + output_quantity = aggregation['output_total'] or 0 + input_count = aggregation['input_count'] or 0 + output_count = aggregation['output_count'] or 0 + + 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 + + last_update = bars.order_by('-modify_date').values_list('modify_date', flat=True).first() + + return Response({ + "role": 'کشتارگاه', + "product": product_type, + "bars": int(total_count), + "total_bars_wight": int(total_quantity), + "input_bars": int(input_count), + "total_input_bars_wight": int(input_quantity), + "total_input_bars_percent": input_percent, + "output_bars": int(output_count), + "total_output_bars_wight": int(output_quantity), + "total_output_bars_percent": output_percent, + "total_count_kill_house": kill_house.count(), + "last_update": last_update, + }, status=status.HTTP_200_OK) + + else: + filters_steward = {} + if province: + filters_steward['province'] = province + kill_house_filterset_class = AllProductsTransportFilterSet + steward = Guilds.objects.filter(**filters_steward, trash=False, is_steward=True).order_by('id') + + if search and search != 'undefined' and search.strip(): + steward = steward.filter( + build_query(kill_house_filterset_class.Meta.fields, search) + ) + + steward_codes = steward.values_list('jihadi_code', flat=True) + + bars = queryset.filter( + Q(jihadi_origin__in=steward_codes) | Q(jihadi_destination__in=steward_codes) + ).order_by('-modify_date') + + if destination_province and destination_province != 'undefined': + bars = bars.filter(destination_province=destination_province) + + aggregation = bars.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + total_count = aggregation['total_count'] or 0 + total_quantity = aggregation['total'] or 0 + input_quantity = aggregation['input_total'] or 0 + output_quantity = aggregation['output_total'] or 0 + input_count = aggregation['input_count'] or 0 + output_count = aggregation['output_count'] or 0 + + 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 + + last_update = bars.values_list('modify_date', flat=True).first() + + return Response({ + "product": product_type, + "bars": int(total_count), + "total_bars_wight": int(total_quantity), + "input_bars": int(input_count), + "total_input_bars_wight": int(input_quantity), + "total_input_bars_percent": input_percent, + "output_bars": int(output_count), + "total_output_bars_wight": int(output_quantity), + "total_output_bars_percent": output_percent, + "total_count_steward": steward.count(), + "last_update": last_update, + }, status=status.HTTP_200_OK) + + if destination_province and destination_province != 'undefined': + queryset = queryset.filter(destination_province=destination_province) + + aggregation = queryset.aggregate( + total=Sum('quantity'), + input_total=Sum('quantity', filter=Q(out=False)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + total_count=Count('id'), + ) + + total_count = aggregation['total_count'] or 0 + total_quantity = aggregation['total'] or 0 + input_quantity = aggregation['input_total'] or 0 + output_quantity = aggregation['output_total'] or 0 + input_count = aggregation['input_count'] or 0 + output_count = aggregation['output_count'] or 0 + + 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 + + last_update = queryset.order_by('-modify_date').values_list('modify_date', flat=True).first() + + return Response({ + "role": 'all', + "product": product_type, + "bars": int(total_count), + "total_bars_wight": int(total_quantity), + "input_bars": int(input_count), + "total_input_bars_wight": int(input_quantity), + "total_input_bars_percent": input_percent, + "output_bars": int(output_count), + "total_output_bars_wight": int(output_quantity), + "total_output_bars_percent": output_percent, + "last_update": last_update, + }, status=status.HTTP_200_OK) + + +class AllProductsTransportProductsListView(APIView): + permission_classes = [AllowAny] + + def get(self, request): + products = AllProductsTransport.objects.filter( + trash=False, + product__isnull=False + ).exclude(product='').values_list('product', flat=True).distinct().order_by('product') + + return Response({ + "products": list(products) + }, status=status.HTTP_200_OK) + + +def _convert_transporting_detail_to_unified(obj): + """تبدیل TransportingDetail به فرمت یکپارچه""" + hatching_data = None + if obj.hatching: + poultry_data = None + if obj.hatching.poultry: + poultry_data = { + 'UnitId': obj.hatching.poultry.UnitId, + 'PartIdCode': obj.hatching.poultry.PartIdCode, + 'Province': obj.hatching.poultry.Province, + 'City': obj.hatching.poultry.City, + 'UnitName': obj.hatching.poultry.UnitName, + 'Mobile': obj.hatching.poultry.Mobile, + } + hatching_data = { + 'PartIdCode': obj.hatching.PartIdCode, + 'poultry': poultry_data, + 'RequestCode': obj.hatching.RequestCode, + 'PedigreeName': obj.hatching.PedigreeName, + } + + return { + 'id': obj.id, + 'key': str(obj.key), + 'source': 'TransportingDetail', + 'record_id': str(obj.id), + 'tracking': obj.TrackingCode, + 'date': obj.Date.date() if obj.Date else None, + 'product': obj.GoodName, + 'items': obj.GoodName, + 'quantity': obj.GoodAmount, + 'unit': 'قطعه', + 'origin_province': obj.hatching.ProvinceName if obj.hatching else None, + 'origin_city': obj.hatching.CityName if obj.hatching else None, + 'origin': obj.SourceUnitName, + 'destination_province': obj.Province, + 'destination_city': obj.City, + 'destination': obj.DesUnitName, + 'jihadi_origin': obj.SourcePartIdCode, + 'jihadi_destination': obj.DesPartIdCode, + 'owner': obj.hatching.PersonFullName if obj.hatching else None, + 'car_tracking_code': None, + 'driver_name': None, + 'gross_weight': None, + 'tare_weight': None, + 'net_weight': None, + 'scale_code': None, + 'scale_name': None, + 'scale_receipt': None, + 'unloading_date': obj.Date.date() if obj.Date else None, + 'unloading': obj.TrackingStatusDescription, + 'out': obj.Out, + 'hatching': hatching_data, + 'create_date': obj.create_date, + 'modify_date': obj.modify_date, + } + + +def _convert_transport_carcass_to_unified(obj): + """تبدیل TransportCarcassDetail به فرمت یکپارچه""" + return { + 'id': obj.id, + 'key': str(obj.key), + 'source': 'TransportCarcassDetail', + 'record_id': obj.id_quarantineh, + 'tracking': obj.tracking, + 'date': obj.date, + 'product': obj.product, + 'items': obj.items, + 'quantity': obj.quantity, + 'unit': obj.unit, + 'origin_province': obj.origin_province, + 'origin_city': obj.origin_city, + 'origin': obj.origin, + 'destination_province': obj.destination_province, + 'destination_city': obj.destination_city, + 'destination': obj.destination, + 'jihadi_origin': obj.jihadi_origin, + 'jihadi_destination': obj.jihadi_destination, + 'owner': obj.owner, + 'car_tracking_code': obj.car_tracking_code, + 'driver_name': obj.driver_name, + 'gross_weight': obj.gross_weight, + 'tare_weight': obj.tare_weight, + 'net_weight': obj.net_weight, + 'scale_code': obj.scale_code, + 'scale_name': obj.scale_name, + 'scale_receipt': obj.scale_receipt, + 'unloading_date': obj.unloading_date, + 'unloading': obj.unloading, + 'out': obj.out, + 'hatching': None, + 'create_date': obj.create_date, + 'modify_date': obj.modify_date, + } + + +def _convert_all_products_to_unified(obj): + """تبدیل AllProductsTransport به فرمت یکپارچه""" + hatching_data = None + if obj.hatching: + poultry_data = None + if obj.hatching.poultry: + poultry_data = { + 'UnitId': obj.hatching.poultry.UnitId, + 'PartIdCode': obj.hatching.poultry.PartIdCode, + 'Province': obj.hatching.poultry.Province, + 'City': obj.hatching.poultry.City, + 'UnitName': obj.hatching.poultry.UnitName, + 'Mobile': obj.hatching.poultry.Mobile, + } + hatching_data = { + 'PartIdCode': obj.hatching.PartIdCode, + 'poultry': poultry_data, + 'RequestCode': obj.hatching.RequestCode, + 'PedigreeName': obj.hatching.PedigreeName, + } + + return { + 'id': obj.id, + 'key': str(obj.key), + 'source': 'AllProductsTransport', + 'record_id': obj.record_id, + 'tracking': obj.tracking, + 'date': obj.date, + 'product': obj.product, + 'items': obj.items, + 'quantity': obj.quantity, + 'unit': obj.unit, + 'origin_province': obj.origin_province, + 'origin_city': obj.origin_city, + 'origin': obj.origin, + 'destination_province': obj.destination_province, + 'destination_city': obj.destination_city, + 'destination': obj.destination, + 'jihadi_origin': obj.jihadi_origin, + 'jihadi_destination': obj.jihadi_destination, + 'owner': obj.owner, + 'car_tracking_code': obj.car_tracking_code, + 'driver_name': obj.driver_name, + 'gross_weight': obj.gross_weight, + 'tare_weight': obj.tare_weight, + 'net_weight': obj.net_weight, + 'scale_code': obj.scale_code, + 'scale_name': obj.scale_name, + 'scale_receipt': obj.scale_receipt, + 'unloading_date': obj.unloading_date, + 'unloading': obj.unloading, + 'out': obj.out, + 'hatching': hatching_data, + 'create_date': obj.create_date, + 'modify_date': obj.modify_date, + } + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def get_all_products_transport_by_code(request): + code = request.GET.get('code') + if not code: + return Response( + {'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 باشد'}, + 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 باشد'}, + status=status.HTTP_400_BAD_REQUEST + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + start_date = None + end_date = None + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + 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: + return False + if tracking: + seen_tracking_codes.add(tracking) + unified_results.append(item) + return True + + if from_source == 'Poultry': + if transport_type == 'out': + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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, + TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری')).order_by('-Date') + if start_date and end_date: + 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: + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_destination=code + ).order_by('-date') + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + carcass_details = carcass_details.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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: + transport_details = TransportingDetail.objects.filter( + trash=False, + DesPartIdCode=code, + TrackingStatusDescription__in=( + 'تایید تخلیه', 'بارگیری')).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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( + trash=False, + jihadi_origin=code + ) + else: + bars = AllProductsTransport.objects.filter( + 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': + if transport_type == 'out': + bars = bars.filter(destination_province=province) + else: + 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 = [ + r for r in unified_results + if (r.get('tracking') and search_lower in str(r['tracking']).lower()) or + (r.get('product') and search_lower in str(r['product']).lower()) or + (r.get('origin') and search_lower in str(r['origin']).lower()) or + (r.get('destination') and search_lower in str(r['destination']).lower()) or + (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, + 'previous': f"?page={page_number - 1}" if page_number > 1 else None, + 'results': paginated_results + }, status=status.HTTP_200_OK) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def get_all_products_transport_products_by_code(request): + code = request.GET.get('code') + if not code: + return Response( + {'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 باشد'}, + 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 باشد'}, + status=status.HTTP_400_BAD_REQUEST + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + start_date = None + end_date = None + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + 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() + + if from_source == 'Poultry': + if transport_type == 'out': + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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='') + .values_list('GoodName', flat=True) + .distinct() + ) + else: + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_destination=code + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + carcass_details = carcass_details.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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='') + .values_list('product', flat=True) + .distinct() + ) + else: + transport_details = TransportingDetail.objects.filter( + trash=False, + DesPartIdCode=code, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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( + trash=False, + jihadi_origin=code + ) + else: + bars = AllProductsTransport.objects.filter( + 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': + if transport_type == 'out': + bars = bars.filter(destination_province=province) + else: + bars = bars.filter(origin_province=province) + if product_type and product_type != 'undefined': + bars = bars.filter(product=product_type) + + products_set.update( + bars.filter(product__isnull=False) + .exclude(product='') + .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) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def get_all_products_transport_provinces_by_code(request): + code = request.GET.get('code') + if not code: + return Response( + {'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 باشد'}, + 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 باشد'}, + status=status.HTTP_400_BAD_REQUEST + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + start_date = None + end_date = None + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + 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() + + if from_source == 'Poultry': + if transport_type == 'out': + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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='') + .values_list('Province', flat=True) + .distinct() + ) + else: + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_destination=code + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + carcass_details = carcass_details.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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='') + .values_list('destination_province', flat=True) + .distinct() + ) + else: + transport_details = TransportingDetail.objects.filter( + trash=False, + DesPartIdCode=code, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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( + trash=False, + jihadi_origin=code + ) + else: + bars = AllProductsTransport.objects.filter( + 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': + if transport_type == 'out': + bars = bars.filter(destination_province=province) + else: + 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) + .exclude(destination_province='') + .values_list('destination_province', flat=True) + .distinct() + ) + else: + provinces_set.update( + bars.filter(origin_province__isnull=False) + .exclude(origin_province='') + .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) + + +@api_view(['GET']) +@permission_classes([AllowAny]) +@csrf_exempt +def get_all_products_transport_dashboard_by_code(request): + code = request.GET.get('code') + if not code: + return Response( + {'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 باشد'}, + 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 باشد'}, + status=status.HTTP_400_BAD_REQUEST + ) + + date1 = request.GET.get('date1') + date2 = request.GET.get('date2') + start_date = None + end_date = None + if date1 and date2 and date1 != 'undefined' and date2 != 'undefined': + try: + start_date = datetime.datetime.strptime(str(date1), '%Y-%m-%d') + 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 + output_quantity = 0 + input_count = 0 + output_count = 0 + last_update = None + + if from_source == 'Poultry': + if transport_type == 'out': + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_cnt=Count('id', filter=Q(out=False)), + output_cnt=Count('id', filter=Q(out=True)), + total_cnt=Count('id'), + last_mod=Max('modify_date'), + ) + total_count += agg['total_cnt'] or 0 + total_quantity += agg['total'] or 0 + input_quantity += agg['input_total'] or 0 + output_quantity += agg['output_total'] or 0 + input_count += agg['input_cnt'] or 0 + 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, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_cnt=Count('id', filter=Q(Out=False)), + output_cnt=Count('id', filter=Q(Out=True)), + total_cnt=Count('id'), + last_mod=Max('modify_date'), + ) + total_count += agg['total_cnt'] or 0 + total_quantity += agg['total'] or 0 + input_quantity += agg['input_total'] or 0 + output_quantity += agg['output_total'] or 0 + input_count += agg['input_cnt'] or 0 + 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: + all_products = AllProductsTransport.objects.filter( + trash=False, + jihadi_destination=code + ) + if start_date and end_date: + all_products = all_products.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_cnt=Count('id', filter=Q(out=False)), + output_cnt=Count('id', filter=Q(out=True)), + total_cnt=Count('id'), + last_mod=Max('modify_date'), + ) + total_count += agg['total_cnt'] or 0 + total_quantity += agg['total'] or 0 + input_quantity += agg['input_total'] or 0 + output_quantity += agg['output_total'] or 0 + input_count += agg['input_cnt'] or 0 + 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( + trash=False, + jihadi_origin=code, + ) + if start_date and end_date: + carcass_details = carcass_details.filter(date__gte=start_date, date__lte=end_date) + if province and province != 'undefined': + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_cnt=Count('id', filter=Q(out=False)), + output_cnt=Count('id', filter=Q(out=True)), + total_cnt=Count('id'), + last_mod=Max('modify_date'), + ) + total_count += agg['total_cnt'] or 0 + total_quantity += agg['total'] or 0 + input_quantity += agg['input_total'] or 0 + output_quantity += agg['output_total'] or 0 + input_count += agg['input_cnt'] or 0 + 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: + transport_details = TransportingDetail.objects.filter( + trash=False, + DesPartIdCode=code, + TrackingStatusDescription__in=('تایید تخلیه', 'بارگیری') + ).select_related('hatching', 'hatching__poultry') + if start_date and end_date: + 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)), + output_total=Sum('GoodAmount', filter=Q(Out=True)), + input_cnt=Count('id', filter=Q(Out=False)), + output_cnt=Count('id', filter=Q(Out=True)), + total_cnt=Count('id'), + last_mod=Max('modify_date'), + ) + total_count += agg['total_cnt'] or 0 + total_quantity += agg['total'] or 0 + input_quantity += agg['input_total'] or 0 + output_quantity += agg['output_total'] or 0 + input_count += agg['input_cnt'] or 0 + 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( + trash=False, + jihadi_origin=code + ) + else: + all_bars = AllProductsTransport.objects.filter( + 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': + if transport_type == 'out': + all_bars = all_bars.filter(destination_province=province) + else: + 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)), + output_total=Sum('quantity', filter=Q(out=True)), + input_count=Count('id', filter=Q(out=False)), + output_count=Count('id', filter=Q(out=True)), + 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 + output_quantity = aggregation['output_total'] or 0 + 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), + "last_update": last_update, + "output_bars": int(output_count), + "product": product_type, + "role": "all", + "total_bars_wight": int(total_quantity), + "total_input_bars_percent": input_percent, + "total_input_bars_wight": int(input_quantity), + "total_output_bars_percent": output_percent, + "total_output_bars_wight": int(output_quantity), + }, status=status.HTTP_200_OK) \ No newline at end of file diff --git a/authentication/__init__.py b/authentication/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/authentication/__pycache__/__init__.cpython-310.pyc b/authentication/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8aded22b8bbd1618fec9c344cabed11382102c24 GIT binary patch literal 135 zcmd1j<>g`kg5bJ?=^*+sh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DD#VV#Ku{bfM zGO;KoDA+S5v9u&3HLoNyIk6-&KQAUeJ~J<~BtBlRpz;=nO>TZlX-=vg$c$npAi=@_ E05n}4GXMYp literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/__init__.cpython-311.pyc b/authentication/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c80e5ac4682e27e066eed965791335ebf862c5c7 GIT binary patch literal 142 zcmZ3^%ge<81oiH}(?RrO5CH>>P{wCAAY(d13PUi1CZpd2X#0(Sz00QV9wg3PC literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/__init__.cpython-312.pyc b/authentication/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..944ecb1dcfec7d57877206cf25429a90e55c984b GIT binary patch literal 130 zcmX@j%ge<81go7mGC}lX5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!QgpV82@3X%Nh~eN zNX;wBOinDx%+HI7kI&4@EQycTE2#X%VUwGmQks)$SHud`!3e~~AjU^#Mn=XWW*`dy DVJ;ir literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/__init__.cpython-39.pyc b/authentication/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ccc34e1d713328ceb4e86124b870457421e83fa3 GIT binary patch literal 138 zcmYe~<>g`kf{M%bnIQTxh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2DX#VRH@uOK-l zD6u#(r82Q7J}B5TCb6_6BQ>uiGdZy&Ge0jTK0Y%qvm`!Vub}c4hfQvNN@-529mt^1 HK+FIDm}ei0 literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/admin.cpython-310.pyc b/authentication/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6462f49bc65c4597f1f001b924c6503e780b8f2 GIT binary patch literal 176 zcmd1j<>g`kg5bJ?=}tiUF^Gc(44TX@fuanW zjJH@5Q*tx&{4|-O_)@YG^V0M6lJoOQiZYXmKnAR2C}IXuVB(j$i&acfVsTui zGdZy&Ge0i|tXHp~@)w6qZhlH>PO4oI2T(a95Esh=i4V+-jEpxJ6fR&xMQlJ70L)A< AH2?qr literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/admin.cpython-312.pyc b/authentication/__pycache__/admin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d6d9eedb7fa286fb0de00b3d6cab4a5c91ff502 GIT binary patch literal 174 zcmX@j%ge<81go7mGM#|*V-N=hn4pZ$0zk%eh7^Vr#vF!R#wbQchDs()=9eI8O~zZS zi7C06d48HqxA;=B67$mY^^)`RN{TX*ikN{4Rx*4Bsrx18Y!wp}>=~0-T9T2PSCW~W uSdy8a7X#L-S5Wzj!zMRBr8Fniu80GuoDqnNL5vT~jEs!;7!-=wfE)m2oG7mV literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/admin.cpython-39.pyc b/authentication/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f0af950beee122fbb5e8ab9bb6209992591e86c GIT binary patch literal 179 zcmYe~<>g`kf{M%bnNC3ZF^Gc(44TX@fuanW zjJH@5Q*tx&{4|-O_)@YG^V0M6lJoOQiZYXmKnAR2C}IXuVB(jKi&ac+UO{q9P-1an yN@ZeEd{D4wOk!zCMrvM3W^!UlW`14_*f_m{%3B;Zx%nxjIjMGxKm$GlF#`Y-c`Dcd literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/apps.cpython-310.pyc b/authentication/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..065b93dc96d014cbb842c7a2b741dc1fe7123e67 GIT binary patch literal 430 zcmY*Vy-ve05I)B#3jJX~U6GiOvg82}LMo0?$&3$KW-* zGVuyboZCvYC*ApezVAEh^k~!vviR*QU(x&Rie2-mn2?)O3JAzbSg?dKxC8W%e*kjD z-g)AoA4AytAryqn9!~4}T31<-&s}HN7!?z8Gp3**VF<)#2}dvSk&}vV$J4HTQdL{b zWn1WKqx5=$&$7yOgpbieqbf~wRpf-!w}mRv9?3n@EbQ4ph)OP$5VkJ_ak|pwLm^%| zS#BrCs504=tsuG<*;>kXvrlN;ZPwxU?B+aeq>;FkP5Kbur~AuNS=T12mklR|yO}wl q5P;7Dw(iYBZU@`{J8a`QX@~w_vdIS2v%$sYx0mi(#t9B#%>Mw`i)!Nl literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/apps.cpython-311.pyc b/authentication/__pycache__/apps.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14170b27b8b26040c9e11470ac7a3acaff1a3edd GIT binary patch literal 529 zcmZut%}T>S5S~p^sr^Gl3PpSHm`lzoB2mP{2cUR557Zvf{OSu zJ(gTOd8@=zy*QhsLeZJsnQwMxzTKUdYPAF?kDYIGivC>$D=Fk4(GX0411C0&h)xJd z&;c$z0hbLjl>y#xXQE47>494K5TQ!q&6ek#xz5ls2YE&6NFF401QReoCmgVs=rWgd zh0DmH#5=7hyfK{68nDoEos8$9$#0osx*EUMMlLt(Ks&WetaQ&U!{%{~tu=MkLR_TO zVIzamxI`)TM7F>cO79|O=b3G83|VA{6x&@oOsN!+dxb)F=po2Ac7&&Kn0ar9Ln3j@v^0>Z-P@%5gdWjv(^I95bqlKxttO(Xx1)z5B%9 k!cdGaxJ0v%2_bXXpRKROhD7!j@Yg&aeu~qte^TjXKe2L!asU7T literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/apps.cpython-312.pyc b/authentication/__pycache__/apps.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2dd6a1cf6275f8453a3946186bc1d880abcfaa5e GIT binary patch literal 452 zcmY*VJxc>Y5S_UXIg?xv34&+}8{wL(RYXW4icJdbj=-{JH}T|hciu;Fc0&F``~`yK zr`TAA11l>#A=;#J_wFn*#mt+1^M={?W|}n+G4C4gi>RNn`47DU%R>QXz<{9#6Lb(k zflFY@6qw3!u9kC-l4+LyB^wL#%}yBh0)OO=hb3KRteRy@fEjRbkb$ExbX2A|TBcfB z-s+^u9rqJ=NE0{k%Po&>c2E6rV6$6$5-{$?cGn$?$>74}9?P3_P1Lva+#tlK6HZ88 zBSdIYPvQn44=MF3W}ER5O}&H&c|bw7m5!+7hiaES6?{ UtBCjk2R|DM?mr*@f+&UR53pl$vH$=8 literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/apps.cpython-39.pyc b/authentication/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03c1b08bdc9840b654ec179d235a7325d66b1f51 GIT binary patch literal 431 zcmY*V%}T^D5Kfvdto!3Z_9}QSLLWdxcU2TGd)U2|LWrHTM*0(*7F@6TEP~JDEmu#z zf+r{Kg1ZCrWq!VIl8l&6M+EKV>r#E-`R$Tj^D&vDn-c^eKyy;ih*EM#zytP9fJyqs zA`kpE2?jsNA_27r3$3rKGF4gPD!WE8nWLK-f+P_If@&Hu@FE`=PVwz*(Ke5=Y*Zo| zRh9ju*JF4RWmbjo5Ed24+=N#uLuPfWWDfRF?1`4azz#VtMIkx2BhFFN<}RLa{@jXu z+c^T6iZ*XJ$}66BqkPxX32fwE`XK_*LBwh(4U?Xb2THnX}H^xG16Y5RPQ05kA o91N*XyUH?PcD((9W7eLV?zsQ=^wAh=c6i=D_`)sBIPQe~0i~8~p#T5? literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/models.cpython-310.pyc b/authentication/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b0738349a3822266d151368342a143bc713b373 GIT binary patch literal 2551 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 literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/models.cpython-39.pyc b/authentication/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21670e0551aab7d8620b24502033ac136f50dfd0 GIT binary patch literal 2717 zcmbtWNpIUm6y|V|D2kFD#aWsL-P1-ut8OU@6h&gkPST*U8^m@GgaLxmjASYl@HdEZ+YH5#6Q=iy&h;`24b z_?wvHj}2xKExQlG4bBo{!~({sZzkr*3M}2X5<9RVvlC}j2`bFEVQ`069vi$O*s%J@ z3S3C4+=axQNotVPxCeCI$R5o({#3y%qGi8;2qR$J2uxuOZQ%?noN<#|`&Lke#6{oUXF+Y&chL9HuM2lHWaf;bJd|vaFqjJt?AG@b0v2 zD_@F)m@th-Le<7;h;u|Pl$}nJL^<6gO7HG294&?=<9=MMmOd;b>qHtvnji;ER`7Yr zstm$Kv}_)vv?^zT#ZBDO+HF3&WoK37(Z(8-b3?6G7%DFeaquJ&==))KZxSV>FgQ2r zX1R=d`GFx9u(c*nKU?{3Yn1Nvw(dk(#HW!A@2ub4f-$y5n#a8;kH_g&;S`;nsj}(F zw@Et_#AWg{K5Oj-Ny^F-L|Q~>RMj>&Z?0UAMZ%RmnZ#TEvQF^J1r%*SivHFY!psZ@z0 z9xpiG)N5XXl0uuF>^4XVCEVDa1&0|p&v6t8Rc><%5BFHV_QdEjUg6cpZs0vJY$K?{ z6W zntLoZ_RK%nuQ~&*!%f!^OHMY~5mLU7smjix`{KaDS0sI9M{-D!(G4&;FWv&yrK2g;s#nYole9IbDRF_ix3TfktDm2km!^J`b9P4ArTu zO@gYD$1MbDxXnZwTh6CC<#P{w9d2*}Tnl|4Zg5gV z-{4I^zo4N%1?cBgovJG$q8}#$g-e$OS%uy@gpoBdoXKw>IQ$Jn5ojNk!^LcJi$kg} zhnxn;LE20&e|_8&#(TyPe;jA%t7&NFR&MJ|;Jla#+UD9*_FlW9ynZaRd{ziiDra4{ zk3vX+T6omAq{tgRY6&wkogVC!uXL?5wC`CWZxNyFRk$1NRJfZ>7AstB zk%X6tTmcF2f76AP;gG2C55|(KxvTNuW}1tEC~{5Ub@3MwVhCHj*(vFUgi1z5km^L? zmh-H5;hv_XIc;Cn_%KQb;|}i@rLjKad*igPtD3%%I(H<_W!&vh9qts>SJL&Avr4}= qy4n=sMb57eITkiLfGBK~`#l!pXW%j=3mrRD%3S7Kt+Oq!<^KmY`ACTX literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/serializers.cpython-310.pyc b/authentication/__pycache__/serializers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c8f839c2d1146cce3972649134c1004cb46f876 GIT binary patch literal 1207 zcma)5&2AGh5VqIe&E~gd+q9@}kOO%DgsMtZLL3?)A}&@WYZW_X>23nv4JbKqDKFE< z;5B^Z#5p&_ff;YoZb=HYw4<5v_#4l+pJ(lMgTNYo{eJnI67mCs>f#Wb!Iuj#iYS_r zj0#H8_fjuof@NIr%ojc-uZUubegxB)!H@ zz$ZOwo4GbgoF+?c@*cCzcM!iZvq_R_8-nvWnU1yPFOy<1#v|3mAUK0>bpl2cK@|}m zG^EOdhTgR&m}1b3+h~I{yzRDy=55fPR?svP9Puta;g?v;<87?|g)U;tuJpq4X`Jan zFR-DM=t^lDQf4zXPtk8l`Dq@f<&HtNtq+?zwZSCOsmgDN*@vt%zn+~xADK9h)gm^d zx5L+?cwW5M(;^wiMKYU?D%|xyLT|iA4Nk8DFd^ZzMNI_m;D(zfqPEbq(O~+nQ|Udy z9G=JHE4*AtBI+_*Y;CwVSPKky@DDwLT@$+c<-z@W$Dpaho_lfUG})1e`zLXdql`;9)9`q1@@gQGwB**RUO<^FmGxi1^FQTp4^HwtHWJ xeW%^rxO<^s4E`p&cY%_=qsU3facmHM*Uz)zi}I12B7HfEphXV7h(*Cs@CTBB?N zz>ypM3oyk0!!rjC&74d;c`GTW>cRJBTgr9|Cd%yYZ{N&&`{vE>y|-URM$!bv$K_vJ zzbPR{fU8HI_5Ylse?}Ly*k*VPqFn=bio1QOJ z3WRrFWkV?QkyqQ@=!BzRW@pm64Z;Bt#HKE>4IKi75R5|ujsQIQ+pKIs) zM*McaXyqe*1+z_;y2h4aTcM}+Ox#mxMbsR{w#BY8D^6Lg785GPIf|UCH0R~2yW^vr z;r#86B_TuCF>(AGotUEikSE5q$Hk_JQt*l>Qt@H+V z!;K{tMG~H19^ljY)yU57S&fOA`t<(7UIH&U2?jC;uzF<55uA)7jCGgg1WMX!3Z+yR zutHi(06q6j!?12PNgPgb?QDP|bc{YD)c^7u7$(gg}%FlO8C*}(ZT?G9T#>6 zbcF%^#oGCSj>5)Ba_;y(=L5*Z-2a8l1u(%w2eSaZ@@r%ZK<0QpR@noIyn*{5V7h{M zAs4Wa`vD8NfQ8(z2$O*BR*PvhDn(G^n-aSHeN}Et2J0#pZQPP>@<8hIV%tkBBQ>^y zz274~Y&e~D9dWd{+Nq`RNAgfE!q=FX;2S`bQA!)+)^YUyP97Xzem4`0Li@&{UO1V% ndy0y)o;DM=)8FpDJjvY|U<`~g+7I=oC-e8v7)Xt4HK~69Xtiui literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/serializers.cpython-312.pyc b/authentication/__pycache__/serializers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b84f5aad89499fb35db7f08d242790b3d1e2ce24 GIT binary patch literal 1481 zcmbtUL2DC16rS1HO}1&%rfJhQO{Er!u$Rz7p&-_S6-1;#EMC^auw?fiKz&|gYWGoO}9phbRl2fy!rOcoA151pVH|Rf#>9&>HVgJ ze8I)wG5SXLBN&IoB`)LYZK^@v3E^ z^ewO6ED!S|MDH)UH^De0g4on0wiYHqAqnk7ix@U*GD}z4L9Ctg^J4M(Y|>qb#S_fd zUFvGjHQT^Az4^c66t_j)QEXo{m0oo!qGTnM$vK*ws}$#zn%nTvp5Xj-!||gXi8WIO zYzki`_B`Rc!7=G#*1grO+q+M89_~7g`U_F5du6BY)vCJ}v?{)W)9_%4O_79OkO63s z)6Bwq<1{;eG0%9s(-3tpbgpKx-r~qGQS&A_cYL4o5wc-z zuaIpSD0tN%YM0YY0c4wAjCJ2g$!=h51T04XZEUszHd`T*54THJN=-@;)cKx-sd`(J z`;viQ<>CWU42LO@Va_;S5{s^;wsFRW(nU=k)+@{)-U>bQPBgH0Yv-QA(WB1NMtf=FCvc)G{Q*6% BCqV!J literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/serializers.cpython-39.pyc b/authentication/__pycache__/serializers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15023659c4ab49009668f81d5506e8046394654e GIT binary patch literal 1288 zcmb_b&2AGh5VqIe&E~g|wgUAHa>;=sLbMV{h(jaPh>I1;vSJ68?k2_F0LityOrM9F zubg-V#DSUJZo6#)iUgKCni=nYV}J9F>ULWM)|YR`$uCOCcMR%_LvRAy2{4*ynv#qP zO3@F}AY+1MT<|OuAtkSfW}1H`nj88dx@4jOnNUZNiLNs-WEwh#OnjYb>gJdXT0a1v z45)8AV-uAoYh&Gj`Sx3g-`K@0NsW)e`IOA3#`70RzMA4M^~E4Kf$fgK7$T@9B7lNa z2T(A$3@rmj*yMM2{(__5nDfD{h+zjQzK5G?>0ER(gAw zi@@M^NJ&hKc!RFp$?swF{sZy*cX0~RExy#oV1V=c4-E0FgQkn-hS%Ctkpn!uN0xo~ zryu%ofRGh882#`(6M5 literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/urls.cpython-310.pyc b/authentication/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a80cd0e75a462b1f60c589d1a3416c9aa7c9c365 GIT binary patch literal 545 zcmY+B%SuBr5QdX9=hC~l@DYT%=mUs|U^i|=EV>AV5}Rpz>baC8r&1Sgy7obQ3|}K# zS3ZJ*=)|^C1NoWxGRgc&ie|G$aP*&ECm)oMH=pc|0FyJE<`G2^MN^VdK{F;8^*Ku` z85jIFuB1U0iii^6DVJZfSmCY4hu?ZC| zRqc~b?H&7*4s%hGkJ3_s<8x`J9qO7r7|SxX*F|YTBM24=JQx?xb+N!=Kos9e1G&sV z@KIuyBEq$Cl7b_bowlp1nan3ex74Z84BO}mia5|<>~O4c+e4x6yZX0*(Hs|DOO|#D zxlKmWCPl9OJBgZy!*%;`UG8EHlfYp<_KkvG-!i{ Vj59_#Wi~6B%tW=0ns3ir3Ttd$xUJQsAkp^2>17*!l(vABg%7PaKbKCwua%U;P>EEOXOQ8EGQaj_4wG^%|pFUr3X zhfsBpDG*JEd?`(2V8Y4`qbr#TF!ciGDF4A!fw{6^s{b)~*M=-S z05FA?_S}wWVEe%8y73WLVb*g!%F*M7$#rL72mP>_FfU@_i5P*vYm7$mUXKCoFk~;9 zEIS}#B{8hpNxV;k*zMY}8wO1LQ(h6xz5IA3hjWe5z8iruZa%pXv;+FuH0JsP&{7nu zPb10zA!HRjA{22QBHR_W2%^vE3=Tr)>#e(;?e?S2vWkwtH-|^(+C4vX5|7?zYk(GS z8-0f`modgEx;?$jQ?xZ*_7pXz%YIs}jo067yxkZnr$~8izA{q+UY(I!sc~bjB7E%! zB3SwcWdW>az!^%Jr= RBb#$sGNq9&K6Vps{0H2^-XQ=0 literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/urls.cpython-312.pyc b/authentication/__pycache__/urls.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c74aa05f59d0f0b821c4e910ca69fd281a2c5e1 GIT binary patch literal 812 zcma)4J#W)M7{0U5ABpQ2wJ4xS6r~bFmZ&pA43vchp;i>hjZ~T3C3WyebhcY%qZ1$& z7*Kx$GXI1r>Ogc-1&E0)s4R5iy*S2YK;o74e%O|eCj1E@SR42O6X;>b5f&YJ(J=02JV>}45GUY7ld~k9FAhk!CKnrCmL9Mu z_4{7x#}SwBDeAJhUmUL&aA9&b^b=4foJUJRyP$7}rNY_*EoHI#IAI(RQdZd`QjxI0 z!(CyED0z?0;UIKzW9xQrd*?y#Zxua>?~W%I=AAI6S-|dcIbk``paf7tXOWBk(mok@YEApV`;u2EtcMHz0A|wqJZ3t5_P^@gO>6%TcXsPOe zbZXDopLCdul6;(&3LIZZJL^!_?7>8qsqGh~1&ttBCU9e1ywJrGivdx5B@N^-l`*#vG4@Y0^!>@7|YnUbmor(7O#?U4D8-Nw{6ZG<(Y+o4ASmAALnB(4&tE1vw z@rc|!5WVFMdU@UJ?GLkjF&_4%k!mINs6RLz{x>%CM|2k}7awGWDpNSbUnXW3Ws5dw TgN2M!MsdD{!A}(aMy>Y`Uz3^Z literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/views.cpython-310.pyc b/authentication/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21eb922d7c8b3fb1376e2ad448020d594cda4049 GIT binary patch literal 1079 zcma)4O>fgc5Z#R(+p(PwOj1x!+)yt40SF-~kPrtdL-psvEEcYaz#vdKg zM#j$rWP&x*L8g_5$b@UAn@1xyjDO(!Y{*S;UdV-(wWjz`scLaJTMiu)yoBn!m`$W{ zpA_}dM6b03IGIu=IGamYV)futvWF$Ei%BOc(;6J2lT!(0p>bN&gS(yIjf6FR^yqmb@p>Exz}U(gNf!fpSodq6V(=B)`Hu4eKP#~qqnj#VGRF(e?}pj(9FrilQ#^+gI=6B?a~%f;)&_(Z{EK5=Iy-Syw@-3bOMR-VfOFh zaR{Lw@DhwjOE~%_ge_zu6Whqa8pa@p?2w~qij);Q>_oJP6V;+lOp8ff*jAmm7IzX_ z!bxgLj6!G@nURmkj8eRu3O=%vpVemB`tGrpJCC}xG zVcT3?tx{GK95EG)eS(Nq%6iE*T$jOFd3J>|$8ue(Qf{iL`xPC*5&v9$ba(zm@yWbV z^_FPavr2|1yyhkIg_RnEYnK4=-8%v{PJRtC?32+0GOHPs2-6x}aWXvaHz{F$^CLqRKzK>@Zbv=E7iB4Fru(u5UW_Ye!S!fq?tGoxhi?<-! zhuW@e7bY`x|%H@Z(ZiwT@HWLd(Ccrz{bQ@EFSl_ zfI|gi+&~lc?%6=M>fQ4@x?k@-8|Zbt_dJX$_}U>l3!6*+(2ZYUIBr{0XZ_^f?aTg1 T;eVYsr~T~p)6OT~kZtl0G3kNh literal 0 HcmV?d00001 diff --git a/authentication/__pycache__/views.cpython-312.pyc b/authentication/__pycache__/views.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..515b16ee4a445cde82711f5a72a7e1f72cb06bec GIT binary patch literal 1497 zcmcgsO-~a+7@q0&WBWN+pg>I|l+O*O-i??b2R{;sk?3JVveb5vt-CGEY#}uqJaF+O zH~0&Nf8o`O8xBh*As##!Zzj|WC+FR5Z3|IuOwwoHedn3kd7k&3eo3bjNRH!2s@V!5 z^c`M0Bhn7eKg-|{RZs<6$i_Ox5QnUgt>}s$D^}Q!=n*@rN9~v%^K)TKwc~o+PUs0c zsV6ZCp~t8a*+-Qq#nsWyN4n2rC5ZL3&x}c?dJQwTt?wE9! zQ-?#mXj%2$#adHSg!-J-cg$Luitv)@G)3|yr%dKHOpD6tY-f6vGP7iv?Nl@i$mcG_e*Eq;tSm zQr{|dRrr$p~9nrpqhfec_qr4l=v0P`_4OyD) zsb|+!mWE?w00=+~U;yA2Ko$V*6&nNqtJo00Fn}*%1fsDHz)pWX$a|#Vl7dHOTrzV) z=D>ryS3H2VH{?MQdi>wwqoCrF_&DVLFa9=A0KgeukN^!Z_;K&UUeE+5WCEm5Uy%-r zR{C|jif3n!^(00!b_jhDb-U(`P{|+!;3KUc1FR{A)&;1+0 ze1%YBky?fw+WrK6?HAS;*kADr^+9k2AF>I#6w4o9mhel#7@wiZGj#6aH#_?qIDUiu0Y+;vn!C0)>1~#V>_NVo~+*w35*Zl9u+@3gnY+Id$=%p44=6G;Dl32 z6lIiR-H{#TFsG><>8dX4Dvx=}XMV%EGEhC%Qy~jg#3D+b5#HtAC&E2JPvegc>jUHS z0GMFM41nqJ5SVbs40$vs)A$G6Po~rc=Y?1sQ5&oerL5M6&_5hor=wAD{ID!^;&7`@^jL{C#$x>)l7*kZ`mKNqK(YIl#fnWEY-e0J4 znJ9Zg4epoOW^6Aj5(SNgriB(j66$-e4Vq;+X<^cIfVKcV;3h-uJ^{aO^f{68% zMl5Rf?JrH=Cgz^zRZby}=IO%DXr8kq$~;530~T?dvoy&>WsnjYXZO0&@8Y!x;11l` zPll#Z&DV+M8$|a_ioUgIrCAK`Il}Ge{M6XMvd`O)>|}{KN!ip=4TT%#};bV#zF>`7A4D1@Ln! z?(=}>0bNz&z5r+ekWO3uD}A@W*k2;oWNzfei3MX`e}?^~3-*@_`-Qh}DC6i@ z31T{VWdfRkO0PasrSseo%;c8J_1`P!!3^ez)TGGoKV}r!PtE!E|9{TpwM$iaoxDMc z8aU_qM5ez?+OQ|y6wdB+1MG|1K}Pv!JngZV3WJetVeE7~B)CA5b}aV|_4#WVOkY(IgLQ5*}q2fZ3YJN+7H&n&F&0Dm6DG>P&f-jeQakMS&5 z(>eW75>AXuEcbc{S)SG;Zx3;n9jBa}5*g3n%kWdi2r*;?Cdxg%q)H)zaD1|`daDaT zGcTLU6OKJgSYeEl2Zg(nCINg_XbuW-8cPWag^WBcg@-g^@IHngM+=T`@!y~ovlwq z{mg^WOw=~jV%(J~hljv}5ZSAd~l&U=(a|?nvaAz@e zwuTJXM30eW=q+PLmu>#6H340Rc1<^aLvzMs^ebAFel6uUqc@e+_zTs*_6KTSwq4bY zKT#d5zuP~nkv&J$ij>>kH0c!ua!Q7Ts+L6&R?f&aEC4u5+f#XX2WHMckey8CT$bYL ZBjAMnUa@N4*8yen&q3X2>Nd1R^B;tXN@xH8 literal 0 HcmV?d00001 diff --git a/authentication/migrations/__pycache__/0001_initial.cpython-311.pyc b/authentication/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd1db462491a31e0994a3c30fc17a3312d4229aa GIT binary patch literal 4654 zcmeHLO>7&-72aL0D3baktsjzNDAI|4MA@R{LMe*EEhLNjYwW}lMa5ziES8)Ry)?B{ zc9&9UAgB%j+G9?wZtY2J5gl~sK}Q{O@No#tftXW(oOGjMozhF+?2`Ji)YgW9CIK?b zeLL^Xw{K>?_hx6nzjbx_1Sr3s{a4{HenI$-E3MMjth{^-l|KteKw?Q)7qgrzQt zcV%7ca#pr=SE()Q2D_`&o^6+eSpmsk3aAacik_CkU6&wy4YyOW9^^_33HK3K6C(4N z*s?UeU?wEyTh|JPYH4NNWbXAc!X@*=eDgi~5o{_ihuitsu#gpzkd=^_bx8u2i> z*j)sKQ+7q@A8w}<#H`20dRrDGA^x_n*l}VJk%(l}w&&iJ;a#|$vL+#zBOp6l79{R@ z&ie<9_X5Uu0n=e)x=#Gadz}|BT{fn>g~2^Vh?P^I-|k%r#s;@jpx+)FA81*S9|Zt+ z%D;MyA;>|nz(@rxZtJ!La*S$fEv6oi-?W7axx2X@0|(&E;vv^E|$oQ9t2qDR^Ehq9Z>? z^bJn@?8@aNH6!fU{1K4R^Ph%xl+P^YPu_;wA{@QFA5` zm$wow;E1#DUej<1nXJ9M;hdQ~5Y|mi&*K(b9*i_g%|W2u6xUQ`}_l$w6PI!_Q9Hd)7%os19p zLD1kEH0!*t6(%7~XZXZfR|sb~nu1v$>VQ%_XG zvG;(tdELSV+%))R$_Ca7`UjBnZd6qDLYYY@$2@ju;aJMrrzX==lc{OuD{tWDQS~3f zOBkE*{aEVPtBdLR)${DFo}Ot}$HvC)Dot{d8&!iJQEkEZX7fv!;`Yh)ZTFS!*@j#2 z4*$_dJvaaEp~Dk3&m{FsHe6Dld;3AdCwODLZKxg?`Zmx{f+JsT(%{H}{QMfpDnvI( z(5wYb8Z?RD0t|_d|J6<7Kse6|*!rSVzfpF7iVfJl6*7N4T=DdJDn10gavx^sgL zj_zYJc&|2ij}G1={@>IC10*!OHI8LH-wdfp; z&Jq8--RJwf&-V|;No=APo1n1?;-9n|#(2Znz6Fz5d`uTVp^G`X_>?Z14MCWa9!v1} zRKn6Re^j^@-;`e15=>ABOJGZ~IlRlsy?Y=-_vsayUZv?gO_yle0!&KEa;PE|xGP24 z;@Z{Exhs%h0?A!f!BvoiM|K8icw}EbbbsTe6OZV`3Y}2N#uh-n5T`l*3o*lA7+mHq zK!OP*ck!{*i1ze#H{KNjk)3JCmHzI=^?tAKg#hB1i^lEK#EHB{;+&5*CQFY=Xr&ff zp`jJx&z{Mjw@)mXdxFnBv7bJ$NH|psr)W4u{L??qU^N0>V0z#T)8QV@G>Bs^8u3%6 zgFiFhD#Jh`1*@ii4Z^g os|&;AvS0lStS)qH+gHOqA&TyXaJl@-NB!4c*p0{k0b&pI-xj!f>Hq)$ literal 0 HcmV?d00001 diff --git a/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc b/authentication/migrations/__pycache__/0001_initial.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98b6bfab8e9436a10f682b151d98d9af71704087 GIT binary patch literal 5106 zcmeHLO>7&-72aL0s3rAB+OkMW7D>CZEy@-x7jjV)X+c?(Y&CXblcHlYGPX<3h+cZN zRCbqAXdpleHKrg!}ffXi)2IxsQ7Ish|r@q-GV@jeOJ4I6z zFb}))-hA`T%s21N%<``T1AYd6+t&p7j{%1H2Q}Kio>t*$9twY85QA8SS!44oOUsNo*f3C7vP>FkTg^j}cvCodS$#Pf_R4We_1m)V{3?HGj-^5t&1 zeBm{7`E_%OhuE8Jj{?^3f3+7RoHgo}%``tdv*S(FGw2nfz9hVIj7`0Xu{SYxbiaR< z7(*9-)SdMbn%?Q$MSVvjyyVG;YstiA;=9$pkS&wGoQ}2IT4hyMFyUmhNVuhRf+zh_ z)u@O?4NC?_q;Fl5*CeebKEgHPgBG%+$d57U-@sa-qGM5&)-dUF;Ua=Ia0hfL)XJtP zA)tVppS)UYR|*b4RFWP;lk|sx??rf3swxKYKrabSqlYo!)vBTpVHKWEAI!n;!JY89 zwf;5fLs7wM$#|&I`yBDF%9?IC!#Q|D9X>^B+4SyNfLR{&QNOS*>H20xLkEcRaT>jl zwKxhA%m}KmmS9`1mJnj0_W0zv$s&;I3B4^(p_b?&Jq1NlAGvT}MHS(iiw#gn!wQwq zRfsbxEg@uZ0om|#GDjb97ixsBg2beUKJ^6eaBAo1_~>m$y8sU&NCh2)D;fz8XhhZb zuF63?(oTW#XE@z5kzNRqDcIr2otC(7|Q*k_(4^2)(fm&S(Ocl7mZ%2$*{gD zt*_HTfI{n7MOZD?H2MuehURk1H^f|aAtT;;H@$F^^nZttu}=EtonX90KOi)Er6T>; z*pn%1GW9oMuIb^1y&vCf`Wau0R!1!%x*v>w9Xw@*ras-ULsM30YL9<1Vdh0s z)fyq)3>W|~*c_eSI&Y6oTcgvvxH0;c z8TjRXaKsExZh7tSq!pgr9sbMc=cB+Ac6r9k@#(F*_V~0lKD}G0XP+32@ntiR+YgSL zvCCThhyS&HMb@NWH5xZ*!-rEnJHlxX{RXdurqRCyYUNmnnH=;Q+aCbi#F~=@$ z{mdS_XpLRmy;lF}lXPS3jv2`82RnP(J6WG?jNdQ=OHMymX+Kx3*www+Ml59p<{a+~ z_0CwanO&nkVP@{xnfI;C`*x;aWeRrYk(GI5XLKv0HyLK0yT`%n0f)JN(N~rGr~7)w zF!2pq72M<;(XLP_uUPRbdwhM?%-*-ND^_;J&K9j~(atJXR5b=ywew^H}*lw_qObA1!I zK4KRr*GFuQa?uxXjox**-s76%L&Jm3vrKSoYXO4g)Znvor+ohAr9<&D_I>fvWwo)n ze6JC{ZwB&*1Luc@6HGWkC!DY%iQVj;(TJqYz{3B}k~M=qka?s-=ExAp96uy;=#9+( zab`fqC+Xgjw8oRW>H6ZAOJ6M6>18XuY^NVs=?8WiTWJhwQDxIK1(vu1&4*~w$p^$W zPx@h@!W|1W7J!9%m;Lz(?{9yt-E42b2_NZmH~eI=qOQ8fldt7L1?MDlkD$nR&LkXv z@XuDVeK=@~lx?m}sl820P7k-B^sVrgdtClXy8|Zu-%6+Fdeg(Q>^EM9J@a>F@+&6( Z71Q_3n_^k-r+zyyVFf0>VW{O0{TuwaSn>b> literal 0 HcmV?d00001 diff --git a/authentication/migrations/__pycache__/0001_initial.cpython-39.pyc b/authentication/migrations/__pycache__/0001_initial.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eee51c076b4214c31b7757ac36e1a5977a2169bb GIT binary patch literal 2095 zcmd5-y>r||6xZjSbRYKFzW4(|2qcCmz+q;n7$%ABv%!D^ng-X?AMVqy zTAKEg1eY%hzytX44KP^4dZG<Mj&-#7p(daiG8?xbdS+rk^eixQxP|9{nV*=zER;<9oVoTKvsf}q=P}EQSpocl%KIYV zc|h0IxGw=(0Hl+4d@ZiUi}4b^A#1}gPiz?T<`w=|F8NIq+rr(QZh!+(Kjegc#@Y#;qaxhR(f~dyBnO2UNu-2@LPnmILQtR}S^FZH(g)~pEUXboENp4HXQ`a* zmYm;hX;#4q2ZbDj>*bya8cFpleM%C{MKv21-!=!@`h=!EGF8hVnC2*iMps5DeLN!U zu1sZZ(tHepl+mKu0~}1@=@NA6n4~%Fsc&Xy>Uij_2q#c=1%apq0TeJw2s}4};PD8l zegUe|l;*Hrm?;Nq^Aj{2%1MAiLy}^W_Qnjpv6`4&KRoy_INaab3wA&4Zhaye=Mj`} zQQuUHaaVq@nLH>&V}nNPuuQjQ;iB0Eoe$`M6tJ<8WeGuPf!xExoo?}HjYbrMxM1HE z?&dLK1wRYfcG8?gq$FzF86z}GKZZ45!7)msOc*#6j%qC&AELUszQ4KN-4eBINXjGS zTaE3&hMngB1^9VThS&nk73~ldRC&9z1yL zt>2(3?RW4iRM^8ZS5Mwjwx^zaGrMUi>%p>bl9%6`dGF2pmv8g)4g&gV?QOr&5&A8K zifR)uS^=twb;ak*(vO2PdX+dsJiA;$kK`{Y5B2}bn_gvsnqq~!t;94;WaygUz zvsIeNeq8F>b+f--I>=u9>I|%f;jMeaYd44P^6tZdyZn9i$Zh;`8w0md)(zV^M!-%a zo6TbB(s%r)#nKJe?7x;PyHn-9;TgiF?SMyVgML)aQ7su)=eAT+x_1GcS}WrYKhG9H pl>b%!0a&SHjG)sweESA;z|Guu!-C@T97Gv7D!y_fgiynI?+b%C_eU7I~J0QjOv zWwiyEcO-ZR2p}*4DGXqW0t5j9_W?l%fEX0^tjcM*k7PV$fiX1w+E)dAB;1t6d04WH z7s5(2LX#p=SC#2>B$;=h`X~hfBp^Tp#xO7tpk}X9R336Ch^RZOxAxQF0uuA6Hj=TF z9a&XUe~45+qe%9df-3AGjcm?B^gD_F9iV@nUoKPMyTI6a@guPA3jtZHZin=>V7MA)zxLKbrM&<*U z%Uf{r?B4C}lcx{5zgE;;&Q@2}b_=VLa1xdaz++rxs!x}M$F2S_S3|591&WVyIRG;Y zI5%bnI&Zz+ow>l-c7gEsA8h88>+4I3e*O_6*lP2+zaK zS5Dk|u7qIhcC~F)iHSU#-^}-oE%)~eg7Wp}EB&4k@+&wug`;zTXL^DP2v9>hTG1}4 z5=!0@NPvAOz!Y7vZ>(a#Pe_^m##&M)zUXv2N~e1}`B~S4GE);$Hzh~s0MBGmDN<1& zRRXl76;phbh5>4}ngfUQoWksU8=c=1&F-zu;7)DJs|<1kTKN3q79qlYAlL4bvQ9S< zv)@}TmrsSZ+G%M#Z?xNZ_CdOlBGi)lIjA$aHm+pIG_Vs^cFOap(=)9MV7+a9HjMoj zZ5wq|<~|d#ObA~Hfo*G}(B2c`^IDqF8az;gvY>3E)ifqJ&S$Ry4#O`;ye8s{L(@wa z1HR}7b-m^vWPF6_s4h?6Jg+-DH1)BZBy8j;j!)jzw@KE!E2@$1GZ9z{Bi*%OTd@Tn zqdUj8i(xZ{_c6mWEl_1F`O8yI6a0!l|FJG&?@`Hp4l8NfegUVEY9ttwJ1$q&W1Qi$ Q7gtMr8TK%R-8^Lf01j5WBme*a literal 0 HcmV?d00001 diff --git a/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc b/authentication/migrations/__pycache__/0003_auto_20250809_1248.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c80288b6511775b988e59966dbe276405c281e69 GIT binary patch literal 1392 zcma)5F>ljA6n}2f zBOAW~g@3}-snrcEOl+3YE}b}^6Q!V}@(q{wefi$I_nzPTxwwcyoZ%D0Z|VTQb1*rT zu`${b#y6lqQ2gINtzX z-C^BmpFQ(gKsk?VYzT+W&T;J>8SG=*L|m{*Fki(YoK*Y&;;% z*1gU3UK;27DKD|O(BBZda{!qR<{Ol$$~FDds|W4=C_{PfdmHJ6VHF0MA z&#%nkug~G<#hJ%1&x*4;Cm+Gj%t!Du^SL0-%zT7?oXf5k^jYlll~ryzjz F{tJRQDt7c*5BC-WW?j#wo4l5h-B63s&-k zbM}^j2mWUUKJvBq$xl28E?6A?pg0zDD@vW$s@0Wgvfee8`(&KbYQB;}mT+K{&U2pl z7_7sd7=ka}9)}}58R3Hwjz)O;7mE>(fPqKAz$0Mb5isxwa6I`unZS%1o7?HTyN+Vd z-c#H58cnM+*JH9ES;|beoh($l2PT)By1LOOL+2d~liQ#VwzI58)uIGaL@UY)u#iTT zXalFkE&$|ZXZ`m`85E+gG&;}D=v=xD+gdf(Ho7Zw9v|39Ix;D(kdiXD1rnZ1`C+Sy zzCdpQZqNXlOk-1f^d@$;!m_%-HyR7DqT1m8DZjD$0i8Sb^X&EWv^1M6U8zPvr)s&n zI7|N>Ogemnlt%Pe(s3o1i{;bB$>NzjUOqWF+H|!~r1bq*b44ohz289?aF2Vxg5W>x ox31=S?As}d=*4b;FZ@C;7<@d1%!mTdg?8ZiqMlYn}paoy#2m6@4flHnfM$kR38Mxzk?e+x(%Ozq*u^3}Xz%wVM+?rM{r z-oi|loJTsuF@^bNrbx_BQDw8&E` zEJ|fvJK_>AQu?9oN2*pa##=mQJPtyhrRs78dCJ&xH6t|?HTUa&T5w?{Ek3>GZ!lKg zFL(DJRo}jQS-tA8I)9I<^tvsbOnlL~t<6>^RS#SQ1+phHoWKZ!`Cz1L*YT&M!%Tig3l(}FgA6-GB>jNllvpJCCY zpg;-+bU_QQ#VQE|dbApYfCNUD491rnXDOseH1U&n{}_<&mRb)>ZHKywoWBEjds2Q}D-(7D0^Ml~+E%sh9YZFcJ_mRe?r=Q7 z$&00O5&Nv|^xtRuO5AOn#`5d!%g1G7yQ(}@y@Ctn;7pl J)CZFX{13~uq^1A> literal 0 HcmV?d00001 diff --git a/authentication/migrations/__pycache__/__init__.cpython-310.pyc b/authentication/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de4dd3ae6d56c19eb97568f6c12e0e37d4b7621d GIT binary patch literal 146 zcmd1j<>g`kg5bJ?=^*+sh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6w%#VV#Ku{bfM zGO;KoDA+S5v9u&3HLoNyIk6-&KQAUXGrb7RDvpVd&&>P{wCAAY(d13PUi1CZpdvx;Nl<1_OzOXB183Mzkb*yQG?l;)(`6|n*}GXilji1Cq` Lk&&^88OQg`kf{M%bnIQTxh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6wt#VRH@uOK-l zD6u#(r82Q7J}B5TCb6_6BQ>uiGdZy&Ge0jTH#5Bm%qotFkI&4@EQycTE2zB1VUwGm PQks)$2Qu?B5HkP(I5Q+K literal 0 HcmV?d00001 diff --git a/authentication/models.py b/authentication/models.py new file mode 100644 index 0000000..aeaa3c6 --- /dev/null +++ b/authentication/models.py @@ -0,0 +1,67 @@ +from django.db import models +from django.conf import settings +import uuid +from django.contrib.auth.models import User + + +class BaseModel(models.Model): + key = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) + create_date = models.DateTimeField(auto_now_add=True) + modify_date = models.DateTimeField(auto_now=True) + created_by = models.ForeignKey( + settings.AUTH_USER_MODEL, + related_name="%(class)s_createdby", + on_delete=models.CASCADE, + null=True, + blank=True, + ) + modified_by = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="%(class)s_modifiedby", + null=True, + blank=True, + ) + trash = models.BooleanField(default=False) + + class Meta: + abstract = True + + +class Province(models.Model): + name = models.CharField(max_length=200, null=True) + tel_prefix = models.CharField(max_length=200, null=True) + Lat = models.FloatField(default=0) + Lng = models.FloatField(default=0) + + def save(self, *args, **kwargs): + super(Province, self).save(*args, **kwargs) + + +class City(models.Model): + province = models.ForeignKey( + Province, on_delete=models.CASCADE, related_name="city_province", null=True + ) + name = models.CharField(max_length=200, null=True) + Lat = models.FloatField(default=0) + Lng = models.FloatField(default=0) + + def save(self, *args, **kwargs): + super(City, self).save(*args, **kwargs) + + +class UserProfile(BaseModel): + key = models.UUIDField(default=uuid.uuid4, editable=True, null=True) + user = models.ForeignKey( + User, on_delete=models.CASCADE, related_name="users", null=True + ) + fullname = models.CharField(max_length=150, null=True, default="") + first_name = models.CharField(max_length=200, null=True, default="") + last_name = models.CharField(max_length=200, null=True, default="") + mobile = models.CharField(max_length=11, null=True, default="") + password = models.CharField(max_length=100, null=True) + base_order = models.BigIntegerField(null=True) + + def save(self, *args, **kwargs): + self.fullname = self.first_name + " " + self.last_name + super(UserProfile, self).save(*args, **kwargs) diff --git a/authentication/serializers.py b/authentication/serializers.py new file mode 100644 index 0000000..0db5ea2 --- /dev/null +++ b/authentication/serializers.py @@ -0,0 +1,21 @@ +from rest_framework import serializers + +from authentication.models import UserProfile, Province, City + + +class ProvinceSerializer(serializers.ModelSerializer): + class Meta: + model = Province + fields = ['key', 'name'] + + +class CitySerializer(serializers.ModelSerializer): + class Meta: + model = City + fields = ['key', 'name'] + + +class UserProfileSerializer(serializers.ModelSerializer): + class Meta: + model = UserProfile + fields = '__all__' diff --git a/authentication/tests.py b/authentication/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/authentication/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/authentication/urls.py b/authentication/urls.py new file mode 100644 index 0000000..8ee804f --- /dev/null +++ b/authentication/urls.py @@ -0,0 +1,25 @@ +from django.urls import include, path +from rest_framework.routers import DefaultRouter +from authentication import views as auth_views + +router = DefaultRouter() + +router.register( + r'province', + auth_views.ProvinceViewSet, + basename="province" +) +router.register( + r'city', + auth_views.CityViewSet, + basename="city" +) + +router.register( + r'profile', + auth_views.UserProfileViewSet, + basename="profile" +) +urlpatterns = [ + path('', include(router.urls)) +] diff --git a/authentication/views.py b/authentication/views.py new file mode 100644 index 0000000..a2dd3a2 --- /dev/null +++ b/authentication/views.py @@ -0,0 +1,23 @@ +from rest_framework import viewsets +from rest_framework.permissions import AllowAny + +from authentication.models import Province, City, UserProfile +from authentication.serializers import ProvinceSerializer, CitySerializer, UserProfileSerializer + + +class ProvinceViewSet(viewsets.ModelViewSet): + queryset = Province.objects.all() + serializer_class = ProvinceSerializer + permission_classes = [AllowAny] + + +class UserProfileViewSet(viewsets.ModelViewSet): + queryset = UserProfile.objects.all() + serializer_class = UserProfileSerializer + permission_classes = [AllowAny] + + +class CityViewSet(viewsets.ModelViewSet): + queryset = City.objects.all() + serializer_class = CitySerializer + permission_classes = [AllowAny] diff --git a/cron_for_city.py b/cron_for_city.py new file mode 100644 index 0000000..60338e6 --- /dev/null +++ b/cron_for_city.py @@ -0,0 +1,11 @@ +import os +import django + + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "RSI.settings") +django.setup() + +from app.views import fix_province, fix_city + +fix_province() +fix_city() \ No newline at end of file diff --git a/cron_for_code.py b/cron_for_code.py new file mode 100644 index 0000000..74a79b2 --- /dev/null +++ b/cron_for_code.py @@ -0,0 +1,8 @@ +import os +import django + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "RSI.settings") +django.setup() + +from app.views import update_product_date_cron +update_product_date_cron() \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..57fabf6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +services: + web: + build: ./ + volumes: + - .:/app + ports: + - "8000:8000" \ No newline at end of file diff --git a/helpers.py b/helpers.py new file mode 100644 index 0000000..ba18a23 --- /dev/null +++ b/helpers.py @@ -0,0 +1,26 @@ +import jdatetime +from rest_framework.pagination import PageNumberPagination +from django.db.models import Q + + +class CustomPagination(PageNumberPagination): + page_size = 10 + page_size_query_param = 'page_size' + max_page_size = 100 + + +def convert_to_miladi(year=None, month=None, day=None): + date = jdatetime.datetime(year, month, day).togregorian() + return date + + +def build_query(fields, value): + query = Q() + for field in fields: + query |= Q(**{f"{field}__icontains": value}) + return query + + +def build_calculation(queryset, column_name, aggregate_func): + result = queryset.aggregate(total=aggregate_func(column_name)) + return result['total'] or 0 diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..ff16eae --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'RSI.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e850076 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,21 @@ +asgiref==3.8.1 +beautifulsoup4==4.12.3 +boto3==1.22.2 +cached-property==2.0.1 +Django==4.2.19 +django-cors-headers==4.7.0 +django-filter==25.1 +django-url-filter==0.3.15 +djangorestframework==3.15.2 +enum-compat==0.0.3 +fuzzywuzzy==0.18.0 +jalali-core==1.0.0 +jdatetime==5.2.0 +openpyxl==3.1.2 +psycopg2==2.9.10 +requests==2.27.1 +six==1.17.0 +sqlparse==0.5.3 +typing-extensions==4.12.2 +tzdata==2025.1 +python-dotenv