import datetime
import hashlib
import random
import re
import difflib
from collections import defaultdict, Counter
from datetime import timedelta
from io import BytesIO
import xml.etree.ElementTree as ET

import jdatetime
import openpyxl
import requests
from bs4 import BeautifulSoup
from dateutil.relativedelta import relativedelta
from django.contrib.auth.models import User, Group
from django.db.models import Q, F, Sum, Avg, Count, Min
from django.http import HttpResponse
from django.http import QueryDict, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from oauth2_provider.contrib.rest_framework.permissions import TokenHasReadWriteScope
from oauth2_provider.models import AccessToken
from openpyxl import Workbook
from openpyxl.styles import Alignment
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import api_view, permission_classes
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from url_filter.integrations.drf import DjangoFilterBackend
from LiveStock.helpers import build_query
from panel.ProvinceOperator.serializers import PoultryScienceReportSerializer
from panel.filterset import PoultryScienceReportFilterSet
from authentication.filterset import (
    SystemUserProfileFilteSet
)
from authentication.models import SystemUserProfile, Province, SystemAddress, City
from authentication.register import ARTA_REGISTER
from authentication.sahandsms.sms import USERNAME_SMS_FINANCIAL, PASSWORD_SMS_FINANCIAL, kill_house_price
from authentication.serializer.serializer import SystemUserProfileSerializer
from authentication.sms_management import send_sms_for_kill_house_not_add_to_inventory, send_sms_for_guild, \
    send_sms_for_guild_for_register, steward_allocation_sms, guild_register_password, guild_register_username, \
    send_sms_for_sale_bar_for_steward, send_sms_for_sale_bar, send_sms_request
from authentication.views import ARTA_URL_CHANGE_MOBILE_NUMBER

ARTA_URL_CHECK_USER_EXISTS = "https://userbackend.rasadyar.com/api/check_user_exists/"
from general_urls import base_url_for_sms_report
from helper_eata import chat_id_mali, token
from panel.ProvinceOperator.serializers import \
    NewProvinceAutoAllocationSerializer, GuildsSerializer
from panel.ProvinceOperator.helpers import guild_steward_allocations_product_warehousing
from panel.KillHouse.helpers import kill_house_allocations_product_warehousing, kill_house_archive_warehousing
from panel.ReportingPanel.filterset import (
    PoultryRequestFilterSet,
    KillHouseRequestFilterSet,
    CityOperatorCheckFilterSet,
    ProvinceOperatorCheckFilterSet,
    VetOperatorCheckFilterSet,
    PoultryHatchingFilterSet, PoultryFilterSet, UserProfileFilterSet
)
from panel.ReportingPanel.models import SearchFields
from panel.models import (
    PoultryRequest,
    KillHouseRequest,
    CityOperatorCheckRequest,
    ProvinceCheckOperatorRequest,
    VetCheckRequest,
    Poultry,
    PoultryHatching, ProvinceKillRequest, ProvinceFactorToKillHouse, KillHouseAssignmentInformation,
    KillHouseFactorToProvince, PovinceInspector, CityOperator, ProvinceOperator, VetFarm, KillHouseVet,
    ProvinceAutoAllocation, KillHouse, IranProvinces, IranCities, AgeNotificationPoultry, CookieSamasat, LastUpdate,
    Wallet, KillHouseFreeSaleBarInformation, KillRequest, KillHouseFreeBarInformation, ChickenCommissionPrices,
    RolesProducts, ColdHouse, StewardAllocation, ProductsTransactions, PosMachineTransactions, POSMachine, Guilds,
    PosSegmentation,
    PoultryRequestQuarantineCode, ChainAllocation, ManagementSendSms, StewardFreeSaleBarInformation, POSTransactions,
    SmsRecipient, EvacuationHatchingDetail, HatchingLossManagement, ChickenAgeRange, PoultryScience,
    PoultryScienceReport, WarehouseArchive
)
from ticket.helper import send_image_to_server_for_poultry_science
from panel.poultry.serializers import (
    PoultryRequestSerializer,
    PoultrySerializer,
    PoultryHatchingSerializer, PoultryRequestForGeneralCasestatusSerializer,
    ChickenCommissionPricesForDashboardSerializer
)
from ticket.models import MessageSupport, TicketSupport
from .helper import (
    poultry_request_fields,
    user_fields,
    city_operator_fields,
    province_operator_fields,
    kill_house_operator_fields,
    vet_operator_fields,
    poultry_hatching_fields, poultry_filterset_fields, poultry_hatching_filterset_fields
)
from .serializer import SearchFieldsSerializer, DetailsGeneraWageSerializer, GenaeralWageSerailizer, \
    DashboardDetailsGeneraWageSerializer, NewDetailsGeneraWageSerializer, IranProvinceSerializer, IranCitiesSerializer, \
    AgeNotificationPoultrySerilizer, CookieSamasatSerilizer, HatchingLossManagementSerializer
from ..KillHouse.helpers import kill_house_allocations_product_warehousing, market_poultry_request_remain_quantity, \
    kill_house_cold_house_allocations, cold_house_warehousing, kill_house_free_buying_product_warehousing, \
    kill_house_free_sale_product_warehousing
from ..ProvinceOperator.helpers import guild_steward_allocations_product_warehousing, \
    guild_steward_free_sale_product_warehousing
from ..admin import PROJECT_API_KEY
from ..convert_date import convert_to_miladi
from ..helper_excel import percent_of_losses, create_value, create_header, create_header_freez, shamsi_date, \
    excel_description, to_locale_str, convert_str_to_date
from ..helper import check_mobile_number
from ..validate_headers import PosDeviceValidator


def check_quarantine_code(code):
    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')
    try:
        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:
                                return True
    except:
        return False


class CustomPagination(PageNumberPagination):
    page_size = 10


class ReportingAllPoultryRequests(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    city_queryset = CityOperatorCheckRequest.objects.all()
    province_queryset = ProvinceCheckOperatorRequest.objects.all()
    kill_house_queryset = KillHouseRequest.objects.all()
    vet_queryset = VetCheckRequest.objects.all()
    poultry_hatching_queryset = PoultryHatching.objects.all()
    serializer_class = PoultryRequestSerializer
    permission_classes = [AllowAny]
    filter_backends = [DjangoFilterBackend]
    filterset_class = PoultryRequestFilterSet
    kill_house_filter_class = KillHouseRequestFilterSet
    city_operator_filter_class = CityOperatorCheckFilterSet
    province_operator_filter_class = ProvinceOperatorCheckFilterSet
    vet_operator_filter_class = VetOperatorCheckFilterSet
    poultry_hatching_filter_class = PoultryHatchingFilterSet
    filterset_fields = poultry_request_fields
    user_filterset_fields = user_fields
    city_operator_filter_fields = city_operator_fields
    province_operator_filter_fields = province_operator_fields
    kill_house_operator_filter_fields = kill_house_operator_fields
    vet_operator_filter_fields = vet_operator_fields
    poultry_hatching_filter_fields = poultry_hatching_fields

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)

        query_val = []
        city_operator_query_val = []
        province_operator_query_val = []
        kill_house_operator_query_val = []
        vet_operator_query_val = []
        poultry_hatching_query_val = []
        user_val = []
        poultry_query_li = []
        hatching_poultry_li = []
        limited_query = []
        city_limited_query = []
        province_limited_query = []
        kill_house_limited_query = []
        vet_limited_query = []
        poultry_hatching_limited_query = []
        limited_dict = {}
        province_limited_dict = {}
        city_limited_dict = {}
        kill_house_limited_dict = {}
        vet_limited_dict = {}
        poultry_hatching_limited_dict = {}
        user_query = []
        user_dict = {}
        values_item = []
        total_tons = []
        if 'type' in request.GET:
            if request.GET['value'] != "":
                if request.GET['type'] == 'filter':
                    if 'value' in request.GET:
                        values = request.GET['value'].split(',')
                        for item in values:
                            if item != "":
                                values_item.append(item)
                        for val in values_item:
                            if not query_val:
                                for item in self.filterset_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (self.filterset_class(data=query, queryset=self.queryset)).filter():
                                        ps = self.filterset_class(data=query, queryset=self.queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            limited_query.append(query)

                            if not city_operator_query_val:
                                for item in self.city_operator_filter_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (
                                            self.city_operator_filter_class(data=query,
                                                                            queryset=self.city_queryset)).filter():
                                        ps = self.city_operator_filter_class(data=query, queryset=self.city_queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            city_limited_query.append(query)

                            if not province_operator_query_val:
                                for item in self.province_operator_filter_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (self.city_operator_filter_class(data=query,
                                                                        queryset=self.province_queryset)).filter():
                                        ps = self.city_operator_filter_class(data=query,
                                                                             queryset=self.province_queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            province_limited_query.append(query)

                            if not kill_house_operator_query_val:
                                for item in self.kill_house_operator_filter_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (self.kill_house_filter_class(data=query,
                                                                     queryset=self.kill_house_queryset)).filter():
                                        ps = self.kill_house_filter_class(data=query, queryset=self.kill_house_queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            kill_house_limited_query.append(query)

                            if not vet_operator_query_val:
                                for item in self.vet_operator_filter_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (
                                            self.vet_operator_filter_class(data=query,
                                                                           queryset=self.vet_queryset)).filter():
                                        ps = self.vet_operator_filter_class(data=query, queryset=self.vet_queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            vet_limited_query.append(query)

                            if not poultry_hatching_query_val:
                                for item in self.poultry_hatching_filter_fields:
                                    query = QueryDict('{0}={1}'.format(item, val))
                                    if (self.poultry_hatching_filter_class(data=query,
                                                                           queryset=self.poultry_hatching_queryset)).filter():
                                        ps = self.poultry_hatching_filter_class(data=query,
                                                                                queryset=self.poultry_hatching_queryset)
                                        filtered_city_operator = ps.filter()
                                        if filtered_city_operator:
                                            poultry_hatching_limited_query.append(query)

                            if not user_val:
                                for user_item in self.user_filterset_fields:
                                    query = QueryDict('{0}__exact={1}'.format(user_item, val))
                                    if (SystemUserProfileFilteSet(
                                            data=query,
                                            queryset=SystemUserProfile.objects.all())
                                    ).filter():
                                        ps = SystemUserProfileFilteSet(
                                            data=query,
                                            queryset=SystemUserProfile.objects.all()
                                        )
                                        filtered_poultry_user = ps.filter()
                                        if filtered_poultry_user:
                                            user_query.append(query)

                        for i in limited_query:
                            for key, value in i.items():
                                limited_dict[key] = value
                        if len(values_item) != len(limited_dict):
                            pass
                        else:
                            for i in PoultryRequest.objects.filter(**limited_dict):
                                query_val.append(i)

                        for i in city_limited_query:
                            for key, value in i.items():
                                city_limited_dict[key] = value
                        if len(values_item) != len(city_limited_dict):
                            pass
                        else:
                            for i in self.city_queryset.filter(**city_limited_dict):
                                query_val.append(i.poultry_request)

                        for i in province_limited_query:
                            for key, value in i.items():
                                province_limited_dict[key] = value
                        if len(values_item) != len(province_limited_dict):
                            pass
                        else:
                            for i in self.province_queryset.filter(**province_limited_dict):
                                query_val.append(i.city_request_Poultry.poultry_request)

                        for i in kill_house_limited_query:
                            for key, value in i.items():
                                kill_house_limited_dict[key] = value
                        if len(values_item) != len(kill_house_limited_dict):
                            pass
                        else:
                            for i in self.kill_house_queryset.filter(**kill_house_limited_dict):
                                query_val.append(i.province_request.city_request_Poultry.poultry_request)

                        for i in vet_limited_query:
                            for key, value in i.items():
                                vet_limited_dict[key] = value
                        if len(values_item) != len(vet_limited_dict):
                            pass
                        else:
                            for i in self.vet_queryset.filter(**vet_limited_dict):
                                query_val.append(
                                    i.kill_house_request.province_request.city_request_Poultry.poultry_request)

                        for i in poultry_hatching_limited_query:
                            for key, value in i.items():
                                poultry_hatching_limited_dict[key] = value
                        if len(values_item) != len(poultry_hatching_limited_dict):
                            pass
                        else:
                            for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict):
                                poultry_query_li.append(i.poultry)
                                hatching_poultry_li.append(i)

                        for i in user_query:
                            for key, value in i.items():
                                user_dict[key] = value
                        if len(values_item) != len(user_dict):
                            pass
                        else:
                            for i in SystemUserProfile.objects.filter(**user_dict):
                                user_val.append(i)

                if 'hatching_date' in request.GET:
                    date_li = []
                    query_li = []
                    if request.GET['hatching_date'] != "":
                        date = request.GET['hatching_date'].split(',')
                        date_split_1 = date[0].split('-')
                        date_split_2 = date[1].split('-')
                        main_date_1 = datetime.datetime(
                            int(date_split_1[0]),
                            int(date_split_1[1]),
                            int(date_split_1[2])
                        )
                        main_date_2 = datetime.datetime(
                            int(date_split_2[0]),
                            int(date_split_2[1]),
                            int(date_split_2[2])
                        )
                        date_li.append(main_date_1)
                        date_li.append(main_date_2)
                        for i in PoultryHatching.objects.all():
                            if date_li[0] <= i.date <= date_li[1]:
                                if i.poultry not in poultry_query_li:
                                    poultry_query_li.append(i.poultry)

                if 'hatching_info' in request.GET:
                    serializer = PoultryHatchingSerializer(hatching_poultry_li, many=True)
                    data = {'hatching_info': serializer.data}
                    return Response(data, status=status.HTTP_200_OK)

                if 'number_of_incubators' in request.GET:
                    if request.GET['number_of_incubators'] != "":
                        num = request.GET['number_of_incubators'].split(',')
                        for i in PoultryHatching.objects.all():
                            if int(num[0]) <= int(i.quantity) <= int(num[1]):
                                if i.poultry not in poultry_query_li:
                                    poultry_query_li.append(i.poultry)

                if 'number_of_requests' in request.GET:
                    if request.GET['number_of_requests'] != "":
                        num = request.GET['number_of_requests'].split(',')
                        for i in Poultry.objects.all():
                            if int(num[0]) <= int(i.number_of_requests) <= int(num[1]):
                                if i not in poultry_query_li:
                                    poultry_query_li.append(i)

                if 'total_capacity' in request.GET:
                    if request.GET['total_capacity'] != "":
                        num = request.GET['total_capacity'].split(',')
                        for i in Poultry.objects.all():
                            if int(num[0]) <= int(i.total_capacity) <= int(num[1]):
                                if i not in poultry_query_li:
                                    poultry_query_li.append(i)

                if 'tons_for_slaughter' in request.GET:
                    total = 0
                    total_li = []
                    if request.GET['tons_for_slaughter'] != "":
                        tons_date = request.GET['tons_for_slaughter']
                        date_split = tons_date.split('-')
                        main_date = (jdatetime.datetime(
                            int(date_split[0]), int(date_split[1]),
                            int(date_split[2])).togregorian())
                        for item in self.queryset:
                            if item.send_date.strftime("%Y-%m-%d") == main_date.strftime("%Y-%m-%d"):
                                total += item.quantity
                                total_li.append(item)
                        serializer = self.serializer_class(total_li, many=True)
                        return Response({'poultry_req': serializer.data, 'total_quantity': total})

                if 'total_tons_in_date' in request.GET:
                    if request.GET['total_tons_in_date'] != "":
                        age_li = []
                        total_tons_split = request.GET['total_tons_in_date'].split(',')
                        total = 0
                        splited_date = total_tons_split[0].split('-')
                        date1 = jdatetime.date(
                            int(splited_date[0]),
                            int(splited_date[1]),
                            int(splited_date[2])
                        ).togregorian()
                        for item in PoultryHatching.objects.all():
                            if item.date != None:
                                date2 = datetime.date(
                                    int(item.date.year),
                                    int(item.date.month),
                                    int(item.date.day),
                                )
                                age = (date1 - date2)
                                if 48 >= age.days >= int(total_tons_split[1]):
                                    total += item.quantity
                                    total_tons.append(item.poultry)
                                    age_li.append(age.days)

                if 'show' in request.GET:
                    if request.GET['show'] == 'active':
                        poultry_req = self.queryset.filter(final_state="pending")
                        serializer = self.serializer_class(poultry_req, many=True)
                        return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)
                    if request.GET['show'] == "deactive":
                        poultry_req = self.queryset.filter(final_state="complete")
                        serializer = self.serializer_class(poultry_req, many=True)
                        return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)
                    if request.GET['show'] == "all":
                        poultry_req = self.queryset
                        serializer = self.serializer_class(poultry_req, many=True)
                        return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)

                serializer = self.serializer_class(query_val, many=True)
                user_serializer = SystemUserProfileSerializer(user_val, many=True)
                poultry_serializer = PoultrySerializer(poultry_query_li, many=True)
                final_output_data = {
                    'poultry_req': serializer.data,
                    'poultry': poultry_serializer.data,
                    'user_detail': user_serializer.data,
                }
                return Response(final_output_data, status=status.HTTP_200_OK)

        serializer = PoultryRequestSerializer(
            self.queryset.filter(send_date=(datetime.datetime.now() - datetime.timedelta(days=1))),
            many=True
        )
        data = {'poultry_req': serializer.data}
        return Response(data, status=status.HTTP_200_OK)


class SearchFieldsViewSet(viewsets.ModelViewSet):
    queryset = SearchFields.objects.all()
    serializer_class = SearchFieldsSerializer
    permission_classes = [TokenHasReadWriteScope]


class NewReportingAllPoultryRequests(viewsets.ModelViewSet):
    userprofile_queryset = SystemUserProfile.objects.all()
    userprofile_serializer_class = SystemUserProfileSerializer
    userprofile_filterset_class = UserProfileFilterSet
    queryset = Poultry.objects.all()
    serializer_class = PoultrySerializer
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    filterset_class = PoultryFilterSet
    poultry_filterset_f = poultry_filterset_fields
    poultry_hatching_queryset = PoultryHatching.objects.all()
    poultry_hatching_filter_class = PoultryHatchingFilterSet
    poultry_hatching_filterset_f = poultry_hatching_filterset_fields
    poultry_hatching_serializer_class = PoultryHatchingSerializer

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)

        query_val = []
        poultry_hatching_query_val = []
        limited_dict = {}
        values_item = []
        limited_query = []
        poultry_hatching_limited_query = []
        poultry_hatching_limited_dict = {}

        if request.GET['type'] == 'filter':
            if 'value' in request.GET and request.GET['value'] != "":
                values = request.GET['value'].split(',')
                for item in values:
                    if item != "":
                        values_item.append(item)
                for val in values_item:
                    if not query_val:
                        for item in self.poultry_filterset_f:
                            query = QueryDict('{0}={1}'.format(item, val))
                            if (self.filterset_class(data=query, queryset=self.queryset)).filter():
                                ps = self.filterset_class(data=query, queryset=self.queryset)
                                filtered_poultry = ps.filter()
                                if filtered_poultry:
                                    limited_query.append(query)

                    if not poultry_hatching_query_val:
                        for item in self.poultry_hatching_filterset_f:
                            query = QueryDict('{0}={1}'.format(item, val))
                            if (self.poultry_hatching_filter_class(data=query,
                                                                   queryset=self.poultry_hatching_queryset)).filter():
                                ps = self.poultry_hatching_filter_class(data=query,
                                                                        queryset=self.poultry_hatching_queryset)
                                filtered_city_operator = ps.filter()
                                if filtered_city_operator:
                                    poultry_hatching_limited_query.append(query)
                for i in limited_query:
                    for key, value in i.items():
                        limited_dict[key] = value
                #
                # if len(values_item) != len(limited_dict):
                #     pass
                # else:

                if len(limited_dict) > 0:
                    for i in Poultry.objects.filter(**limited_dict):
                        query_val.append(i)
                for i in poultry_hatching_limited_query:
                    for key, value in i.items():
                        poultry_hatching_limited_dict[key] = value

                    # if len(values_item) == len(poultry_hatching_limited_dict):
                    #     pass
                    # else:
                for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict):
                    if i.poultry in query_val:
                        pass
                    else:
                        if len(limited_dict) > 0:
                            pass
                        else:
                            query_val.append(i.poultry)
                values_item_count = len(values_item)
                if values_item_count != len(limited_dict):
                    if len(poultry_hatching_limited_dict) == 0:
                        query_val = []

            if 'double_hatching_date' in request.GET:
                date_li = []
                query_li = []
                if request.GET['double_hatching_date'] != "":
                    date = request.GET['double_hatching_date'].split(',')
                    date_split_1 = date[0].split('-')
                    date_split_2 = date[1].split('-')
                    main_date_1 = datetime.datetime(
                        int(date_split_1[0]),
                        int(date_split_1[1]),
                        int(date_split_1[2])
                    )
                    main_date_2 = datetime.datetime(
                        int(date_split_2[0]),
                        int(date_split_2[1]),
                        int(date_split_2[2])
                    )
                    date_li.append(main_date_1)
                    date_li.append(main_date_2)
                    for i in PoultryHatching.objects.all():
                        if date_li[0].year <= i.date.year and date_li[0].month <= i.date.month and date_li[
                            0].day <= i.date.day and i.date.year <= date_li[1].year and i.date.month <= date_li[
                            1].month and i.date.day <= date_li[1].day:
                            if i.poultry not in query_val:
                                query_val.append(i.poultry)
            if 'single_hatching_date' in request.GET:
                date_li = []
                query_li = []
                if request.GET['single_hatching_date'] != "":
                    date = request.GET['single_hatching_date']
                    date_split = date.split('-')
                    main_date = datetime.datetime(
                        int(date_split[0]),
                        int(date_split[1]),
                        int(date_split[2])
                    )
                    date_li.append(main_date)
                    for i in PoultryHatching.objects.all():
                        if date_li[0].year == i.date.year and date_li[0].month == i.date.month and date_li[
                            0].day == i.date.day:
                            if i.poultry not in query_val:
                                query_val.append(i.poultry)
            if 'double_age' in request.GET:
                age = request.GET['double_age'].split(',')
                age1 = int(age[0])
                age2 = int(age[1])
                hatching = PoultryHatching.objects.filter(state='pending')
                if hatching.count() > 0:
                    for hatch in hatching:
                        chicken_age = (datetime.datetime.now() - hatch.date).days + 1
                        if age1 <= chicken_age and chicken_age <= age2:
                            if hatch.poultry in query_val:
                                pass
                            else:
                                query_val.append(hatch.poultry)
            if 'single_age' in request.GET:
                age = int(request.GET['single_age'])
                hatching = PoultryHatching.objects.filter(state='pending')
                if hatching.count() > 0:
                    for hatch in hatching:
                        chicken_age = (datetime.datetime.now() - hatch.date).days + 1
                        if age == chicken_age:
                            if hatch.poultry in query_val:
                                pass
                            else:
                                query_val.append(hatch.poultry)

            serializer = self.serializer_class(query_val, many=True)

            return Response(serializer.data, status=status.HTTP_200_OK)


class ForcastViewSet(viewsets.ModelViewSet):
    queryset = PoultryHatching.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryHatchingSerializer

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)

        user = SystemUserProfile.objects.get(user=request.user)
        from datetime import datetime, timedelta
        date1 = datetime.strptime(request.GET['date1'], '%Y-%m-%d')
        date2 = datetime.strptime(request.GET['date2'], '%Y-%m-%d')
        d = request.GET['day']
        days_interval = (date2 - date1).days
        hatching_dict = {}
        quantity = 0
        poultry_list_id = []
        poultry_list = []
        interal_dict = {}
        final_list = []
        hatchs = PoultryHatching.objects.filter(poultry__address__province=user.province, state='pending')
        if hatchs.count() > 0:
            for i in range(days_interval + 1):
                first_date = date1 + timedelta(days=i)
                second_date = first_date - timedelta(days=int(d))
                for hatch in hatchs:
                    if hatch.date.year == second_date.year and hatch.date.month == second_date.month and hatch.date.day == second_date.day:
                        quantity += hatch.quantity
                        if hatch.poultry in poultry_list:
                            pass
                        else:
                            poultry_list.append(hatch.poultry)
                for p in poultry_list:
                    interal_dict = {
                        "name": p.user.fullname,
                        "mobile": p.user.mobile,
                        "unitname": p.unit_name,
                        "province": p.user.province.name,
                        "city": p.user.city.name,
                    }
                    poultry_list_id.append(interal_dict)

                hatching_dict.update({"date": str(first_date), "quantity": quantity, "poultry": poultry_list_id})
                quantity = 0
                final_list.append(hatching_dict)
                hatching_dict = {}
                poultry_list_id = []
                poultry_list = []

        return Response(final_list, status=status.HTTP_200_OK)


class PoultryReporttViewSet(viewsets.ModelViewSet):
    queryset = PoultryHatching.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryHatchingSerializer

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user)
        poultry_request_list = []
        dates = []
        hatching_list = []
        average_weight_chart_list = []
        quantity = 0
        losses = 0
        poultry_requests = PoultryRequest.objects.filter(poultry__user=user, trash=False).order_by('send_date')
        if poultry_requests.count() > 0:
            for poultry_request in poultry_requests:
                total_amount = 0
                average_weight = 0
                average_fee = 0
                sales_price = 0
                paid_state = None
                if ProvinceKillRequest.objects.filter(
                        province_request__city_request_Poultry__poultry_request=poultry_request,
                        state='accepted').exists():
                    age = (poultry_request.send_date - poultry_request.hatching.date).days + 1
                else:
                    age = (datetime.datetime.now() - poultry_request.hatching.date).days + 1
                poultry_request_dict = {
                    "hatching_period": poultry_request.hatching.period,
                    "date": poultry_request.send_date.date(),
                    "hatching_date": poultry_request.hatching.date,
                    "hatching_chicken_breed": poultry_request.hatching.chicken_breed,
                    "quantity": poultry_request.quantity,
                    "age": age,
                    "weight_of_suffering": 2.5,
                    "request_id": poultry_request.id,

                }
                province_factors = ProvinceFactorToKillHouse.objects.filter(
                    province_check_req__poultry_request=poultry_request)
                if province_factors.count() > 0:
                    factor_count = province_factors.count()
                    factor_counter = 0
                    paid_state = 'pending'
                    for factor in province_factors:
                        if factor.poultry_factor != None:
                            total_amount += factor.poultry_factor.shares['poultryShareWithProfit']
                            if factor.poultry_factor.paid_state == 'paid':
                                factor_counter += 1
                        else:
                            total_amount += factor.shares['poultryShareWithProfit']
                            if factor.paid_state == 'paid':
                                factor_counter += 1
                        average_weight += factor.total_weight
                        sales_price += factor.factor_fee
                        average_fee = factor.province_check_req.fee
                    if factor_count == factor_counter:
                        paid_state = 'paid'
                    sales_price = sales_price / factor_count
                    average_weight = average_weight / factor_count
                    average_weight_dict = {
                        "date": poultry_request.send_date.date(),
                        "weight": average_weight,
                    }
                    average_weight_chart_list.append(average_weight_dict)

                poultry_request_dict.update({
                    "total_amount": total_amount,
                    "average_weight": average_weight,
                    "average_fee": average_fee,
                    "sales_price": sales_price,
                    "paid_state": paid_state,

                })
                poultry_request_list.append(poultry_request_dict)

        poultry_hatchings = PoultryHatching.objects.filter(trash=False).order_by('date')
        if poultry_hatchings.count() > 0:
            for poultry_hatching in poultry_hatchings:
                if poultry_hatching.date.date() in dates:
                    pass
                else:
                    dates.append(poultry_hatching.date.date())
            for date in dates:
                hatching = PoultryHatching.objects.filter(date__year=date.year, date__month=date.month,
                                                          date__day=date.day)
                for hatch in hatching:
                    quantity += hatch.quantity
                    losses += hatch.losses
                internal_hatching_dict = {
                    "date": date,
                    "quantity": quantity,
                    "losses": losses,
                }
                hatching_list.append(internal_hatching_dict)

                quantity = 0
                losses = 0

        final_dict = {
            "table": poultry_request_list,
            "hatching_chart": hatching_list,
            "weight_chart": average_weight_chart_list,
        }

        return Response(final_dict, status=status.HTTP_200_OK)


# ویوست مربوط به نامه جهاد واستانداری
class PoultryRequestletterReportViewSet(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PoultryRequestSerializer

    def list(self, request, *args, **kwargs):
        province = Province.objects.get(id=2)
        from datetime import datetime
        # refresh(request.user.id)
        if 'general_report' in request.GET:
            date = datetime.strptime(request.GET['date'], '%Y-%m-%d')
            poultry_requests_list = []
            poultry_requests_dict = {}
            poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province,
                                                             send_date__year=date.year, send_date__month=date.month,
                                                             send_date__day=date.day).order_by('send_date')

            if poultry_requests.count() > 0:
                for poultry_request in poultry_requests:
                    poultry_requests_dict.update({
                        'poultry_name': poultry_request.poultry.unit_name,
                        'quantity': poultry_request.previous_quantity,
                        'weight': poultry_request.Index_weight,
                        'age': (poultry_request.send_date.date() - poultry_request.hatching.date.date()).days + 1,
                        'confirmed_quantity': poultry_request.quantity,
                        'remain_quantity': poultry_request.hatching.left_over,
                    })

                    poultry_requests_list.append(poultry_requests_dict)
                    poultry_requests_dict = {}
            return Response(poultry_requests_list, status=status.HTTP_200_OK)

        elif 'daily_report' in request.GET:
            now = datetime.now().date()
            date_list = []
            hatching_list = []
            poultry_request_detail_list = []
            poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province).order_by('-send_date')
            if poultry_requests.count() > 0:
                for poultry_request in poultry_requests:
                    if poultry_request.send_date.date() in date_list:
                        pass
                    else:
                        date_list.append(poultry_request.send_date.date())
                for date in date_list:
                    quantity = 0
                    remain_quantity = 0
                    province_quantity = 0
                    average_weight = 0
                    total_poultry_request_quantity = 0
                    accepted_request_quantity = 0
                    poultry_requests_list = PoultryRequest.objects.filter(poultry__address__province=province,
                                                                          send_date__year=date.year,
                                                                          send_date__month=date.month,
                                                                          send_date__day=date.day)
                    for internal_poultry_reqs in poultry_requests_list:
                        if internal_poultry_reqs.hatching in hatching_list:
                            pass
                        else:
                            hatching_list.append(internal_poultry_reqs.hatching)
                            remain_quantity += internal_poultry_reqs.hatching.left_over

                        quantity += internal_poultry_reqs.previous_quantity
                        average_weight += internal_poultry_reqs.Index_weight
                        province_quantity += internal_poultry_reqs.quantity
                        total_poultry_request_quantity += internal_poultry_reqs.quantity
                        if internal_poultry_reqs.province_state == 'accepted':
                            accepted_request_quantity += internal_poultry_reqs.quantity
                    average_weight = round(average_weight / poultry_requests_list.count(), 2)

                    poultry_request_detail_list.append({
                        'today': now,
                        'date': date,
                        'province': province.name,
                        'previous_quantity': quantity,
                        'index_weight': average_weight,
                        'province_quantity': province_quantity,
                        'remain_quantity': remain_quantity,
                        'country_quantity': 0,
                        'total_poultry_request_quantity': total_poultry_request_quantity,
                        'accepted_request_quantity': accepted_request_quantity,

                    })
                return Response(poultry_request_detail_list, status=status.HTTP_200_OK)


class CasestatusViewSet(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PoultryRequestSerializer

    def list(self, request, *args, **kwargs):
        poultry_request_list = []
        user = SystemUserProfile.objects.get(user=request.user)
        date = datetime.datetime.strptime(str(request.GET['date']), '%Y-%m-%d')
        if request.GET['role'] == 'CityOperator':
            city_operator = CityOperator.objects.get(user=user, trash=False)
            poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
                                                             poultry__city_operator=city_operator.unit_name,
                                                             trash=False).order_by('id')
        elif request.GET['role'] in ['VetFarm', 'CityCommerce', 'CityJahad', 'CityPoultry']:

            poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
                                                             poultry__address__city=user.city,
                                                             trash=False).order_by('id')
        else:
            poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
                                                             poultry__address__province=user.province,
                                                             trash=False).order_by('id')
        if poultry_requests:
            for poultry_request in poultry_requests:
                vet_farm = VetFarm.objects.filter(poultry=poultry_request.poultry, trash=False)
                if vet_farm.count() > 0:
                    vet_farm = vet_farm.last()
                    vet_farm_name = vet_farm.vet.user.fullname
                    vet_farm_mobile = vet_farm.vet.user.mobile
                else:
                    vet_farm_name = None
                    vet_farm_mobile = None

                poultry_request_dict = {}
                poultry_request_dict.update({"poultry": {
                    "user_fullname": poultry_request.poultry.user.fullname,
                    "user_mobile": poultry_request.poultry.user.mobile,
                    "poultry_name": poultry_request.poultry.unit_name,
                    "poultry_city": poultry_request.poultry.address.city.name,
                    "poultry_province": poultry_request.poultry.address.province.name,
                    "poultry_request_quantity": poultry_request.quantity,
                    "poultry_request_remain_quantity": poultry_request.remain_quantity,
                    "freezing": poultry_request.freezing,
                    "chicken_breed": poultry_request.chicken_breed,
                    "send_date": poultry_request.send_date,
                    "index_weight": poultry_request.Index_weight,
                    "vet_farm_name": vet_farm_name,
                    "vet_farm_mobile": vet_farm_mobile,

                }

                })
                city_operator = CityOperator.objects.filter(key=poultry_request.city_operator.key, trash=False)
                if city_operator:
                    city_operator = city_operator.last()
                    city_operator_name = city_operator.user.fullname
                    city_operator_mobile = city_operator.user.mobile
                    city_operator_province = city_operator.address.province.name
                    city_operator_city = city_operator.address.city.name
                else:

                    city_operator_name = None
                    city_operator_mobile = None
                    city_operator_province = None
                    city_operator_city = None

                city = CityOperatorCheckRequest.objects.filter(poultry_request=poultry_request, trash=False)
                if city:
                    city = city.last()
                    poultry_request_dict['city_state'] = {
                        "operator_name": city_operator_name,
                        "operator_mobile": city_operator_mobile,
                        "operator_province": city_operator_province,
                        "operator_city": city_operator_city,
                        "state": city.state,
                    }
                else:
                    poultry_request_dict['city_state'] = {
                        "operator_name": city_operator_name,
                        "operator_mobile": city_operator_mobile,
                        "operator_province": city_operator_province,
                        "operator_city": city_operator_city,
                        "state": 'pending',
                    }
                role = Group.objects.get(name='ProvinceOperator')
                province_operator = ProvinceOperator.objects.filter(
                    address__province__name=poultry_request.poultry.address.province.name,
                    user__role=role, trash=False)
                if province_operator:
                    province_operator = province_operator.last()
                    province_operator_name = province_operator.user.fullname
                    province_operator_mobile = province_operator.user.mobile
                    province_operator_provinc = province_operator.address.province.name
                    province_operator_city = province_operator.address.city.name

                else:
                    province_operator_name = None
                    province_operator_mobile = None
                    province_operator_provinc = None
                    province_operator_city = None

                province = ProvinceCheckOperatorRequest.objects.filter(poultry_request=poultry_request,
                                                                       trash=False)
                if province:
                    province = province.last()
                    poultry_request_dict['province_state'] = {
                        "province_operator_name": province_operator_name,
                        "province_operator_mobile": province_operator_mobile,
                        "province_operator_provinc": province_operator_provinc,
                        "province_operator_city": province_operator_city,
                        "state": province.state,
                    }
                else:

                    poultry_request_dict.update({"province_state": {
                        "province_operator_name": province_operator_name,
                        "province_operator_mobile": province_operator_mobile,
                        "province_operator_provinc": province_operator_provinc,
                        "province_operator_city": province_operator_city,
                        "state": 'pending',
                    }})

                province_kill_requests = ProvinceKillRequest.objects.filter(trash=False,
                                                                            province_request__poultry_request=poultry_request)
                if province_kill_requests:
                    province_kill_request_list = []
                    for province_kill_request in province_kill_requests:
                        province_kill_request_dict = {}
                        province_kill_request_dict = {
                            "state": province_kill_request.state,
                            "buyer_name": province_kill_request.kill_request.kill_house.name,
                            "buyer_mobile": province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
                            "quantity": province_kill_request.main_quantity,
                        }
                        buyer_type = None
                        if province_kill_request.kill_request.kill_house.killer == False:
                            buyer_type = 'kill_house'
                        else:
                            buyer_type = 'killer'
                        province_kill_request_dict.update({
                            "buyer_type": buyer_type,
                        })
                        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                                              province_kill_request=province_kill_request)
                        if kill_house_requests:
                            kill_house_request_list = []
                            for kill_house_request in kill_house_requests:
                                kill_house_vet = KillHouseVet.objects.filter(
                                    kill_house=kill_house_request.kill_request.kill_house, trash=False)
                                if kill_house_vet.count() > 0:
                                    kill_house_vet = kill_house_vet.last()
                                    kill_house_vet_name = kill_house_vet.vet.user.fullname
                                    kill_house_vet_mobile = kill_house_vet.vet.user.mobile
                                else:
                                    kill_house_vet_name = None
                                    kill_house_vet_mobile = None

                                kill_house_request_dict = {}
                                kill_house_request_dict = {
                                    "vet_state": kill_house_request.vet_state,
                                    "kill_house_vet_name": kill_house_vet_name,
                                    "kill_house_vet_mobile": kill_house_vet_mobile,
                                    "driver_name": kill_house_request.add_car.driver.driver_name,
                                    "driver_mobile": kill_house_request.add_car.driver.driver_mobile,
                                    "pelak": kill_house_request.add_car.driver.pelak,
                                    "health_code": kill_house_request.add_car.driver.health_code,
                                    "quantity": kill_house_request.quantity,
                                    "traffic_code": kill_house_request.traffic_code,
                                    "clearance_code": kill_house_request.clearance_code,
                                    "bar_code": kill_house_request.bar_code,
                                }
                                bar = KillHouseAssignmentInformation.objects.filter(trash=False,
                                                                                    kill_house_request=kill_house_request)
                                if bar:
                                    bar = bar.last()
                                    kill_house_request_dict.update({
                                        "bar": {
                                            "car_weight_without_load": bar.car_weight_without_load,
                                            "car_weight_without_load_image": bar.car_weight_without_load_image,
                                            "car_weight_with_load": bar.car_weight_with_load,
                                            "car_weight_with_load_image": bar.car_weight_with_load_image,
                                            "net_weight": bar.net_weight,
                                            "state": bar.state,
                                            "real_quantity": bar.real_quantity,
                                            "exploited_carcass": bar.exploited_carcass
                                        }
                                    })
                                else:
                                    kill_house_request_dict.update({
                                        "bar": None
                                    })
                                province_factor = ProvinceFactorToKillHouse.objects.filter(
                                    province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                                    trash=False)
                                if province_factor:
                                    province_factor = province_factor.last()
                                    kill_house_request_dict.update({"province_factor": {
                                        "total_weight": province_factor.total_weight,
                                        "factor_fee": province_factor.factor_fee,
                                        "total_price": province_factor.total_price,
                                        "paid_state": province_factor.paid_state,
                                    }

                                    })
                                else:
                                    kill_house_request_dict.update({"province_factor": None})

                                kill_house_factor = KillHouseFactorToProvince.objects.filter(
                                    province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                                    trash=False)
                                if kill_house_factor:
                                    kill_house_factor = kill_house_factor.last()
                                    kill_house_request_dict.update({"kill_house_factor": {
                                        "payment_code": kill_house_factor.payment_code,
                                        "state": kill_house_factor.state,
                                        "factor_image": kill_house_factor.factor_image,
                                        "message": kill_house_factor.message,
                                    }

                                    })
                                else:
                                    kill_house_request_dict.update({"kill_house_factor": None})
                                kill_house_request_list.append(kill_house_request_dict)
                            province_kill_request_dict.update({"kill_house_requests": kill_house_request_list})


                        else:
                            province_kill_request_dict.update({"kill_house_requests": None})

                        province_kill_request_list.append(province_kill_request_dict)
                    poultry_request_dict.update({"province_kill_requests": province_kill_request_list})

                else:
                    poultry_request_dict.update({"province_kill_requests": None})

                province_inspector = PovinceInspector.objects.filter(poultry_request=poultry_request, trash=False)
                if province_inspector:
                    province_inspector = province_inspector.last()
                    poultry_request_dict.update({"province_inspector": {
                        "state": province_inspector.state

                    }})
                else:
                    poultry_request_dict.update({"province_inspector": None})
                poultry_request_list.append(poultry_request_dict)
        return Response(poultry_request_list, status=status.HTTP_200_OK)


class GeneralCasestatusViewSet(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PoultryRequestSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = PoultryRequestFilterSet
    filterset_fields = [
        'poultry__unit_name',
        'poultry__user__fullname',
        'poultry__user__mobile',
        'order_code',
    ]

    def list(self, request, *args, **kwargs):
        poultry_reqs = []
        poultry_requests = []
        user = SystemUserProfile.objects.get(user=request.user)
        date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        if request.GET['role'] == 'CityOperator':
            city_operator = CityOperator.objects.get(user=user)
            poultry_reqs = PoultryRequest.objects.filter(
                poultry__address__province=user.province,
                poultry__city_operator=city_operator.unit_name,
                send_date__date__gte=date1,
                send_date__date__lte=date2,
                trash=False
            ).order_by('id').select_related('poultry__user')

        elif request.GET['role'] == 'CityCommerce' or request.GET['role'] == 'VetFarm':
            poultry_reqs = PoultryRequest.objects.filter(
                poultry__address__province=user.province,
                poultry__address__city=user.city,
                send_date__date__gte=date1,
                send_date__date__lte=date2,
                trash=False
            ).order_by('id').select_related('poultry__user')

        else:
            poultry_reqs = PoultryRequest.objects.filter(
                poultry__address__province=user.province,
                send_date__date__gte=date1,
                send_date__date__lte=date2,
                trash=False).order_by('id').select_related('poultry__user')

        if 'search' in request.GET:
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "":
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=poultry_reqs
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=poultry_reqs)
                            poultry_requests = ps.filter()
                    poultry_reqs = [] if len(poultry_requests) == 0 else poultry_requests

        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_reqs)
        if page is not None:
            serializer = PoultryRequestForGeneralCasestatusSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = PoultryRequestForGeneralCasestatusSerializer(poultry_reqs, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class HatchingQueryViewSet(viewsets.ModelViewSet):
    queryset = PoultryHatching
    serializer_class = PoultryHatchingSerializer
    permission_classes = [AllowAny]

    def list(self, request, *args, **kwargs):

        hatchings = PoultryHatching.objects.filter(trash=False).order_by('-date')
        if hatchings:
            hatchings_list = []
            quantity = 0

            for hatching in hatchings:
                poultry_requests = PoultryRequest.objects.filter(
                    hatching=hatching,
                    trash=False,
                    state_process__in=('pending', 'accepted'),
                    province_state__in=('pending', 'accepted')
                )

                quantity_req = sum(poultry_req.quantity for poultry_req in poultry_requests)
                quantity += hatching.quantity

                hatching_dict = {
                    "poultry_name": hatching.poultry.unit_name,
                    "quantity": hatching.quantity,
                    "breed": hatching.breed,
                    "left_over": hatching.left_over,
                    "date": hatching.date.date(),
                    "period": hatching.period,
                    "poultry_request": quantity_req
                }

                hatchings_list.append(hatching_dict)

            return Response(hatchings_list)


class BuyerRemittance(viewsets.ModelViewSet):
    queryset = ProvinceAutoAllocation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = NewProvinceAutoAllocationSerializer

    def list(self, request, *args, **kwargs):

        if 'allocation_key' in request.GET:
            serializer = NewProvinceAutoAllocationSerializer(
                ProvinceAutoAllocation.objects.filter(key=request.GET['allocation_key'], trash=False, ).select_related(
                    'poultry_request'), many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)


        elif 'poultry_request_key' in request.GET:

            poultry_request = PoultryRequest.objects.filter(key=request.GET['poultry_request_key']).prefetch_related(
                'poultry_request_auto_quantity_province',
            ).last()

            province_auto_allocations = poultry_request.poultry_request_auto_quantity_province.all().select_related(
                'poultry_request',
                'province_kill_request',
                'daily_quota__kill_house__kill_house_operator__user',
                'daily_quota__killer_kill_house__kill_house_operator__user')
            poultry_requests_list = []
            kill_house_list = []
            killer_list = []
            for a in province_auto_allocations:
                if a.poultry_request not in poultry_requests_list:
                    poultry_requests_list.append(a.poultry_request)
                num1 = 0
                for b in province_auto_allocations:
                    if b.daily_quota == a.daily_quota:
                        num1 += b.quantity * b.poultry_request.Index_weight
                dict1 = {
                    "buyer_name": a.daily_quota.kill_house.name,
                    "weight": num1
                }
                if dict1 not in killer_list:
                    killer_list.append(dict1)
                if a.daily_quota.killer_kill_house == None:
                    for b in province_auto_allocations:
                        if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house:
                            num1 += b.quantity * b.poultry_request.Index_weight
                    dict2 = {
                        "kill_house_name": a.daily_quota.kill_house.name,
                        "weight": num1
                    }
                    if dict2 not in kill_house_list:
                        kill_house_list.append(dict2)

            allocation_list = []
            for allocation in province_auto_allocations:
                if allocation.daily_quota.killer_kill_house:
                    kill_house = allocation.daily_quota.killer_kill_house
                else:
                    kill_house = allocation.daily_quota.kill_house

                allocation_dict = {
                    "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
                    "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
                    "quantity": allocation.quantity,
                    "kill_house": {
                        "kill_house_fullname": kill_house.kill_house_operator.user.fullname,
                        "kill_house_mobile": kill_house.kill_house_operator.user.mobile,
                    }
                }
                allocation_list.append(allocation_dict)
            internal_poultry_req_dict = {
                "poultry_fullname": poultry_request.poultry.user.fullname,
                "base_order": poultry_request.poultry.user.base_order,
                "poultry_mobile": poultry_request.poultry.user.mobile,
                "poultry_quantity": poultry_request.quantity,
                "index_weight": poultry_request.Index_weight,
                "date": poultry_request.send_date,
                "allocations": allocation_list,
            }
            final_dict = {
                "poultry": internal_poultry_req_dict,
                "buyer": killer_list,
                "kill_house": kill_house_list
            }
            return Response(final_dict, status=status.HTTP_200_OK)

        elif 'auto_allocation' in request.GET:

            now = datetime.datetime.now().date()
            date = datetime.datetime.strptime(str(request.GET['date']),
                                              '%Y-%m-%d').date() if 'date' in request.GET else now
            allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related(
                'poultry_request',
                'province_kill_request',
                'daily_quota__kill_house__kill_house_operator__user',
                'daily_quota__killer_kill_house__kill_house_operator__user'
            )

            poultry_requests_list = []
            final_poultry_requests_list = []
            kill_house_list = []
            killer_list = []

            for a in allocations:
                if a.poultry_request not in poultry_requests_list:
                    poultry_requests_list.append(a.poultry_request)
                num1 = 0
                for b in allocations:
                    if b.daily_quota == a.daily_quota:
                        num1 += b.quantity * b.poultry_request.Index_weight
                dict1 = {
                    "buyer_name": a.daily_quota.kill_house.name,
                    "weight": num1
                }
                if dict1 not in killer_list:
                    killer_list.append(dict1)
                if a.daily_quota.killer_kill_house == None:
                    for b in allocations:
                        if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house:
                            num1 += b.quantity * b.poultry_request.Index_weight
                    dict2 = {
                        "kill_house_name": a.daily_quota.kill_house.name,
                        "weight": num1
                    }
                    if dict2 not in kill_house_list:
                        kill_house_list.append(dict2)

            allocation_list = []

            for poultry_request in poultry_requests_list:
                for allocation in allocations:
                    if allocation.poultry_request != poultry_request:
                        continue

                    kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house

                    allocation_dict = {
                        "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
                        "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
                        "quantity": allocation.quantity,
                        "kill_house": {
                            "kill_house_fullname": kill_house.kill_house_operator.user.fullname,
                            "kill_house_mobile": kill_house.kill_house_operator.user.mobile,
                        }
                    }
                    allocation_list.append(allocation_dict)

                internal_poultry_req_dict = {
                    "poultry_fullname": poultry_request.poultry.user.fullname,
                    "poultry_mobile": poultry_request.poultry.user.mobile,
                    "poultry_quantity": poultry_request.quantity,
                    "index_weight": poultry_request.Index_weight,
                    "date": poultry_request.send_date,
                    "allocations": allocation_list,
                }
                final_poultry_requests_list.append(internal_poultry_req_dict)
            final_dict = {
                "poultry": final_poultry_requests_list,
                "buyer": killer_list,
                "kill_house": kill_house_list,
            }

            return Response(final_dict, status=status.HTTP_200_OK)

        elif 'poultry_remittance' in request.GET:
            now = datetime.datetime.now().date()
            date = datetime.datetime.strptime(str(request.GET['date']),
                                              '%Y-%m-%d').date() if 'date' in request.GET else now
            allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related(
                'poultry_request',
                'province_kill_request',
                'daily_quota__kill_house__kill_house_operator__user',
                'daily_quota__killer_kill_house__kill_house_operator__user'
            )

            poultry_requests_list = []
            final_poultry_requests_list = []
            allocation_list = []
            for a in allocations:
                if a.poultry_request not in poultry_requests_list:
                    poultry_requests_list.append(a.poultry_request)
            for poultry_request in poultry_requests_list:
                for allocation in allocations:
                    if allocation.poultry_request != poultry_request:
                        continue

                    kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house

                    allocation_dict = {
                        "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
                        "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
                        "quantity": allocation.quantity,
                        "kill_house": {
                            "kill_house_fullname": kill_house.kill_house_operator.user.fullname,
                            "kill_house_mobile": kill_house.kill_house_operator.user.mobile,
                        }
                    }
                    allocation_list.append(allocation_dict)

                internal_poultry_req_dict = {
                    "poultry_fullname": poultry_request.poultry.user.fullname,
                    "poultry_mobile": poultry_request.poultry.user.mobile,
                    "poultry_quantity": poultry_request.quantity,
                    "date": poultry_request.send_date,
                    "allocations": allocation_list,
                }
                final_poultry_requests_list.append(internal_poultry_req_dict)
            return Response(final_poultry_requests_list, status=status.HTTP_200_OK)

        elif 'factor_to_province' in request.GET:
            factor = ProvinceFactorToKillHouse.objects.get(
                key=request.GET['factor_to_province'], paid_state='pending')
            # serializer = ProvinceFactorToKillHousePdfSerializer(factor)
            # return Response(serializer.data,status=status.HTTP_200_OK)

            economic_code_kill_house = factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code if factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code else None
            economic_code_poultry = factor.province_check_req.poultry_request.poultry.user.national_code if factor.province_check_req.poultry_request.poultry.user.national_code else None
            dict1 = {
                "buyer_name": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.name,
                # "economic_code_kill_house":economic_code_kill_house,
                # "national_id_kill_house":None,
                "serial_number_kill_house": factor.province_check_req.poultry_request.poultry.user.base_order,
                "adders_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.address,
                # "register_number_kill_house":None,
                "postal_code_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.postal_code,
                "poultry_name": factor.province_check_req.poultry_request.poultry.unit_name + ' ' + factor.province_check_req.poultry_request.poultry.user.fullname,
                # "economic_code_poultry":economic_code_poultry,
                # "national_id_poultry":None,
                "adders_poultry": factor.province_check_req.poultry_request.poultry.address.address,
                # "register_number_poultry":None,
                "postal_code_poultry": factor.province_check_req.poultry_request.poultry.address.postal_code,
                "factor_bar_code": factor.factor_bar_code,
                "amount": factor.total_weight,
                "chicken_price": factor.factor_fee,
                "total_price": factor.total_price,

            }
            return Response(dict1, status=status.HTTP_200_OK)


class DetailsGeneralWageViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = GenaeralWageSerailizer
    queryset = ProvinceKillRequest.objects.filter(
        state__in=('pending', 'accepted'), trash=False, archive_wage=False,
        first_car_allocated_quantity=0,
        return_to_province=False).exclude(union_share=0, company_share=0, guilds_share=0)

    def list(self, request, *args, **kwargs):
        ser_general = self.serializer_class(self.queryset).data
        return Response(ser_general['general'], status=status.HTTP_200_OK)


class DetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = DetailsGeneraWageSerializer
    # serializer_class = NewDetailsGeneraWageSerializer
    queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
                                                                    'kill_house_operator__user__city').exclude(
        out_province=True)

    def list(self, request, *args, **kwargs):
        ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data
        return Response(ser_data, status=status.HTTP_200_OK)


class NewDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = NewDetailsGeneraWageSerializer
    queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
                                                                    'kill_house_operator__user__city').exclude(
        out_province=True)

    def list(self, request, *args, **kwargs):
        ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data
        return Response(ser_data, status=status.HTTP_200_OK)


class DashboardDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = DashboardDetailsGeneraWageSerializer
    queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
                                                                    'kill_house_operator__user__city').exclude(
        out_province=True)

    def list(self, request, *args, **kwargs):
        ser_data = self.serializer_class(self.queryset, context={'request': request}).data
        return Response(ser_data, status=status.HTTP_200_OK)


class DataReportPercentagesViewSet(viewsets.ModelViewSet):
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DetailsGeneraWageSerializer
    queryset = KillHouseRequest.objects.filter(trash=False).order_by('kill_request__recive_date')

    def list(self, request, *args, **kwargs):
        user = request.user
        if request.GET['role'] == 'CityOperator':
            city_operator = CityOperator.objects.get(user__user=user, trash=False)
            kill_requests = self.queryset.filter(
                province_request__poultry_request__poultry__city_operator=city_operator.unit_name)
        else:
            kill_requests = self.queryset
        all_list = {}
        if request.GET['type'] == 'year':
            has_code_list = []
            quarantine_quantity_list = []
            assignment_state_archive_list = []
            accepted_assignment_real_weight_list = []
            hasnt_code_list = []
            difference_bar_list = []
            ware_house_confirmation_list = []
            ware_house_accepted_real_weight_list = []
            weight_year_list = []

            now = datetime.datetime.now().date()
            start_date = now - relativedelta(years=1)  # محاسبه تاریخ یک سال پیش

            current_date = start_date
            while current_date <= now:
                kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
                                                    kill_request__recive_date__date__year=current_date.year)
                has_code_year = len(kill_request.filter(clearance_code__isnull=False))
                quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
                assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
                accepted_assignment_real_weight = kill_request.aggregate(
                    total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
                accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
                    'total_quantity') or 0
                hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
                difference_bar = len(kill_request.filter(
                    Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
                ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
                ware_house_accepted_real_weight = kill_request.aggregate(
                    total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0

                dict_has_code_year = {
                    'date': current_date,
                    'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_quarantine_quantity_year = {
                    'date': current_date,
                    'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_assignment_state_archive_year = {
                    'date': current_date,
                    'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_accepted_assignment_real_weight_year = {
                    'date': current_date,
                    'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_hasnt_code_year = {
                    'date': current_date,
                    'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_difference_bar_year = {
                    'date': current_date,
                    'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_ware_house_confirmation_year = {
                    'date': current_date,
                    'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_ware_house_accepted_real_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
                                     2) if accepted_assignment_real_weight > 0 else 0
                }

                has_code_list.append(dict_has_code_year)
                quarantine_quantity_list.append(dict_quarantine_quantity_year)
                assignment_state_archive_list.append(dict_assignment_state_archive_year)
                accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
                hasnt_code_list.append(dict_hasnt_code_year)
                difference_bar_list.append(dict_difference_bar_year)
                ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
                ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
                weight_year_list.append(dict_weight_year)

                current_date += relativedelta(months=1)

            all_list['hasCode'] = has_code_list
            all_list['quarantineQuantity'] = quarantine_quantity_list
            all_list['assignmentStateArchive'] = assignment_state_archive_list
            all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
            all_list['hasntCode'] = hasnt_code_list
            all_list['differenceBar'] = difference_bar_list
            all_list['wareHouseConfirmation'] = ware_house_confirmation_list
            all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
            all_list['weightYear'] = weight_year_list
        elif request.GET['type'] == 'sixMonths':
            has_code_list = []
            quarantine_quantity_list = []
            assignment_state_archive_list = []
            accepted_assignment_real_weight_list = []
            hasnt_code_list = []
            difference_bar_list = []
            ware_house_confirmation_list = []
            ware_house_accepted_real_weight_list = []
            weight_year_list = []

            now = datetime.datetime.now().date()
            start_date = now - relativedelta(months=5)  # محاسبه تاریخ شش ماه پیش

            current_date = start_date
            while current_date <= now:
                kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
                                                    kill_request__recive_date__date__year=current_date.year)
                has_code_year = len(kill_request.filter(clearance_code__isnull=False))
                quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
                assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
                accepted_assignment_real_weight = kill_request.aggregate(
                    total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
                accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
                    'total_quantity') or 0
                hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
                difference_bar = len(kill_request.filter(
                    Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
                ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
                ware_house_accepted_real_weight = kill_request.aggregate(
                    total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0

                dict_has_code_year = {
                    'date': current_date,
                    'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_quarantine_quantity_year = {
                    'date': current_date,
                    'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_assignment_state_archive_year = {
                    'date': current_date,
                    'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_accepted_assignment_real_weight_year = {
                    'date': current_date,
                    'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_hasnt_code_year = {
                    'date': current_date,
                    'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_difference_bar_year = {
                    'date': current_date,
                    'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_ware_house_confirmation_year = {
                    'date': current_date,
                    'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_ware_house_accepted_real_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
                                     2) if accepted_assignment_real_weight > 0 else 0
                }

                has_code_list.append(dict_has_code_year)
                quarantine_quantity_list.append(dict_quarantine_quantity_year)
                assignment_state_archive_list.append(dict_assignment_state_archive_year)
                accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
                hasnt_code_list.append(dict_hasnt_code_year)
                difference_bar_list.append(dict_difference_bar_year)
                ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
                ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
                weight_year_list.append(dict_weight_year)

                current_date += relativedelta(months=1)

            all_list['hasCode'] = has_code_list
            all_list['quarantineQuantity'] = quarantine_quantity_list
            all_list['assignmentStateArchive'] = assignment_state_archive_list
            all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
            all_list['hasntCode'] = hasnt_code_list
            all_list['differenceBar'] = difference_bar_list
            all_list['wareHouseConfirmation'] = ware_house_confirmation_list
            all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
            all_list['weightYear'] = weight_year_list
        elif request.GET['type'] == 'threeMonths':
            has_code_list = []
            quarantine_quantity_list = []
            assignment_state_archive_list = []
            accepted_assignment_real_weight_list = []
            hasnt_code_list = []
            difference_bar_list = []
            ware_house_confirmation_list = []
            ware_house_accepted_real_weight_list = []
            weight_year_list = []

            now = datetime.datetime.now().date()
            start_date = now - relativedelta(months=2)  # محاسبه تاریخ سه ماه پیش

            current_date = start_date
            while current_date <= now:
                kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
                                                    kill_request__recive_date__date__year=current_date.year)
                has_code_year = len(kill_request.filter(clearance_code__isnull=False))
                quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
                assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
                accepted_assignment_real_weight = kill_request.aggregate(
                    total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
                accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
                    'total_quantity') or 0
                hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
                difference_bar = len(kill_request.filter(
                    Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
                ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
                ware_house_accepted_real_weight = kill_request.aggregate(
                    total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0

                dict_has_code_year = {
                    'date': current_date,
                    'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_quarantine_quantity_year = {
                    'date': current_date,
                    'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_assignment_state_archive_year = {
                    'date': current_date,
                    'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_accepted_assignment_real_weight_year = {
                    'date': current_date,
                    'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_hasnt_code_year = {
                    'date': current_date,
                    'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_difference_bar_year = {
                    'date': current_date,
                    'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_ware_house_confirmation_year = {
                    'date': current_date,
                    'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_ware_house_accepted_real_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
                                     2) if accepted_assignment_real_weight > 0 else 0
                }

                has_code_list.append(dict_has_code_year)
                quarantine_quantity_list.append(dict_quarantine_quantity_year)
                assignment_state_archive_list.append(dict_assignment_state_archive_year)
                accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
                hasnt_code_list.append(dict_hasnt_code_year)
                difference_bar_list.append(dict_difference_bar_year)
                ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
                ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
                weight_year_list.append(dict_weight_year)

                current_date += relativedelta(months=1)

            all_list['hasCode'] = has_code_list
            all_list['quarantineQuantity'] = quarantine_quantity_list
            all_list['assignmentStateArchive'] = assignment_state_archive_list
            all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
            all_list['hasntCode'] = hasnt_code_list
            all_list['differenceBar'] = difference_bar_list
            all_list['wareHouseConfirmation'] = ware_house_confirmation_list
            all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
            all_list['weightYear'] = weight_year_list
        else:
            has_code_list = []
            quarantine_quantity_list = []
            assignment_state_archive_list = []
            accepted_assignment_real_weight_list = []
            hasnt_code_list = []
            difference_bar_list = []
            ware_house_confirmation_list = []
            ware_house_accepted_real_weight_list = []
            weight_year_list = []

            now = datetime.datetime.now().date()
            last_year = now - relativedelta(months=1)  # محاسبه تاریخ یک ماه پیش

            current_date = last_year
            while current_date <= now:
                kill_request = kill_requests.filter(kill_request__recive_date__date=current_date)
                has_code_year = len(kill_request.filter(clearance_code__isnull=False))
                quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
                assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
                accepted_assignment_real_weight = kill_request.aggregate(
                    total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
                accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
                    'total_quantity') or 0
                hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
                difference_bar = len(kill_request.filter(
                    Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
                ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
                ware_house_accepted_real_weight = kill_request.aggregate(
                    total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0

                dict_has_code_year = {
                    'date': current_date,
                    'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_quarantine_quantity_year = {
                    'date': current_date,
                    'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_assignment_state_archive_year = {
                    'date': current_date,
                    'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_accepted_assignment_real_weight_year = {
                    'date': current_date,
                    'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_hasnt_code_year = {
                    'date': current_date,
                    'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_difference_bar_year = {
                    'date': current_date,
                    'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
                }
                dict_ware_house_confirmation_year = {
                    'date': current_date,
                    'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
                        kill_request) > 0 else 0
                }
                dict_ware_house_accepted_real_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
                                     2) if accepted_real_weight > 0 else 0
                }
                dict_weight_year = {
                    'date': current_date,
                    'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
                                     2) if accepted_assignment_real_weight > 0 else 0
                }

                has_code_list.append(dict_has_code_year)
                quarantine_quantity_list.append(dict_quarantine_quantity_year)
                assignment_state_archive_list.append(dict_assignment_state_archive_year)
                accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
                hasnt_code_list.append(dict_hasnt_code_year)
                difference_bar_list.append(dict_difference_bar_year)
                ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
                ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
                weight_year_list.append(dict_weight_year)

                current_date += relativedelta(days=1)  # به روز بعد بروید

            all_list['hasCode'] = has_code_list
            all_list['quarantineQuantity'] = quarantine_quantity_list
            all_list['assignmentStateArchive'] = assignment_state_archive_list
            all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
            all_list['hasntCode'] = hasnt_code_list
            all_list['differenceBar'] = difference_bar_list
            all_list['wareHouseConfirmation'] = ware_house_confirmation_list
            all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
            all_list['weightYear'] = weight_year_list
        return Response(all_list)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def check_excel(request):
    url = request.GET.get('url')
    if not url:
        return JsonResponse({'status': 'error', 'message': 'URL parameter is missing'}, status=400)

    try:
        r = requests.head(f'https://{base_url_for_sms_report}backend.rasadyar.com/{url}')
        return JsonResponse({'status': r.status_code})
    except requests.RequestException as e:
        return JsonResponse({'status': 'error', 'message': str(e)}, status=500)


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


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def find_gid_code(request):
    date = datetime.datetime.now().date() - datetime.timedelta(days=7)
    kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False,
                                                         quarantine_quantity__isnull=True).only(
        'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
    ).order_by('-id')
    session = requests.Session()
    session.mount('https://', SSLAdapter())

    for kill in kill_house_request:
        if kill.clearance_code is None:
            kill.quarantine_code_state = 'noclearance'
        else:
            data = {'gid': str(kill.clearance_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')
            text = context.body.get_text(strip=True)
            if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                kill.quarantine_code_state = 'notconfirmed'
                if kill.quarantine_quantity is not None:
                    kill.quarantine_quantity = None
            else:
                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]:
                            quantity = r.find('td')
                            match = re.search(r'\d+', quantity.text)
                            if match:
                                number = match.group()
                                kill.quarantine_quantity = int(number)
                                if kill.quarantine_code_state is not None:
                                    kill.quarantine_code_state = None
                else:
                    for table in table:
                        p_tags = table.find_all('p')
                        for p in p_tags:
                            p_text = p.get_text(strip=True)
                            if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                                kill.quarantine_code_state = 'contradiction'
                                if kill.quarantine_quantity is not None:
                                    kill.quarantine_quantity = None
        kill.save()
    return HttpResponse('ok')


def get_gid(clearance_code):
    kill = KillHouseRequest.objects.filter(clearance_code=clearance_code, trash=False).order_by('id')
    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kill:
        if len(kill) > 1:
            for k in kill[1:]:
                if k.quarantine_quantity is not None:
                    k.quarantine_quantity = None
                k.quarantine_code_state = 'merge'
                k.save()
        kill = kill.first()
        if kill.quarantine_code_state != 'merge':
            data = {'gid': str(kill.clearance_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')
            text = context.body.get_text(strip=True)
            if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                kill.quarantine_code_state = 'notconfirmed'
                if kill.quarantine_quantity is not None:
                    kill.quarantine_quantity = None
            else:
                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:
                            jalali_date = date_match.group(1)
                            year, month, day = map(int, jalali_date.split('/'))
                            date = convert_to_miladi(year=year, month=month, day=day)
                            kill.inquiry_date = date.date()
                            send_date = kill.kill_request.recive_date.date()

                            one_day = timedelta(days=1)
                            if abs(send_date - date.date()) <= one_day:
                                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:
                                            number = match.group()
                                            kill.quarantine_quantity = int(number)
                                            if kill.quarantine_code_state is not None:
                                                kill.quarantine_code_state = None
                                for i in table[4:5]:
                                    rows = i.find_all('tr')

                                    pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                                                             style='font-family:Tahoma').text.strip()
                                    kill.inquiry_pelak = pelak_txt
                                    td = rows[1].find_all('td')[1]
                                    driver_txt = td.find('span', class_='dynamictxt').text.strip()
                                    kill.inquiry_driver = driver_txt

                                    for r in rows:
                                        tds = r.find_all('td', colspan="2")
                                        if len(tds) >= 2:
                                            origin_td = tds[0]
                                            origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                                            kill.inquiry_origin = origin_text

                                            destination_td = tds[1]
                                            destination_text = destination_td.find('span',
                                                                                   class_='dynamictxt').text.strip()
                                            kill.inquiry_destination = destination_text
                            else:
                                kill.quarantine_code_state = 'contradiction'
                                kill.quarantine_quantity = None
                else:
                    for table in table:
                        p_tags = table.find_all('p')
                        for p in p_tags:
                            p_text = p.get_text(strip=True)
                            if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                                kill.quarantine_code_state = 'contradiction'
                                if kill.quarantine_quantity is not None:
                                    kill.quarantine_quantity = None
        kill.save()


def cron_find_gid_code():
    date = datetime.datetime.now().date() - datetime.timedelta(days=7)
    kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False,
                                                         quarantine_quantity__isnull=True,
                                                         clearance_code__isnull=False).only(
        'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
    ).order_by('-id')
    session = requests.Session()
    session.mount('https://', SSLAdapter())

    for kill in kill_house_request:
        if kill.quarantine_code_state != 'merge':
            if kill.clearance_code is None:
                kill.quarantine_code_state = 'noclearance'
            else:
                data = {'gid': str(kill.clearance_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')
                text = context.body.get_text(strip=True)
                if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                    kill.quarantine_code_state = 'notconfirmed'
                    if kill.quarantine_quantity is not None:
                        kill.quarantine_quantity = None
                else:
                    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:
                                jalali_date = date_match.group(1)
                                year, month, day = map(int, jalali_date.split('/'))
                                date = convert_to_miladi(year=year, month=month, day=day)
                                kill.inquiry_date = date.date()
                                send_date = kill.kill_request.recive_date.date()

                                one_day = timedelta(days=1)
                                if abs(send_date - date.date()) <= one_day:
                                    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:
                                                number = match.group()
                                                kill.quarantine_quantity = int(number)
                                                if kill.quarantine_code_state is not None:
                                                    kill.quarantine_code_state = None
                                    for i in table[4:5]:
                                        rows = i.find_all('tr')

                                        pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                                                                 style='font-family:Tahoma').text.strip()
                                        kill.inquiry_pelak = pelak_txt
                                        td = rows[1].find_all('td')[1]
                                        driver_txt = td.find('span', class_='dynamictxt').text.strip()
                                        kill.inquiry_driver = driver_txt

                                        for r in rows:
                                            tds = r.find_all('td', colspan="2")
                                            if len(tds) >= 2:
                                                origin_td = tds[0]
                                                origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                                                kill.inquiry_origin = origin_text

                                                destination_td = tds[1]
                                                destination_text = destination_td.find('span',
                                                                                       class_='dynamictxt').text.strip()
                                                kill.inquiry_destination = destination_text
                                else:
                                    kill.quarantine_code_state = 'contradiction'
                                    kill.quarantine_quantity = None

                    else:
                        for table in table:
                            p_tags = table.find_all('p')
                            for p in p_tags:
                                p_text = p.get_text(strip=True)
                                if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                                    kill.quarantine_code_state = 'contradiction'
                                    if kill.quarantine_quantity is not None:
                                        kill.quarantine_quantity = None
        kill.save()


class IranProvinceViewSet(viewsets.ModelViewSet):
    queryset = IranProvinces.objects.all().order_by('id')
    serializer_class = IranProvinceSerializer
    permission_classes = [AllowAny]


class IranCityViewSet(viewsets.ModelViewSet):
    queryset = IranCities.objects.all().order_by('id')
    serializer_class = IranCitiesSerializer
    permission_classes = [AllowAny]

    def list(self, request, *args, **kwargs):
        query = self.queryset.filter(province_id__name=request.GET.get('name'))
        ser_data = self.serializer_class(query, many=True).data
        return Response(ser_data, status=status.HTTP_200_OK)


def fix_image_voilation_hatching(request):
    hatchings = PoultryHatching.objects.filter(violation_image__isnull=False)
    for h in hatchings:
        h.violation_image1 = [h.violation_image]
        h.save()
    return HttpResponse('ok')


def fix_image_voilation_hatching_return(request):
    hatchings = PoultryHatching.objects.filter(violation_image1__isnull=False)
    for h in hatchings:
        h.violation_image = h.violation_image1
        h.save()
    return HttpResponse('ok')


class AgeNotificationPoultryViewSet(viewsets.ModelViewSet):
    queryset = AgeNotificationPoultry.objects.all()
    serializer_class = AgeNotificationPoultrySerilizer
    permission_classes = [AllowAny]

    def list(self, request, *args, **kwargs):
        query = self.queryset.filter(trash=False)
        ser_data = self.serializer_class(query, many=True).data
        return Response(ser_data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        query = self.queryset.get(key=request.data['notif_key'])
        request.data.pop('notif_key')
        ser_data = self.serializer_class(query)
        ser_data.update(instance=query, validated_data=request.data)
        return Response(ser_data.data, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        query = self.queryset.get(key=request.GET['notif_key'])
        query.trash = True
        query.save()
        return Response({'result': 'با موفقیت حذف شد.'}, status=status.HTTP_200_OK)


def send_sms_for_poultry_from_age_notification():
    notif_poultry = AgeNotificationPoultry.objects.filter(trash=False)
    if notif_poultry:
        for n in notif_poultry:
            poultry_hatchings = PoultryHatching.objects.filter(
                archive=False,
                allow_hatching='pending',
                trash=False,
                left_over__gt=(F('quantity') * n.losses_percent) / 100,
                chicken_age=n.poultry_age
            ).values_list('poultry__user__mobile', flat=True).distinct()

            mobile_numbers = ','.join(poultry_hatchings)
            if len(mobile_numbers) > 0:
                req = send_sms_request(
                    f"http://webservice.sahandsms.com/newsmswebservice.asmx/SendPostUrl?username={USERNAME_SMS_FINANCIAL}&password={PASSWORD_SMS_FINANCIAL}&from=30002501&to={mobile_numbers}&message={n.message}")


def remove_access_token():
    ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/"
    requests.get(
        url=ARTA_remove_access_token,
        verify=False
    )
    now = datetime.datetime.now()
    accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3))
    for access in accesses:
        access.expires = now - timedelta(days=2)
        access.save()


def kill_house_not_add_to_inventory():
    now = datetime.datetime.now().date() - timedelta(days=2)
    kill_houses = KillHouse.objects.filter(trash=False, out_province=False).select_related('kill_house_operator__user')
    for kill_house in kill_houses:
        kill_request = len(KillHouseRequest.objects.filter(Q(killhouse_user=kill_house) | Q(killer=kill_house),
                                                           trash=False, ware_house_confirmation=False,
                                                           calculate_status=True,
                                                           kill_request__recive_date__date__lte=now))
        if kill_request > 0:
            send_sms_for_kill_house_not_add_to_inventory(kill_house.kill_house_operator.user.mobile, kill_request)


class CookieSamasatViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    queryset = CookieSamasat.objects.first()
    serializer_class = CookieSamasatSerilizer

    def list(self, request, *args, **kwargs):
        cookie = CookieSamasat.objects.all().first()
        if not cookie:
            cookie = CookieSamasat(
                cookie='-',
                table_name='-'
            )
            cookie.save()
        ser_data = self.serializer_class(cookie).data
        return Response(ser_data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        query = CookieSamasat.objects.first()

        if base_url_for_sms_report == 'test':
            province_list = ['bu', 'ma', 'ha']
            for name in province_list:
                requests.put(f"https://{name}backend.rasadyar.com/cookie-samasat/0/", data=request.data)

        serializer = self.serializer_class(query, data=request.data, partial=True)
        if serializer.is_valid():
            serializer.save()
            return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


# def create_poultry(phone_number,full_name,city,province):
#     group = Group.objects.get(name__exact="Poultry")
#     hashed_password=None
#     password=None
#     user = User(username=phone_number, first_name=first_name, last_name=last_name, password=hashed_password)
#     user.save()
#     base_id = SystemUserProfile.objects.all()
#     if base_id.count() > 0:
#         base_id = int(base_id.last().base_order) + 1
#     else:
#         base_id = 1000
#     system_profile = SystemUserProfile(
#         mobile=phone_number,
#         first_name=first_name,
#         last_name=last_name,
#         fullname=first_name + '' + last_name,
#         user=user,
#         base_order=base_id,
#         password=password,
#         birthday=str(datetime.datetime.now().date()),
#         city=city,
#         province=province
#     )
#     system_profile.save()
#     system_profile.role.add(group)
#     wallet = Wallet()
#     wallet.save()

# درست نیست
@api_view(["PUT"])
@permission_classes([AllowAny])
@csrf_exempt
def api_update_poultry_hatching(request):
    not_find_list = []

    for data in request.data['Data']:
        breeding_uniq_id = data['PartIdCode']
        licence_number = data['RequestCode']
        hatching_quantity = data['BaseHatchingCount']
        poultry_name = data['UnitName']
        losses = data['EvacuationCount']
        health_certificate = data['DesCertId']
        evacuation_details = data.get('EvacuationDetail') or []
        if isinstance(evacuation_details, dict):
            evacuation_details = [evacuation_details]
        report_type_field_map = {
            'تلفات ناشی از بیماری': 'total_disease_losses',
            'معدوم سازی گله': 'total_flock_destruction',
            'تلفات عادی گله': 'total_normal_flock_losses',
            'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses',
            'تلفات ناشی از آتش سوزی': 'total_fire_losses',
        }
        evacuation_losses = {}
        evacuation_fields = set()
        for detail in evacuation_details:
            if not isinstance(detail, dict):
                continue
            report_type = (detail.get('ReportTypeString') or '').strip()
            field_name = report_type_field_map.get(report_type)
            if not field_name:
                continue
            try:
                good_count = int(detail.get('GoodCount') or 0)
            except (TypeError, ValueError):
                continue
            evacuation_losses[field_name] = evacuation_losses.get(field_name, 0) + good_count
            evacuation_fields.add(field_name)

        def apply_evacuation_losses(instance):
            for field in evacuation_fields:
                setattr(instance, field, evacuation_losses.get(field, 0))

        poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()

        if not poultry:
            not_find_list.append(breeding_uniq_id)
            continue
        poultry.unit_name = poultry_name
        poultry.save()
        hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
        if hatch:
            period = hatch.last().period + 1
        else:
            period = 1

        hatching_date = data['HatchingDatePersian'].split('/')
        date = convert_to_miladi(
            year=int(hatching_date[0]),
            month=int(hatching_date[1]),
            day=int(hatching_date[2])
        )

        poultry_hatching = hatch.filter(trash=False, archive=False, state='pending',
                                        allow_hatching='pending').order_by('id')

        if not poultry_hatching.exists():
            if not hatch.filter(archive=True, state='complete',
                                allow_hatching="True", licence_number=licence_number).exists():
                hatching = PoultryHatching(
                    poultry=poultry,
                    date=date,
                    quantity=hatching_quantity,
                    breed=[
                        {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
                    period=period,
                    chicken_breed='*ترکیبی',
                    hall=1,
                    left_over=hatching_quantity,
                    latest_hatching_change={
                        "role": "UnitWindow",
                        "date": str(datetime.datetime.now().date()),
                        "full_name": ""
                    },
                    licence_number=licence_number,
                    breeding_unique_id=breeding_uniq_id,
                    losses=losses,
                    health_certificate=health_certificate

                )
                apply_evacuation_losses(hatching)
                hatching.save()

        else:
            previouse_hatching = poultry_hatching.last()

            hatchings = poultry_hatching.filter(licence_number=licence_number)
            if not hatchings:
                if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses):
                    previouse_hatching.violation = True
                    previouse_hatching.save()

                hatching = PoultryHatching(
                    poultry=poultry,
                    date=date,
                    quantity=hatching_quantity,
                    breed=[
                        {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
                    period=period,
                    chicken_breed='*ترکیبی',
                    hall=1,
                    left_over=hatching_quantity,
                    latest_hatching_change={
                        "role": "UnitWindow",
                        "date": str(datetime.datetime.now().date()),
                        "full_name": ""
                    },
                    licence_number=licence_number,
                    breeding_unique_id=breeding_uniq_id,
                    losses=losses,
                    health_certificate=health_certificate

                )
                apply_evacuation_losses(hatching)
                hatching.save()
            else:
                last_hatchings = hatchings.first()
                if last_hatchings.health_certificate is None:
                    last_hatchings.health_certificate = health_certificate
                last_hatchings.date = date
                last_hatchings.quantity = hatching_quantity
                last_hatchings.losses = losses
                apply_evacuation_losses(last_hatchings)
                last_hatchings.save()

        update = LastUpdate.objects.first()
        update.update_date = datetime.datetime.now()
        update.save()
    return Response(not_find_list, status=status.HTTP_201_CREATED)


@api_view(["PUT"])
@permission_classes([AllowAny])
@csrf_exempt
def api_update_chicken_breed(request):
    for data in request.data['Data']:
        breeding_uniq_id = data['PartIdCode']
        breed = data['PedigreeName']
        health_certificate = data['CertId']
        poultry_hatching = PoultryHatching.objects.filter(Q(poultry__breeding_unique_id=breeding_uniq_id,
                                                            health_certificate__isnull=True) | Q(
            poultry__breeding_unique_id=breeding_uniq_id, health_certificate__isnull=False,
            health_certificate=health_certificate)
                                                          , violation=False, trash=False, allow_hatching='pending',
                                                          state='pending',
                                                          ).order_by(
            'id').last()

        if poultry_hatching:
            if poultry_hatching.chicken_breed == '*ترکیبی':
                poultry_hatching.chicken_breed = breed
            elif poultry_hatching.chicken_breed != breed and poultry_hatching.chicken_breed != '*ترکیبی':
                poultry_hatching.chicken_breed = 'ترکیبی'
            else:
                continue

            poultry_hatching.save()

    return Response({"result": "انجام شد."}, status=status.HTTP_201_CREATED)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def api_update_poultry_hatching_from_rsi(request):
    not_find_list = []
    r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')

    for data in r.json():
        breeding_uniq_id = data['PartIdCode']
        licence_number = data['RequestCode']
        hatching_quantity = data['ChickCountSum']
        CertId = data['CertId']
        poultry_name = data.get('UnitName', None)
        losses = data.get('Evacuation', 0)
        province = data['ProvinceName']
        city = data['CityName']
        PersonTypeName = data['PersonTypeName']
        InteractTypeName = data['InteractTypeName']
        UnionTypeName = data['UnionTypeName']
        date = convert_str_to_date(str(data['Date']), with_datetime=True)
        samasat_discharge_percentage = data['samasat_discharge_percentage']
        evacuation_details = data.get('EvacuationDetail') or []
        if isinstance(evacuation_details, dict):
            evacuation_details = [evacuation_details]
        report_type_field_map = {
            'تلفات ناشی از بیماری': 'total_disease_losses',
            'معدوم سازی گله': 'total_flock_destruction',
            'تلفات عادی گله': 'total_normal_flock_losses',
            'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses',
            'تلفات ناشی از آتش سوزی': 'total_fire_losses',
        }
        evacuation_detail_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',
        ]
        report_type_fields = set(report_type_field_map.values())
        report_type_field_list = list(report_type_fields)

        def build_unique_key(detail_payload):
            external_id = detail_payload.get('ExternalId')
            if external_id:
                return f"external:{external_id}"
            string_id = detail_payload.get('StringId')
            if string_id:
                return f"string:{string_id}"
            return "fallback:" + "|".join(
                str(detail_payload.get(key) or '') for key in ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate'))

        def sync_evacuation_detail_records(hatching_instance):
            if not hatching_instance.pk:
                return

            def normalize_good_count(value):
                if value in (None, ''):
                    return None
                try:
                    return int(value)
                except (TypeError, ValueError):
                    try:
                        return int(float(value))
                    except (TypeError, ValueError):
                        return None

            retained_ids = set()
            seen_unique_keys = set()

            for detail in evacuation_details:
                if not isinstance(detail, dict):
                    continue
                detail_payload = {field: detail.get(field) for field in evacuation_detail_fields}
                detail_payload['GoodCount'] = normalize_good_count(detail_payload.get('GoodCount'))
                if not any(value not in (None, '') for value in detail_payload.values()):
                    continue

                unique_key = build_unique_key(detail_payload)
                if unique_key in seen_unique_keys:
                    continue
                seen_unique_keys.add(unique_key)

                external_id = detail_payload.get('ExternalId')
                string_id = detail_payload.get('StringId')
                lookup_kwargs = {'hatching': hatching_instance}
                if external_id:
                    lookup_kwargs['ExternalId'] = external_id
                elif string_id:
                    lookup_kwargs['StringId'] = string_id
                else:
                    lookup_key_fields = ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate')
                    lookup_kwargs.update({field: detail_payload.get(field) for field in lookup_key_fields})

                defaults = detail_payload.copy()
                defaults['hatching'] = hatching_instance

                try:
                    detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create(
                        defaults=defaults,
                        **lookup_kwargs
                    )
                except EvacuationHatchingDetail.MultipleObjectsReturned:
                    EvacuationHatchingDetail.objects.filter(**lookup_kwargs).delete()
                    detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create(
                        defaults=defaults,
                        **lookup_kwargs
                    )

                retained_ids.add(detail_instance.pk)

            if retained_ids:
                hatching_instance.evacuation_details.exclude(pk__in=retained_ids).delete()
            else:
                hatching_instance.evacuation_details.all().delete()

        def apply_evacuation_losses(instance):
            totals = {field: 0 for field in report_type_fields}
            detail_qs = instance.evacuation_details.filter(trash=False, IsDeleted=False)
            for detail in detail_qs:
                report_type = (detail.ReportTypeString or '').strip()
                field_name = report_type_field_map.get(report_type)
                if not field_name:
                    continue
                totals[field_name] += detail.GoodCount or 0
            for field, value in totals.items():
                setattr(instance, field, value)

        hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id')

        try:
            if not hatch:
                poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()
                if not poultry:
                    first_name = data['poultry']['FirstName']
                    last_name = data['poultry']['LastName']
                    mobile = data['poultry']['Mobile']
                    system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
                    province = Province.objects.filter(trash=False, name__exact=province).first()
                    city = City.objects.filter(trash=False, name__exact=city).first()
                    if not system_profile:

                        data = {
                            "username": mobile,
                            "first_name": first_name,
                            "last_name": last_name,
                            "password": '123456',
                            "national_code": '0',
                            "role": "Poultry",
                            "api_key": PROJECT_API_KEY
                        }
                        req = requests.post(
                            url=ARTA_REGISTER,
                            data=data,
                            verify=False
                        )

                        if req.status_code == 200:
                            hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
                            user = User.objects.filter(username=mobile).first()
                            if not user:
                                user = User(username=mobile, first_name=first_name, last_name=last_name,
                                            password=hashed_password)
                                user.save()
                            base_id = SystemUserProfile.objects.all()
                            if base_id.count() > 0:
                                base_id = int(base_id.last().base_order) + 1
                            else:
                                base_id = 1000
                            system_profile = SystemUserProfile(
                                mobile=mobile,
                                first_name=str(first_name),
                                last_name=str(last_name),
                                fullname=str(first_name) + ' ' + str(last_name),
                                user=user,
                                base_order=base_id,
                                password='123456',
                                birthday=str(datetime.datetime.now().date()),
                                city=city,
                                province=province,
                            )
                            system_profile.save()

                        else:
                            not_find_list.append(breeding_uniq_id)

                    group = Group.objects.get(name__exact="Poultry")
                    if not system_profile.role.filter(name="Poultry"):
                        system_profile.role.add(group)

                    wallet = Wallet()
                    wallet.save()
                    poultry = Poultry(
                        user=system_profile,
                        unit_name=poultry_name,
                        system_code=data.get('poultry', {}).get('SystemCode', None),
                        epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None),
                        breeding_unique_id=breeding_uniq_id,
                    )

                    address = SystemAddress(
                        province=province,
                        city=city,
                        address=city
                    )
                    address.save()
                    poultry.address = address
                    poultry.user = system_profile
                    poultry.wallet = wallet
                    poultry.save()

                poultry.unit_name = poultry_name
                poultry.save()

                hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
                if hatch:
                    period = hatch.last().period + 1
                else:
                    period = 1
                hatching = PoultryHatching(
                    poultry=poultry,
                    date=date,
                    quantity=hatching_quantity,
                    breed=[
                        {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
                    period=period,
                    chicken_breed=data["PedigreeName"],
                    hall=1,
                    left_over=hatching_quantity,
                    latest_hatching_change={
                        "role": "UnitWindow",
                        "date": str(datetime.datetime.now().date()),
                        "full_name": ""
                    },
                    licence_number=licence_number,
                    breeding_unique_id=breeding_uniq_id,
                    losses=losses,
                    PersonTypeName=PersonTypeName,
                    InteractTypeName=InteractTypeName,
                    UnionTypeName=UnionTypeName,
                    samasat_discharge_percentage=samasat_discharge_percentage,
                    CertId=CertId,
                    predicate_date=date + timedelta(
                        days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None,

                )
                hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1
                hatching.save()
                sync_evacuation_detail_records(hatching)
                apply_evacuation_losses(hatching)
                if report_type_field_list:
                    hatching.save(update_fields=report_type_field_list)
                else:
                    hatching.save()
            else:
                last_hatchings = hatch.first()
                last_hatchings.date = date
                last_hatchings.quantity = hatching_quantity
                last_hatchings.losses = losses
                last_hatchings.PersonTypeName = PersonTypeName
                last_hatchings.InteractTypeName = InteractTypeName
                last_hatchings.UnionTypeName = UnionTypeName
                last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1
                last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage
                last_hatchings.predicate_date = date + timedelta(
                    days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None
                sync_evacuation_detail_records(last_hatchings)
                apply_evacuation_losses(last_hatchings)
                update_fields = [
                                    'date',
                                    'quantity',
                                    'losses',
                                    'PersonTypeName',
                                    'InteractTypeName',
                                    'UnionTypeName',
                                    'chicken_age',
                                    'samasat_discharge_percentage',
                                    'predicate_date',
                                ] + report_type_field_list
                last_hatchings.save(update_fields=update_fields)
            update = LastUpdate.objects.first()
            update.update_date = datetime.datetime.now()
            update.save()
        except:
            not_find_list.append(breeding_uniq_id)

    if not_find_list:
        token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde"
        chat_id = '10046800'
        url = f'https://eitaayar.ir/api/{token}/sendMessage'
        base_message = f'{base_url_for_sms_report}' \
                       '\n'
        messages = []
        current_message = base_message
        new_message_part = ','.join(not_find_list)
        if len(current_message) + len(new_message_part) > 4000:  # محدودیت تعداد کاراکترها
            messages.append(current_message)
            current_message = base_message  # شروع یک پیام جدید

        current_message += new_message_part

        if current_message and current_message != base_message:
            messages.append(current_message)
        for message in messages:
            data = {
                'chat_id': chat_id,
                'text': message,
            }
            r = requests.post(url, data=data, verify=False)

    return Response(not_find_list, status=status.HTTP_201_CREATED)


class HatchingLossManagementViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = HatchingLossManagementSerializer

    def get_queryset(self):
        queryset = HatchingLossManagement.objects.filter(trash=False)
        if not queryset.exists():
            queryset = HatchingLossManagement.objects.filter(
                pk=HatchingLossManagement.objects.create().pk
            )
        return queryset

    def get_object(self):
        return self.get_queryset().first()

    def list(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(
            serializer.data,
            status=status.HTTP_200_OK,
        )

    def create(self, request, *args, **kwargs):
        return self._update_instance(request, partial=False)

    def update(self, request, *args, **kwargs):
        return self._update_instance(request, partial=False)

    def _update_instance(self, request, partial):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        instance = serializer.save()
        self._recalculate_hatchings()
        return Response(self.get_serializer(instance).data, status=status.HTTP_200_OK)

    def _recalculate_hatchings(self):
        count = 0
        hatchings = PoultryHatching.objects.filter(trash=False, archive=False, allow_hatching='pending')
        for hatching in hatchings.iterator():
            hatching.save()
            count += 1
        return count


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def update_hatching(request):
    r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')
    for data in r.json():
        print(data['PartIdCode'])
    return Response(r.json())


def cron_update_poultry_hatching_from_rsi():
    not_find_list = []
    r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')

    for data in r.json():
        breeding_uniq_id = data['PartIdCode']
        licence_number = data['RequestCode']
        hatching_quantity = data['ChickCountSum']
        CertId = data['CertId']
        poultry_name = data.get('UnitName', None)
        losses = data.get('Evacuation', 0)
        province = data['ProvinceName']
        city = data['CityName']
        PersonTypeName = data['PersonTypeName']
        InteractTypeName = data['InteractTypeName']
        UnionTypeName = data['UnionTypeName']
        date = datetime.datetime.strptime(data['Date'], "%Y-%m-%dT%H:%M:%SZ")
        samasat_discharge_percentage = data['samasat_discharge_percentage']

        hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id')

        try:
            if not hatch:
                poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()
                if not poultry:
                    first_name = data['poultry']['FirstName']
                    last_name = data['poultry']['LastName']
                    mobile = data['poultry']['Mobile']
                    system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
                    if not system_profile:

                        data = {
                            "username": mobile,
                            "first_name": first_name,
                            "last_name": last_name,
                            "password": '123456',
                            "national_code": '0',
                            "role": "Poultry",
                            "api_key": PROJECT_API_KEY
                        }
                        req = requests.post(
                            url=ARTA_REGISTER,
                            data=data,
                            verify=False
                        )

                        if req.status_code == 200:
                            hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
                            user = User.objects.filter(username=mobile).first()
                            if not user:
                                user = User(username=mobile, first_name=first_name, last_name=last_name,
                                            password=hashed_password)
                                user.save()
                            base_id = SystemUserProfile.objects.all()
                            if base_id.count() > 0:
                                base_id = int(base_id.last().base_order) + 1
                            else:
                                base_id = 1000
                            system_profile = SystemUserProfile(
                                mobile=mobile,
                                first_name=str(first_name),
                                last_name=str(last_name),
                                fullname=str(first_name) + ' ' + str(last_name),
                                user=user,
                                base_order=base_id,
                                password='123456',
                                birthday=str(datetime.datetime.now().date()),
                            )
                            system_profile.save()

                        else:
                            not_find_list.append(breeding_uniq_id)

                    group = Group.objects.get(name__exact="Poultry")
                    if not system_profile.role.filter(name="Poultry"):
                        system_profile.role.add(group)

                    wallet = Wallet()
                    wallet.save()
                    poultry = Poultry(
                        user=system_profile,
                        unit_name=poultry_name,
                        system_code=data.get('poultry', {}).get('SystemCode', None),
                        epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None),
                        breeding_unique_id=breeding_uniq_id,
                    )
                    province = Province.objects.filter(trash=False, name__exact=province).first()
                    city = City.objects.filter(trash=False, name__exact=city).first()
                    address = SystemAddress(
                        province=province,
                        city=city,
                        address=city
                    )
                    address.save()
                    poultry.address = address
                    poultry.user = system_profile
                    poultry.wallet = wallet
                    poultry.save()

                poultry.unit_name = poultry_name
                poultry.save()

                hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
                if hatch:
                    period = hatch.last().period + 1
                else:
                    period = 1
                hatching = PoultryHatching(
                    poultry=poultry,
                    date=date,
                    quantity=hatching_quantity,
                    breed=[
                        {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
                    period=period,
                    chicken_breed=data["PedigreeName"],
                    hall=1,
                    left_over=hatching_quantity,
                    latest_hatching_change={
                        "role": "UnitWindow",
                        "date": str(datetime.datetime.now().date()),
                        "full_name": ""
                    },
                    licence_number=licence_number,
                    breeding_unique_id=breeding_uniq_id,
                    losses=losses,
                    PersonTypeName=PersonTypeName,
                    InteractTypeName=InteractTypeName,
                    UnionTypeName=UnionTypeName,
                    samasat_discharge_percentage=samasat_discharge_percentage,
                    CertId=CertId,
                    predicate_date=date + timedelta(
                        days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None,

                )
                hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1
                hatching.save()
            else:
                last_hatchings = hatch.first()
                last_hatchings.date = date
                last_hatchings.quantity = hatching_quantity
                last_hatchings.losses = losses
                last_hatchings.PersonTypeName = PersonTypeName
                last_hatchings.InteractTypeName = InteractTypeName
                last_hatchings.UnionTypeName = UnionTypeName
                last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1
                last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage
                last_hatchings.predicate_date = date + timedelta(
                    days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None
                last_hatchings.save()
            update = LastUpdate.objects.first()
            update.update_date = datetime.datetime.now()
            update.save()
        except:
            not_find_list.append(breeding_uniq_id)

        # poultry = Poultry.objects.filter(breeding_unique_id=breeding_uniq_id).first()
        # try:
        #     if not poultry:
        #         first_name = data['poultry']['FirstName']
        #         last_name = data['poultry']['LastName']
        #         mobile = data['poultry']['Mobile']
        #         system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
        #         if not system_profile:
        #
        #             data = {
        #                 "username": mobile,
        #                 "first_name": first_name,
        #                 "last_name": last_name,
        #                 "password": '123456',
        #                 "national_code": '0',
        #                 "role": "Poultry",
        #                 "api_key": PROJECT_API_KEY
        #             }
        #             req = requests.post(
        #                 url=ARTA_REGISTER,
        #                 data=data,
        #                 verify=False
        #             )
        #
        #             if req.status_code == 200:
        #                 hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
        #                 user = User.objects.filter(username=mobile).first()
        #                 if not user:
        #                     user = User(username=mobile, first_name=first_name, last_name=last_name,
        #                                 password=hashed_password)
        #                     user.save()
        #                 base_id = SystemUserProfile.objects.all()
        #                 if base_id.count() > 0:
        #                     base_id = int(base_id.last().base_order) + 1
        #                 else:
        #                     base_id = 1000
        #                 system_profile = SystemUserProfile(
        #                     mobile=mobile,
        #                     first_name=str(first_name),
        #                     last_name=str(last_name),
        #                     fullname=str(first_name) + ' ' + str(last_name),
        #                     user=user,
        #                     base_order=base_id,
        #                     password='123456',
        #                     birthday=str(datetime.datetime.now().date()),
        #                 )
        #                 system_profile.save()
        #
        #             else:
        #                 continue
        #
        #         group = Group.objects.get(name__exact="Poultry")
        #         if not system_profile.role.filter(name="Poultry"):
        #             system_profile.role.add(group)
        #
        #         wallet = Wallet()
        #         wallet.save()
        #         poultry = Poultry(
        #             user=system_profile,
        #             unit_name=poultry_name,
        #             system_code=data.get('poultry', {}).get('SystemCode',None),
        #             epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode',None),
        #             breeding_unique_id=breeding_uniq_id,
        #         )
        #         province=Province.objects.filter(trash=False,name__exact=province).first()
        #         city=City.objects.filter(trash=False,name__exact=city).first()
        #         address = SystemAddress(
        #             province=province,
        #             city=city,
        #             address=city
        #         )
        #         address.save()
        #         poultry.address = address
        #         poultry.user = system_profile
        #         poultry.wallet = wallet
        #         poultry.save()
        #
        #     poultry.unit_name = poultry_name
        #     poultry.save()
        #     hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
        #     if hatch:
        #         period = hatch.last().period + 1
        #     else:
        #         period = 1
        #
        #     # hatching_date = data['HatchingDatePersian'].split('/')
        #     date = data['Date']
        #
        #     poultry_hatching = hatch.filter(trash=False,archive=False, state='pending',
        #                                     allow_hatching='pending').order_by('id')
        #
        #     if not poultry_hatching.exists():
        #         if not hatch.filter(archive=True, state='complete',
        #                             allow_hatching="True",licence_number=licence_number).exists():
        #             hatching = PoultryHatching(
        #                 poultry=poultry,
        #                 date=date,
        #                 quantity=hatching_quantity,
        #                 breed=[
        #                     {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
        #                 period=period,
        #                 chicken_breed=data["PedigreeName"],
        #                 hall=1,
        #                 left_over=hatching_quantity,
        #                 latest_hatching_change={
        #                     "role": "UnitWindow",
        #                     "date": str(datetime.datetime.now().date()),
        #                     "full_name": ""
        #                 },
        #                 licence_number=licence_number,
        #                 breeding_unique_id=breeding_uniq_id,
        #                 losses=losses,
        #
        #             )
        #             hatching.save()
        #
        #     else:
        #         previouse_hatching = poultry_hatching.last()
        #
        #         hatchings = poultry_hatching.filter(licence_number=licence_number)
        #         if not hatchings:
        #             if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses):
        #                 previouse_hatching.violation = True
        #                 previouse_hatching.save()
        #
        #             hatching = PoultryHatching(
        #                 poultry=poultry,
        #                 date=date,
        #                 quantity=hatching_quantity,
        #                 breed=[
        #                     {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
        #                 period=period,
        #                 chicken_breed=data["PedigreeName"],
        #                 hall=1,
        #                 left_over=hatching_quantity,
        #                 latest_hatching_change={
        #                     "role": "UnitWindow",
        #                     "date": str(datetime.datetime.now().date()),
        #                     "full_name": ""
        #                 },
        #                 licence_number=licence_number,
        #                 breeding_unique_id=breeding_uniq_id,
        #                 losses=losses,
        #
        #             )
        #             hatching.save()
        #         else:
        #             last_hatchings=hatchings.first()
        #             # if last_hatchings.health_certificate is None:
        #             #     last_hatchings.health_certificate=health_certificate
        #             last_hatchings.date = date
        #             last_hatchings.quantity = hatching_quantity
        #             last_hatchings.losses = losses
        #             last_hatchings.save()
        #
        #     update = LastUpdate.objects.first()
        #     update.update_date = datetime.datetime.now()
        #     update.save()
        # except:
        #     not_find_list.append(breeding_uniq_id)
    if not_find_list:
        token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde"
        chat_id = '10046800'
        url = f'https://eitaayar.ir/api/{token}/sendMessage'
        base_message = f'{base_url_for_sms_report}' \
                       '\n'
        messages = []
        current_message = base_message
        new_message_part = ','.join(not_find_list)
        if len(current_message) + len(new_message_part) > 4000:  # محدودیت تعداد کاراکترها
            messages.append(current_message)
            current_message = base_message  # شروع یک پیام جدید

        current_message += new_message_part

        if current_message and current_message != base_message:
            messages.append(current_message)
        for message in messages:
            data = {
                'chat_id': chat_id,
                'text': message,
            }
            r = requests.post(url, data=data, verify=False)


def fix_bar_without_quarantine(request):
    kill_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False,
                                                   quarantine_code_state__isnull=False).only('clearance_code')
    print(len(kill_request))
    for kill in kill_request:
        get_gid(kill.clearance_code)
    return HttpResponse('ok')


def get_gid_out_province(id):
    kill = KillHouseFreeSaleBarInformation.objects.get(id=id, trash=False)
    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kill:
        data = {'gid': str(kill.clearance_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')
        text = context.body.get_text(strip=True)
        if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
            # kill.quarantine_code_state = 'notconfirmed'
            # if kill.quarantine_quantity is not None:
            #     kill.quarantine_weight_of_carcasses = None
            pass
        else:
            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:
                        jalali_date = date_match.group(1)
                        year, month, day = map(int, jalali_date.split('/'))
                        date = convert_to_miladi(year=year, month=month, day=day)
                        send_date = kill.date.date()

                        one_day = timedelta(days=1)
                        if abs(send_date - date.date()) <= one_day:
                            #     kill.inquiry_date = date.date()
                            for i in table[5:6]:
                                row = i.find_all('tr')
                                for r in row[0:1]:

                                    quantity = r.find_all('td')[1]
                                    match = re.search(r'\d+', quantity.text)

                                    if match:
                                        number = match.group()
                                        kill.quarantine_weight_of_carcasses = int(number)
                            # if kill.quarantine_code_state is not None:
                            #     kill.quarantine_code_state=None
                        else:
                            kill.quarantine_weight_of_carcasses = 0
                # for i in table[4:5]:
                #     rows = i.find_all('tr')
                #
                #     pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                #                              style='font-family:Tahoma').text.strip()
                #     kill.inquiry_pelak=pelak_txt
                #     td=rows[1].find_all('td')[1]
                #     driver_txt = td.find('span', class_='dynamictxt').text.strip()
                #     kill.inquiry_driver=driver_txt
                #
                #     for r in rows:
                #         tds = r.find_all('td', colspan="2")
                #         if len(tds) >= 2:
                #             origin_td = tds[0]
                #             origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                #             kill.inquiry_origin=origin_text
                #
                #             destination_td = tds[1]
                #             destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
                #             kill.inquiry_destination=destination_text

            else:
                for table in table:
                    p_tags = table.find_all('p')
                    for p in p_tags:
                        p_text = p.get_text(strip=True)
                        if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                            # kill.quarantine_code_state = 'contradiction'
                            if kill.quarantine_weight_of_carcasses > 0:
                                kill.quarantine_weight_of_carcasses = 0
        kill.save()


def get_gid_out_province_cron_job():
    kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0,
                                                           clearance_code__isnull=False, trash=False)
    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kills:
        for kill in kills:
            try:
                data = {'gid': str(kill.clearance_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')
                text = context.body.get_text(strip=True)
                if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                    # kill.quarantine_code_state = 'notconfirmed'
                    # if kill.quarantine_quantity is not None:
                    #     kill.quarantine_weight_of_carcasses = None
                    pass
                else:
                    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:
                                jalali_date = date_match.group(1)
                                year, month, day = map(int, jalali_date.split('/'))
                                date = convert_to_miladi(year=year, month=month, day=day)
                                # kill.inquiry_date = date.date()
                                if kill.date:
                                    send_date = kill.date.date()

                                    one_day = timedelta(days=1)
                                    if abs(send_date - date.date()) <= one_day:
                                        for i in table[5:6]:
                                            row = i.find_all('tr')
                                            for r in row[0:1]:

                                                quantity = r.find_all('td')[1]
                                                match = re.search(r'\d+', quantity.text)

                                                if match:
                                                    number = match.group()
                                                    kill.quarantine_weight_of_carcasses = int(number)
                                                    # if kill.quarantine_code_state is not None:
                                                    #     kill.quarantine_code_state=None
                                    else:
                                        kill.quarantine_weight_of_carcasses = 0
                    # for i in table[4:5]:
                    #     rows = i.find_all('tr')
                    #
                    #     pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                    #                              style='font-family:Tahoma').text.strip()
                    #     kill.inquiry_pelak=pelak_txt
                    #     td=rows[1].find_all('td')[1]
                    #     driver_txt = td.find('span', class_='dynamictxt').text.strip()
                    #     kill.inquiry_driver=driver_txt
                    #
                    #     for r in rows:
                    #         tds = r.find_all('td', colspan="2")
                    #         if len(tds) >= 2:
                    #             origin_td = tds[0]
                    #             origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                    #             kill.inquiry_origin=origin_text
                    #
                    #             destination_td = tds[1]
                    #             destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
                    #             kill.inquiry_destination=destination_text

                # else:
                #     for table in table:
                #         p_tags = table.find_all('p')
                #         for p in p_tags:
                #             p_text = p.get_text(strip=True)
                #             if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                #                 kill.quarantine_code_state = 'contradiction'
                #                 if kill.quarantine_quantity is not None:
                #                     kill.quarantine_quantity = None
                kill.save()
            except Exception:
                continue


def get_gid_out_province_manual(request):
    kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0,
                                                           clearance_code__isnull=False, trash=False)
    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kills:
        for kill in kills:
            data = {'gid': str(kill.clearance_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')
            text = context.body.get_text(strip=True)
            if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                # kill.quarantine_code_state = 'notconfirmed'
                # if kill.quarantine_quantity is not None:
                #     kill.quarantine_weight_of_carcasses = None
                pass
            else:
                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:
                            jalali_date = date_match.group(1)
                            year, month, day = map(int, jalali_date.split('/'))
                            date = convert_to_miladi(year=year, month=month, day=day)
                            # kill.inquiry_date = date.date()
                            send_date = kill.date.date()

                            one_day = timedelta(days=1)
                            if abs(send_date - date.date()) <= one_day:
                                for i in table[5:6]:
                                    row = i.find_all('tr')
                                    for r in row[0:1]:

                                        quantity = r.find_all('td')[1]
                                        match = re.search(r'\d+', quantity.text)

                                        if match:
                                            number = match.group()
                                            kill.quarantine_weight_of_carcasses = int(number)
                                            # if kill.quarantine_code_state is not None:
                                            #     kill.quarantine_code_state=None
                            else:
                                kill.quarantine_weight_of_carcasses = 0
                    # for i in table[4:5]:
                    #     rows = i.find_all('tr')
                    #
                    #     pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                    #                              style='font-family:Tahoma').text.strip()
                    #     kill.inquiry_pelak=pelak_txt
                    #     td=rows[1].find_all('td')[1]
                    #     driver_txt = td.find('span', class_='dynamictxt').text.strip()
                    #     kill.inquiry_driver=driver_txt
                    #
                    #     for r in rows:
                    #         tds = r.find_all('td', colspan="2")
                    #         if len(tds) >= 2:
                    #             origin_td = tds[0]
                    #             origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                    #             kill.inquiry_origin=origin_text
                    #
                    #             destination_td = tds[1]
                    #             destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
                    #             kill.inquiry_destination=destination_text

                # else:
                #     for table in table:
                #         p_tags = table.find_all('p')
                #         for p in p_tags:
                #             p_text = p.get_text(strip=True)
                #             if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                #                 kill.quarantine_code_state = 'contradiction'
                #                 if kill.quarantine_quantity is not None:
                #                     kill.quarantine_quantity = None
            kill.save()
    return HttpResponse(f'تعداد بار :{len(kills)}')


def get_gid_poultry_request(poultry_id):
    kill = PoultryRequest.objects.filter(id=poultry_id, trash=False).first()

    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kill:
        # if kill.quarantine_code_state!='merge':
        data = {'gid': str(kill.quarantine_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')
        text = context.body.get_text(strip=True)

        if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
            kill.quarantine_code_state = 'notconfirmed'
            if kill.quarantine_quantity is not None:
                kill.quarantine_quantity = None
        else:
            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:
                        jalali_date = date_match.group(1)
                        year, month, day = map(int, jalali_date.split('/'))
                        date = convert_to_miladi(year=year, month=month, day=day)
                        # kill.inquiry_date = date.date()
                        send_date = kill.send_date.date()

                        one_day = timedelta(days=1)
                        if abs(send_date - date.date()) <= one_day:
                            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:
                                        number = match.group()
                                        kill.quarantine_quantity = int(number)
                                        # if kill.quarantine_code_state is not None:
                                        #     kill.quarantine_code_state=None
                            # for i in table[4:5]:
                            #     rows = i.find_all('tr')
                            #
                            #     pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                            #                              style='font-family:Tahoma').text.strip()
                            #     kill.inquiry_pelak=pelak_txt
                            #     td=rows[1].find_all('td')[1]
                            #     driver_txt = td.find('span', class_='dynamictxt').text.strip()
                            #     kill.inquiry_driver=driver_txt
                            #
                            #     for r in rows:
                            #         tds = r.find_all('td', colspan="2")
                            #         if len(tds) >= 2:
                            #             origin_td = tds[0]
                            #             origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                            #             kill.inquiry_origin=origin_text
                            #
                            #             destination_td = tds[1]
                            #             destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
                            #             kill.inquiry_destination=destination_text
                        else:
                            kill.quarantine_quantity = 0

            else:
                for table in table:
                    p_tags = table.find_all('p')
                    for p in p_tags:
                        p_text = p.get_text(strip=True)
                        if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                            # kill.quarantine_code_state = 'contradiction'
                            if kill.quarantine_quantity > 0:
                                kill.quarantine_quantity = 0
        kill.save()


def get_gid_poultry_request_quarantine_code(poultry_id):
    kill = PoultryRequestQuarantineCode.objects.filter(id=poultry_id, trash=False).first()

    session = requests.Session()
    session.mount('https://', SSLAdapter())
    if kill:
        # if kill.quarantine_code_state!='merge':
        data = {'gid': str(kill.quarantine_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')
        text = context.body.get_text(strip=True)

        if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
            # kill.quarantine_code_state = 'notconfirmed'
            # if kill.quarantine_quantity is not None:
            #     kill.quarantine_quantity = None
            if kill.system_quarantine_quantity > 0:
                kill.system_quarantine_quantity = 0
        else:
            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:
                        jalali_date = date_match.group(1)
                        year, month, day = map(int, jalali_date.split('/'))
                        date = convert_to_miladi(year=year, month=month, day=day)
                        # kill.inquiry_date = date.date()
                        send_date = kill.poultry_request.send_date.date()

                        one_day = timedelta(days=1)
                        if abs(send_date - date.date()) <= one_day:
                            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:
                                        number = match.group()
                                        kill.system_quarantine_quantity = int(number)
                                        # if kill.quarantine_code_state is not None:
                                        #     kill.quarantine_code_state=None
                            # for i in table[4:5]:
                            #     rows = i.find_all('tr')
                            #
                            #     pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                            #                              style='font-family:Tahoma').text.strip()
                            #     kill.inquiry_pelak=pelak_txt
                            #     td=rows[1].find_all('td')[1]
                            #     driver_txt = td.find('span', class_='dynamictxt').text.strip()
                            #     kill.inquiry_driver=driver_txt
                            #
                            #     for r in rows:
                            #         tds = r.find_all('td', colspan="2")
                            #         if len(tds) >= 2:
                            #             origin_td = tds[0]
                            #             origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                            #             kill.inquiry_origin=origin_text
                            #
                            #             destination_td = tds[1]
                            #             destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
                            #             kill.inquiry_destination=destination_text
                        else:
                            kill.system_quarantine_quantity = 0

            else:
                for table in table:
                    p_tags = table.find_all('p')
                    for p in p_tags:
                        p_text = p.get_text(strip=True)
                        if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                            # kill.quarantine_code_state = 'contradiction'
                            if kill.system_quarantine_quantity > 0:
                                kill.system_quarantine_quantity = 0
        kill.save()


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def dashboard_monitoring_view(request):
    now = datetime.datetime.now().date()
    yesterday = now - timedelta(days=1)
    hatching = PoultryHatching.objects.filter(
        state='pending',
        archive=False,
        allow_hatching='pending',
        trash=False
    ).only(
        'quantity',
        'killed_quantity',
        'left_over',
        'chicken_age',
        'poultry'
    ).select_related('poultry')

    hatching_aggregates = hatching.aggregate(
        total_quantity=Sum('quantity'),
        total_killed_quantity=Sum('killed_quantity'),
        total_left_over=Sum('left_over'),
        total_left_over_between_40_75=Sum(
            'left_over',
            filter=Q(chicken_age__range=(40, 75))
        ),

        #
        total_left_over_lt_35=Sum(
            'left_over',
            filter=Q(chicken_age__lt=35)
        ),
        total_left_over_between_35_40=Sum(
            'left_over',
            filter=Q(chicken_age__range=(35, 39))
        ),
        total_left_over_between_40_45=Sum(
            'left_over',
            filter=Q(chicken_age__range=(40, 44))
        ),
        total_left_over_between_45_50=Sum(
            'left_over',
            filter=Q(chicken_age__range=(45, 49))
        ),
        total_left_over_between_50_55=Sum(
            'left_over',
            filter=Q(chicken_age__range=(50, 54))
        ),
        total_left_over_between_55_60=Sum(
            'left_over',
            filter=Q(chicken_age__range=(55, 59))
        ),
        total_left_over_between_60_65=Sum(
            'left_over',
            filter=Q(chicken_age__range=(60, 64))
        ),
        total_left_over_between_65_70=Sum(
            'left_over',
            filter=Q(chicken_age__range=(65, 70))
        ),
        total_left_over_gt_70=Sum(
            'left_over',
            filter=Q(chicken_age__gt=70)
        ),
        #
        total_killing_ave_age=Avg('poultry__killing_ave_age')
    )

    kill_house_free_bar = KillHouseFreeBarInformation.objects.filter(
        trash=False,
        archive_wage=False,
        date__date__gte=yesterday
    ).only(
        'quantity',
        'live_weight',
        'number_of_carcasses',
        'weight_of_carcasses',
        'send_date',
        'type',
        'out'
    )

    kill_house_free_bar_aggregates = kill_house_free_bar.aggregate(
        total_quantity_yesterday_live=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')),
        total_weight_yesterday_live=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')),
        total_quantity_yesterday_carcass=Sum('number_of_carcasses',
                                             filter=Q(date__date=yesterday, buy_type='carcass')),
        total_weight_yesterday_carcass=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')),

        total_quantity_live=Sum('quantity', filter=Q(create_date__date=now, buy_type='live')),
        total_weight_live=Sum('live_weight', filter=Q(create_date__date=now, buy_type='live')),
        total_quantity_carcass=Sum('number_of_carcasses',
                                   filter=Q(date__date=now, buy_type='carcass')),
        total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now, buy_type='carcass')),
        warehouse_total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now)),
        # yesterday
        total_quantity_live_yesterday=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')),
        total_weight_live_yesterday=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')),
        total_quantity_carcass_yesterday=Sum('number_of_carcasses',
                                             filter=Q(date__date=yesterday, buy_type='carcass')),
        total_weight_carcass_yesterday=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')),

    )

    poultry_request = PoultryRequest.objects.filter(
        trash=False,
        state_process__in=('pending', 'accepted'),
        province_state__in=('pending', 'accepted'),
        out_province_request_cancel=False,
        temporary_trash=False,
        temporary_deleted=False,
        send_date__date__gte=yesterday
    ).only(
        'quantity',
        'Index_weight',
        'send_date'
    )

    poultry_request_aggregates = poultry_request.aggregate(
        total_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=False, out=False)),
        total_weight=Sum(F('quantity') * F('Index_weight'),
                         filter=Q(send_date__date=now, direct_buying=False, out=False)),
        total_direct_buying_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=True)),
        total_direct_buying_weight=Sum(F('quantity') * F('Index_weight'),
                                       filter=Q(send_date__date=now, direct_buying=True)),
        total_quantity_out_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)),
        poultry_out_province_quantity=Sum('quantity', filter=Q(out=True, send_date__date=now)),
        poultry_out_province_weight=Sum(F('quantity') * F('Index_weight'), filter=Q(out=True, send_date__date=now)),
        total_killing_ave_weight=Avg('Index_weight', filter=Q(send_date__date=now)),
        # yesterday
        total_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=False, out=False)),
        total_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
                                   filter=Q(send_date__date=yesterday, direct_buying=False, out=False)),
        total_direct_buying_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=True)),
        total_direct_buying_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
                                                 filter=Q(send_date__date=yesterday, direct_buying=True)),
        poultry_out_province_quantity_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)),
        poultry_out_province_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
                                                  filter=Q(out=True, send_date__date=yesterday)),
        total_killing_ave_weight_yesterday=Avg('Index_weight', filter=Q(send_date__date=now))
    )

    province_kill_request = ProvinceKillRequest.objects.filter(
        trash=False,
        archive_wage=False,
        return_to_province=False,
        state__in=('pending', 'accepted'),
        kill_request__recive_date__date__gte=yesterday
    ).only(
        'total_killed_quantity',
        'total_killed_weight',
        'kill_request__recive_date'
    )

    province_kill_request_aggregates = province_kill_request.aggregate(
        total_quantity_yesterday=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=yesterday)),
        total_weight_yesterday=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=yesterday)),
        total_quantity=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=now)),
        total_weight_carcass=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)) * 0.75,
        province_kill_request_total_weight=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)),
        province_kill_request_total_weight_yesterday=Sum('total_killed_weight',
                                                         filter=Q(kill_request__recive_date__date=yesterday))
    )

    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        kill_request__recive_date__date__gte=yesterday,
        temporary_trash=False,
        temporary_deleted=False
    ).select_related('kill_request').only(
        'ware_house_accepted_real_weight',
        'weight_loss',
        'ware_house_confirmation',
        'kill_request__recive_date'
    )

    kill_house_request_aggregates = kill_house_request.aggregate(
        total_real_weight=Sum(
            'ware_house_accepted_real_weight',
            filter=Q(
                kill_request__recive_date__date=yesterday,
                ware_house_confirmation=True
            )
        ),
        total_weight_loss=Avg(
            'weight_loss',
            filter=Q(kill_request__recive_date__date=yesterday)
        ),
        total_quantity=Sum(
            'accepted_real_quantity',
            filter=Q(kill_request__recive_date__date=now)
        ),
        total_quantity_yesterday=Sum(
            'accepted_real_quantity',
            filter=Q(kill_request__recive_date__date=yesterday)
        ),
        total_weight_yesterday=Sum(
            'accepted_real_weight',
            filter=Q(kill_request__recive_date__date=yesterday)
        ),
        total_weight=Sum(
            'accepted_real_weight',
            filter=Q(kill_request__recive_date__date=now)
        ),
        total_real_weight_yesterday=Sum(
            'ware_house_accepted_real_weight',
            filter=Q(
                kill_request__recive_date__date=yesterday,
                ware_house_confirmation=True
            )
        )
    )

    kill_request = KillRequest.objects.filter(
        recive_date__date=now,
        trash=False,
        poultry__isnull=True,
        province_state='accepted'
    ).only(
        'kill_capacity',
        'recive_date',
        'province_state'
    )

    kill_request_aggregates = kill_request.aggregate(
        total_quantity=Sum('kill_capacity'),
    )

    if hatching_aggregates['total_left_over_between_40_75'] and poultry_request_aggregates['total_killing_ave_weight']:
        weight_between_forty_seventy_five = int(hatching_aggregates['total_left_over_between_40_75'] *
                                                poultry_request_aggregates['total_killing_ave_weight'])
    else:
        weight_between_forty_seventy_five = 0

    enter_warehouse_weight = (kill_house_free_bar_aggregates['warehouse_total_weight_carcass'] or 0) + (
            kill_house_request_aggregates['total_real_weight_yesterday'] or 0)
    roles_product = RolesProducts.objects.filter(trash=False)

    roles_product_aggregates = roles_product.aggregate(
        total_remain_weight=Sum('total_remain_weight'),
        total_out_province_allocated_weight=Sum('out_province_allocated_weight'),
    )

    cold_house = ColdHouse.objects.filter(trash=False).only(
        'total_remain_weight'
    )

    cold_house_aggregates = cold_house.aggregate(
        total_freezing_weight=Sum('total_remain_weight')
    )
    kill_house_free_sale_bar_aggregates = KillHouseFreeSaleBarInformation.objects.filter(
        trash=False
    ).aggregate(
        total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'),
        total_real_weight_of_carcasses_now=Sum('real_weight_of_carcasses', filter=Q(date__date=now))
    )
    steward_allocation = StewardAllocation.objects.filter(
        trash=False,
        calculate_status=True,
        temporary_trash=False,
        temporary_deleted=False,
        receiver_state__in=('accepted', 'pending')
    ).exclude(
        seller_type='ColdHouse'
    ).only(
        'real_weight_of_carcasses',
        'date'
    )

    steward_allocation_aggregates = steward_allocation.aggregate(
        total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'),
        total_real_weight_of_carcasses_now=Sum(
            'real_weight_of_carcasses',
            filter=Q(date__date=now)
        ),
    )

    chicken_price = ChickenCommissionPrices.objects.filter(trash=False, date__date__gte=now - timedelta(7)).order_by(
        'date')
    ser_data = ChickenCommissionPricesForDashboardSerializer(chicken_price, many=True)
    province_kill_request_weight = province_kill_request_aggregates['province_kill_request_total_weight'] or 0
    province_kill_request_total_weight_yesterday = province_kill_request_aggregates[
                                                       'province_kill_request_total_weight_yesterday'] or 0
    province_kill_request_weight_yesterday = province_kill_request_aggregates['total_weight_yesterday'] or 0
    bars_live_weight = kill_house_free_bar_aggregates['total_weight_live'] or 0
    total_weight_live_yesterday = kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0
    bars_carcasses_weight = kill_house_free_bar_aggregates['total_weight_carcass'] or 0
    total_weight_carcass_yesterday = kill_house_free_bar_aggregates['total_weight_carcass_yesterday'] or 0
    bars_yesterday_carcasses_weight = kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0
    bars_yesterday_live_weight = kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0
    total_loss_weight = int(((province_kill_request_weight + bars_live_weight) * 0.75) + bars_carcasses_weight)
    total_loss_weight_yesterday = int(((province_kill_request_total_weight_yesterday +
                                        total_weight_live_yesterday) * 0.75) + total_weight_carcass_yesterday)
    total_yesterday_loss_weight = int(((province_kill_request_weight_yesterday + bars_yesterday_live_weight)
                                       * 0.75) + bars_yesterday_carcasses_weight)

    result = {
        'hatching': {
            'quantity': hatching_aggregates['total_quantity'] or 0,
            'killedQuantity': hatching_aggregates['total_killed_quantity'] or 0,
            'leftOver': hatching_aggregates['total_left_over'] or 0,
            'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0,
            'killingAveAge': int(hatching_aggregates['total_killing_ave_age'] or 0),
            'total_left_over_lt_35': int(hatching_aggregates['total_left_over_lt_35'] or 0),
            'total_left_over_between_35_40': int(hatching_aggregates['total_left_over_between_35_40'] or 0),
            'total_left_over_between_40_45': int(hatching_aggregates['total_left_over_between_40_45'] or 0),
            'total_left_over_between_45_50': int(hatching_aggregates['total_left_over_between_45_50'] or 0),
            'total_left_over_between_50_55': int(hatching_aggregates['total_left_over_between_50_55'] or 0),
            'total_left_over_between_55_60': int(hatching_aggregates['total_left_over_between_55_60'] or 0),
            'total_left_over_between_60_65': int(hatching_aggregates['total_left_over_between_60_65'] or 0),
            'total_left_over_between_65_70': int(hatching_aggregates['total_left_over_between_65_70'] or 0),
            'total_left_over_gt_70': int(hatching_aggregates['total_left_over_gt_70'] or 0),
        },
        'yesterdayKilling': {
            'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_yesterday_live'] or 0,
            'weightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0,
            'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_yesterday_carcass'] or 0,
            'weightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0,
            'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity_yesterday'] or 0,
            'provinceKillRequestWeight': province_kill_request_aggregates['total_weight_yesterday'] or 0,
            'outQuantity': poultry_request_aggregates['total_quantity_out_yesterday'] or 0,
            # 'weightOfCarcass': kill_house_request_aggregates['total_real_weight'] or 0,
            # 'losses': round((kill_house_request_aggregates['total_weight_loss'] or 0),1),
            'weightOfCarcass': total_yesterday_loss_weight,
            'losses': 25,

        },
        'killing': {
            'quantity': poultry_request_aggregates['total_quantity'] or 0,
            'total_weight': poultry_request_aggregates['total_weight'] or 0,
            'killRequestQuantity': poultry_request_aggregates['total_direct_buying_quantity'] or 0,
            'killRequestWeight': poultry_request_aggregates['total_direct_buying_weight'] or 0,
            # 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0,
            'poultry_out_province_quantity': poultry_request_aggregates['poultry_out_province_quantity'] or 0,
            'poultry_out_province_weight': poultry_request_aggregates['poultry_out_province_weight'] or 0,
            'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_live'] or 0,
            'WeightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_live'] or 0,
            'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_carcass'] or 0,
            'WeightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_carcass'] or 0,
            'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity'] or 0,
            'provinceKillRequestWeightCarcass': int(
                province_kill_request_aggregates['province_kill_request_total_weight'] or 0),
            'KillHouseRequestQuantity': kill_house_request_aggregates['total_quantity'] or 0,
            'KillHouseRequestWeight': kill_house_request_aggregates['total_weight'] or 0,
            'total_loss_weight': int(total_loss_weight),

        },
        'killingYesterday': {
            'quantityYesterday': poultry_request_aggregates['total_quantity_yesterday'] or 0,
            'total_weightYesterday': poultry_request_aggregates['total_weight_yesterday'] or 0,
            'killRequestQuantityYesterday': poultry_request_aggregates['total_direct_buying_quantity_yesterday'] or 0,
            'killRequestWeightYesterday': poultry_request_aggregates['total_direct_buying_weight_yesterday'] or 0,
            # 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0,
            'poultry_out_province_quantityYesterday': poultry_request_aggregates[
                                                          'poultry_out_province_quantity_yesterday'] or 0,
            'poultry_out_province_weightYesterday': poultry_request_aggregates[
                                                        'poultry_out_province_weight_yesterday'] or 0,
            'quantityKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates[
                                                         'total_quantity_live_yesterday'] or 0,
            'WeightKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0,
            'quantityKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[
                                                            'total_quantity_carcass_yesterday'] or 0,
            'WeightKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[
                                                          'total_weight_carcass_yesterday'] or 0,
            'provinceKillRequestQuantityYesterday': province_kill_request_aggregates['total_quantity_yesterday'] or 0,
            'provinceKillRequestWeightCarcassYesterday': int(
                province_kill_request_aggregates['province_kill_request_total_weight_yesterday'] or 0),
            'KillHouseRequestQuantityYesterday': kill_house_request_aggregates['total_quantity_yesterday'] or 0,
            'KillHouseRequestWeightYesterday': kill_house_request_aggregates['total_weight_yesterday'] or 0,
            'total_loss_weightYesterday': int(total_loss_weight_yesterday),

        },
        'inventory': {
            'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0,
            'weightBetweenFortySeventyFive': weight_between_forty_seventy_five,
            'aveWeight': round((poultry_request_aggregates['total_killing_ave_weight'] or 0), 1),
            'carcassWeight': int(weight_between_forty_seventy_five * 0.75),

        },
        'warehouseKillHouse': {
            'remainingChickenStock': roles_product_aggregates['total_remain_weight'] or 0,
            'remainingFreezingWeight': cold_house_aggregates['total_freezing_weight'] or 0,
            'outProvinceAllocatedWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses'] or 0,
            'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses'] or 0,

        },
        'warehouseInformation': {
            'enterWarehouseWeight': enter_warehouse_weight,
            'outSellWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses_now'] or 0,
            'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses_now'] or 0,
            'leftOverWarehouseWeight': roles_product_aggregates['total_remain_weight'] or 0,

        },
        'chickenPrice': ser_data.data
    }
    return Response(result, status=status.HTTP_200_OK)


def remove_access_token_manual(request):
    ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/"
    requests.get(
        url=ARTA_remove_access_token,
        verify=False
    )
    now = datetime.datetime.now()
    accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3))
    for access in accesses:
        access.expires = now - timedelta(days=2)
        access.save()
    return HttpResponse('ok')


def find_gid_code_manual(request):
    kill_house_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False,
                                                         quarantine_quantity__isnull=True).only(
        'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
    ).order_by('-id')
    session = requests.Session()
    session.mount('https://', SSLAdapter())

    for kill in kill_house_request:
        if kill.quarantine_code_state != 'merge':
            if kill.clearance_code is None:
                kill.quarantine_code_state = 'noclearance'
            else:
                data = {'gid': str(kill.clearance_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')
                text = context.body.get_text(strip=True)
                if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش  اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
                    kill.quarantine_code_state = 'notconfirmed'
                    if kill.quarantine_quantity is not None:
                        kill.quarantine_quantity = None
                else:
                    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:
                                jalali_date = date_match.group(1)
                                year, month, day = map(int, jalali_date.split('/'))
                                date = convert_to_miladi(year=year, month=month, day=day)
                                kill.inquiry_date = date.date()
                                send_date = kill.kill_request.recive_date.date()

                                one_day = timedelta(days=1)
                                if abs(send_date - date.date()) <= one_day:
                                    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:
                                                number = match.group()
                                                kill.quarantine_quantity = int(number)
                                                if kill.quarantine_code_state is not None:
                                                    kill.quarantine_code_state = None
                                    for i in table[4:5]:
                                        rows = i.find_all('tr')

                                        pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
                                                                 style='font-family:Tahoma').text.strip()
                                        kill.inquiry_pelak = pelak_txt
                                        td = rows[1].find_all('td')[1]
                                        driver_txt = td.find('span', class_='dynamictxt').text.strip()
                                        kill.inquiry_driver = driver_txt

                                        for r in rows:
                                            tds = r.find_all('td', colspan="2")
                                            if len(tds) >= 2:
                                                origin_td = tds[0]
                                                origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
                                                kill.inquiry_origin = origin_text

                                                destination_td = tds[1]
                                                destination_text = destination_td.find('span',
                                                                                       class_='dynamictxt').text.strip()
                                                kill.inquiry_destination = destination_text
                                else:
                                    kill.quarantine_code_state = 'contradiction'
                                    kill.quarantine_quantity = None

                    else:
                        for table in table:
                            p_tags = table.find_all('p')
                            for p in p_tags:
                                p_text = p.get_text(strip=True)
                                if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
                                    kill.quarantine_code_state = 'contradiction'
                                    if kill.quarantine_quantity is not None:
                                        kill.quarantine_quantity = None
        kill.save()
    return HttpResponse('ok')


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def get_all_pos_transaction(request):
    filters = {}
    date1 = request.GET.get('date1')
    date2 = request.GET.get('date2')
    price_type = request.GET.get('price_type')
    paid = request.GET.get('paid')
    validator = PosDeviceValidator(request)
    validation_error = validator.validation_version()
    if validation_error:
        return validation_error

    validation_device = validator.validation_device()
    if not validation_device:
        return Response({"result": "نشست شما منقضی شده لطفا مجدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)

    pos = POSMachine.objects.get(pos_id=validation_device)
    filters['trash'] = False
    filters['pos'] = pos

    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 price_type:
        filters['price_type__in'] = price_type.split(',')

    if paid:
        filters['paid'] = True if paid == 'true' else False

    transactions = PosMachineTransactions.objects.filter(**filters).only('price', 'price_type').order_by('-date')
    product_transactions = ProductsTransactions.objects.filter(trash=False, transaction__in=transactions).only \
        ('price', 'cur_weight', 'targetunit', 'image')

    transactions_aggregate = transactions.aggregate(
        total_price=Sum('price'),
        total_price_cash=Sum('price', filter=Q(price_type='cash')),
        total_price_credit=Sum('price', filter=Q(price_type='credit')),
        total_price_card=Sum('price', filter=Q(price_type='card')),
    )

    product_groups = defaultdict(lambda: {'price': 0, 'weight': 0, 'targetunit': None, 'image': None})

    for pt in product_transactions:
        product_groups[pt.name]['price'] += pt.price
        product_groups[pt.name]['weight'] += pt.cur_weight
        if not product_groups[pt.name]['targetunit']:
            product_groups[pt.name]['targetunit'] = pt.targetunit
        if not product_groups[pt.name]['image']:
            product_groups[pt.name]['image'] = pt.image

    unique_products = [{
        'name': name,
        'price': data['price'],
        'weight': data['weight'],
        'targetunit': data['targetunit'],
        'image': data['image']
    } for name, data in product_groups.items()]

    result_dict = {
        'count': transactions.count(),
        'total_price': transactions_aggregate['total_price'] or 0,
        'total_price_cash': transactions_aggregate['total_price_cash'] or 0,
        'total_price_credit': transactions_aggregate['total_price_credit'] or 0,
        'total_price_card': transactions_aggregate['total_price_card'] or 0,
        'products': unique_products
    }

    return Response(result_dict)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def send_clearance_code_to_rsi(request):
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        temporary_trash=False,
        temporary_deleted=False,
        clearance_code__isnull=False
    ).values_list('clearance_code', flat=True).distinct()

    kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
        .values_list('quarantine_code', flat=True).distinct()

    result = list(kill_house_request) + list(kill_house_free_sale)

    response = requests.post(
        f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}'
        f'&date1={date1}&date2={date2}',
        json=result,
        headers={'Content-Type': 'application/json'}
    )

    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 response.json():
                if data['Out'] == False:
                    vet_farm_mobile = ''
                    vet_farm_name = ''
                    vet_farm = VetFarm.objects.filter(trash=False,
                                                      poultry__breeding_unique_id=data['hatching']['poultry'][
                                                          'PartIdCode']).first()
                    if vet_farm:
                        vet_farm_mobile = vet_farm.vet.user.mobile
                        vet_farm_name = vet_farm.vet.user.fullname
                    unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
                    unique_slaughterhouses_out_false.add(data['DesUnitName'])
                    total_slaughter_out_false += data['GoodAmount']
                    date_str = str(data['Date']).split('T')[0]  # جدا کردن بخش تاریخ
                    date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
                    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['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 response.json() 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 response.json():
                if data['Out'] == True:
                    vet_farm_mobile = ''
                    vet_farm_name = ''
                    vet_farm = VetFarm.objects.filter(trash=False,
                                                      poultry__breeding_unique_id=data['hatching']['poultry'][
                                                          'PartIdCode']).first()
                    if vet_farm:
                        vet_farm_mobile = vet_farm.vet.user.mobile
                        vet_farm_name = vet_farm.vet.user.fullname

                    unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
                    unique_slaughterhouses_out_false.add(data['DesUnitName'])
                    total_slaughter_out_false += data['GoodAmount']
                    date_str = str(data['Date']).split('T')[0]  # جدا کردن بخش تاریخ
                    date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
                    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['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 response.json() if data['Out'] == False) 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


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def api_send_clearance_code_to_rsi(request):
    page = ''
    search_filter = ''
    province = f'province={base_url_for_sms_report}'
    search = request.GET.get('search')
    value = request.GET.get('value')
    if search:
        if search != 'undefined' and value.strip():
            search_filter = f'&search={search}&value={value}'
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        temporary_trash=False,
        temporary_deleted=False,
        clearance_code__isnull=False
    ).values_list('clearance_code', flat=True).distinct()

    kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
        .values_list('quarantine_code', flat=True).distinct()

    result = list(kill_house_request) + list(kill_house_free_sale)
    if 'page' in request.GET:
        page = f'&page={request.GET["page"]}&page_size={request.GET["page_size"]}'

    response = requests.get(
        f'https://rsibackend.rasadyar.com/app/api_send_different_bar/?{province}{page}'
        f'{search_filter}'
        f'&date1={date1}&date2={date2}',
        json=result,
        headers={'Content-Type': 'application/json'}
    )

    return Response(response.json(), status=status.HTTP_200_OK)


@api_view(["POST"])
@permission_classes([AllowAny])
@csrf_exempt
def create_steward_allocation_from_excel(request):
    file = request.FILES['file'].read()
    read = openpyxl.load_workbook(BytesIO(file), data_only=True)
    sheet = read.active
    result_list = []
    for i, row in enumerate(sheet.iter_rows(values_only=True)):
        if i <= 1:
            continue

        mobile = row[3]
        kill_house_name = row[4]
        allocation_type = row[5]
        date = row[6]
        sell_type = row[7]
        seller_type = 'KillHouse'
        type = 'manual'
        weight_of_carcasses = row[8]
        amount = row[9]

        buyer_type = 'Steward' if allocation_type == 'مباشر' else 'Guild'
        try:
            miladi_date = date.split('/')
            new_date = convert_to_miladi(
                year=int(miladi_date[0]),
                month=int(miladi_date[1]),
                day=int(miladi_date[2])
            )
            kill_house = KillHouse.objects.filter(name=kill_house_name, trash=False).first()
            user = SystemUserProfile.objects.filter(trash=False, mobile=mobile).first()
            if user:
                to_steward = None
                to_guild = None
                if buyer_type == 'Steward':
                    to_steward = Guilds.objects.get(user=user, trash=False)
                else:
                    to_guild = Guilds.objects.get(user=user, trash=False)
                product = RolesProducts.objects.get(kill_house=kill_house)
                steward_allocation = StewardAllocation(
                    date=new_date,
                    real_weight_of_carcasses=weight_of_carcasses,
                    weight_of_carcasses=weight_of_carcasses,
                    product=product,
                    kill_house=kill_house,
                    seller_type=seller_type,
                    allocation_type='killhouse_guild' if allocation_type == 'صنف' else 'killhouse_steward',
                    sell_type='exclusive' if sell_type == 'اختصاصی' else 'free',
                    type=type,
                    amount=amount,
                    total_amount=int(amount * weight_of_carcasses),
                )
                if buyer_type == 'Steward':
                    steward_allocation.to_steward = to_steward
                else:
                    steward_allocation.to_guilds = to_guild
                steward_allocation.save()
                kill_house_allocations_product_warehousing(product)
        except:
            result_list.append(mobile)
    return Response(result_list)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def send_bar_info_from_ticket(request):
    user = SystemUserProfile.objects.get(trash=False, key=request.GET['key'])
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
    kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('id')
    kill_house_request = KillHouseRequest.objects.filter(trash=False,
                                                         kill_request__recive_date__date__gte=date1,
                                                         kill_request__recive_date__date__lte=date2,
                                                         temporary_trash=False, temporary_deleted=False)
    if kill_house_request:
        message = 'با سلام و احترام' \
                  '***' \
                  'بدینوسیله گزارش اسناد بارهای کشتارگاه ها از مورخه {0} تا {1} به شرح زیر بحضور ایفاد میگردد:' \
                  '***' \
                  '***'.format(shamsi_date(date1), shamsi_date(date2))
    else:
        message = 'با سلام و احترام' \
                  '***' \
                  ' از مورخه {0} تا {1} باری وجود ندارد.' \
                  '***' \
                  '***'.format(shamsi_date(date1), shamsi_date(date2))
    m = 1
    for kill_house in kill_houses:
        kill_house_request1 = kill_house_request.filter(trash=False, killhouse_user=kill_house,
                                                        kill_request__recive_date__date__gte=date1,
                                                        kill_request__recive_date__date__lte=date2,
                                                        temporary_trash=False, temporary_deleted=False)
        bar_count = kill_house_request1.count()
        bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count()
        bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True').count()
        bar_document_status = kill_house_request1.filter(bar_document_status__isnull=False).count()
        bar_document_status_titles = kill_house_request1.values_list('bar_document_status__title', flat=True)
        bars_info = []
        if (None not in bar_document_status_titles and bar_document_status_titles) or (bar_assigment_pending_count != 0) \
                or (bar_assigment_true_count > 0):
            message += '{0}) {1} :' \
                       'تعداد {2} بار ایجاد شده است.***'.format(m, kill_house.name, to_locale_str(bar_count))
            if bar_assigment_pending_count > 0 or bar_assigment_true_count > 0:
                message += '📑 {1} بار دارای سند(بارنامه) و تعداد {0} بار فاقد سند(بارنامه) میباشد.*** '. \
                    format(to_locale_str(bar_assigment_pending_count), to_locale_str(bar_assigment_true_count))
            if bar_document_status > 0:
                message += '🌐 از بارهای دارای سند تعداد {0} بار توسط ربات هوش مصنوعی سامانه مورد بررسی قرار گرفت که به شرح زیر میباشد: '. \
                    format(to_locale_str(bar_document_status))
                status_counts = Counter(bar_document_status_titles)
                for title, count in status_counts.items():
                    if title:
                        bars_info.append(
                            '***' \
                            '🚛 {0} بار شامل سند ({1})'.format(to_locale_str(count), title))

            if bars_info:
                message += '.'.join(bars_info)

            message += '***' \
                       '-------------------------------------------------------' \
                       '***' \
                       '***'
            m += 1

    new_ticket = TicketSupport(
        user=user,
        title="استعلام اسناد بارها از مورخه {0} تا {1}".format(shamsi_date(date1), shamsi_date(date2)),
        status='open',
        read_only=True,
        type_ticket='single',
        parent=None,
        last_message='Admin',
    )
    new_ticket.save()
    new_ticket.to_user.add(user)
    msg = MessageSupport(
        ticket=new_ticket,
        message=message,
        created_by=user,
        sender='Admin'
    )
    msg.save()
    return Response({'result': 'با موفقیت انجام شد.'}, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def all_clearance_code_to_rsi(request):
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    # kill_house_request = KillHouseRequest.objects.filter(
    #     trash=False,
    #     temporary_trash=False,
    #     temporary_deleted=False,
    #     clearance_code__isnull=False
    # ).values_list('clearance_code', flat=True).distinct()
    #
    # kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
    #     .values_list('quarantine_code', flat=True).distinct()

    result = []

    response = requests.post(
        f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}'
        f'&date1={date1}&date2={date2}',
        json=result,
        headers={'Content-Type': 'application/json'}
    )

    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 response.json():
                if data['Out'] == False:
                    vet_farm_mobile = ''
                    vet_farm_name = ''
                    vet_farm = VetFarm.objects.filter(trash=False,
                                                      poultry__breeding_unique_id=data['hatching']['poultry'][
                                                          'PartIdCode']).first()
                    if vet_farm:
                        vet_farm_mobile = vet_farm.vet.user.mobile
                        vet_farm_name = vet_farm.vet.user.fullname
                    unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
                    unique_slaughterhouses_out_false.add(data['DesUnitName'])
                    total_slaughter_out_false += data['GoodAmount']
                    date_str = str(data['Date']).split('T')[0]  # جدا کردن بخش تاریخ
                    date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
                    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 response.json() 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 response.json():
                if data['Out'] == True:
                    vet_farm_mobile = ''
                    vet_farm_name = ''
                    vet_farm = VetFarm.objects.filter(trash=False,
                                                      poultry__breeding_unique_id=data['hatching']['poultry'][
                                                          'PartIdCode']).first()
                    if vet_farm:
                        vet_farm_mobile = vet_farm.vet.user.mobile
                        vet_farm_name = vet_farm.vet.user.fullname

                    unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
                    unique_slaughterhouses_out_false.add(data['DesUnitName'])
                    total_slaughter_out_false += data['GoodAmount']
                    date_str = str(data['Date']).split('T')[0]  # جدا کردن بخش تاریخ
                    date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
                    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 response.json() if data['Out'] == False) 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


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def ticket_different_clearance_code_from_rsi(request):
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    poultry_hatchings_licence_numbers = PoultryHatching.objects.filter(trash=False,
                                                                       licence_number=request.GET.get('licence_number'))

    for poultry_hatching in poultry_hatchings_licence_numbers:
        poultry_hatching_licence_number = poultry_hatching.licence_number
        response = requests.post(
            f'https://rsibackend.rasadyar.com/app/send_different_bar_with_licence_number/?'
            f'licence_number={poultry_hatching_licence_number}'
            f'&date1={date1}&date2={date2}',
            headers={'Content-Type': 'application/json'}
        )
        kill_house_request = KillHouseRequest.objects.filter(trash=False,
                                                             province_request__poultry_request__hatching__licence_number
                                                             =poultry_hatching_licence_number,
                                                             temporary_trash=False,
                                                             temporary_deleted=False).order_by(
            '-kill_request__recive_date')
        if date1:
            kill_house_request.filter(kill_request__recive_date__date__gte=date1,
                                      kill_request__recive_date__date__lte=date2)
        vet_farm = VetFarm.objects.filter(trash=False, poultry=poultry_hatching.poultry).first()
        code_rasadyar = []

        all_quantity_in_rsi = 0
        for i in response.json():
            all_quantity_in_rsi += i['GoodAmount']
        bars_info = []
        for kill_req in kill_house_request:
            if kill_req.clearance_code:
                quarantine_code = kill_req.clearance_code
                code_rasadyar.append(quarantine_code)

            else:
                quarantine_code = 'ندارد'
            bars_info.append(
                'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
                    quarantine_code,
                    to_locale_str(int(kill_req.accepted_real_quantity)),
                    kill_req.killhouse_user.name,
                    shamsi_date(kill_req.kill_request.recive_date)
                ))
        poultry_requests = PoultryRequest.objects.filter(trash=False, out=True,
                                                         state_process__in=('pending', 'accepted'),
                                                         province_state__in=('pending', 'accepted'),
                                                         out_province_request_cancel=False,
                                                         hatching=poultry_hatching).order_by(
            '-send_date'
        )
        # code_rsi=[data['TrackingCode'] for data in response.json()]
        bars_info_rsi = []
        rsi_quantity = 0
        for poultry_request in poultry_requests:
            if poultry_request.quarantine_code:
                quarantine_code = poultry_request.quarantine_code
                code_rasadyar.append(quarantine_code)

            else:
                quarantine_code = 'ندارد'
            bars_info.append(
                'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
                    quarantine_code,
                    to_locale_str(int(poultry_request.quantity)),
                    poultry_request.buyer_fullname,
                    shamsi_date(poultry_request.send_date),
                ))
        chain_allocations = ChainAllocation.objects.filter(trash=False, poultry_hatching=poultry_hatching).order_by(
            '-date')
        for poultry_request in chain_allocations:
            if poultry_request.quarantine_code:
                quarantine_code = poultry_request.quarantine_code
                code_rasadyar.append(quarantine_code)
            else:
                quarantine_code = 'ندارد'
            bars_info.append(
                'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
                    quarantine_code,
                    to_locale_str(int(poultry_request.quantity)),
                    poultry_request.buyer_name,
                    shamsi_date(poultry_request.date),
                ))
        for bar in response.json():
            rsi_quantity += bar['GoodAmount']
            date_str = str(bar['Date']).split('T')[0]
            date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
            state = '✅' if bar['TrackingCode'] in code_rasadyar else '❌'
            bars_info_rsi.append(
                'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3}){4}'.format(
                    bar['TrackingCode'],
                    to_locale_str(int(bar['GoodAmount'])),
                    bar['DesUnitName'],
                    shamsi_date(date),
                    state
                ))

        bars_details = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info)])
        bars_details_rsi = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info_rsi)])
        accepted_real_quantity = 0
        accepted_real_quantity += kill_house_request.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get('total_quantity') or 0
        accepted_real_quantity += chain_allocations.aggregate(
            total_quantity=Sum('quantity')).get('total_quantity') or 0
        accepted_real_quantity += poultry_requests.aggregate(
            total_quantity=Sum('quantity')).get('total_quantity') or 0
        if rsi_quantity - accepted_real_quantity > 0:
            new_message = 'در مجموع شما {0} قطعه بدون مجوز کشتار در سامانه قرنطینه ثبت کرده اید.' \
                          '***' \
                          'در صورت تکرار و عدم رعایت موضوع و ضوابط اجرایی در استان،مراتب و گزارش تخلف به مراجع مسئول ارجاع میگردد.' \
                          '***' \
                          '***' \
                .format(to_locale_str(int(rsi_quantity - accepted_real_quantity)))
            new_message1 = 'خارج از سامانه مجوز حمل'
        else:
            new_message = ''
            new_message1 = 'اطلاعات زیر'
        message = " دامپزشک محترم فارم {0}({9})" \
                  "***" \
                  "با سلام" \
                  "***" \
                  "با توجه بررسی های انجام شده" \
                  " و استعلامات از پایش کشوری سامانه" \
                  " رصد یار برای فارم {1} با شناسه یکتا {10} و شماره مجوز جوجه ریزی {11} {12} صادر گردیده است." \
                  "***" \
                  "***" \
                  "اطلاعات مجوز صادر شده در قرنطینه:" \
                  "***" \
                  "{2}" \
                  "***" \
                  "جمعا {3} بار با مجموع {4} قطعه" \
                  "***" \
                  "***" \
                  "اطلاعات مجوز صادر شده در رصدیار : " \
                  "***" \
                  "{5}" \
                  "***" \
                  "جمعا {6} بار با مجموع {7} قطعه" \
                  "***" \
                  "***" \
                  "{8}" \
                  "ربات هوشمند سامانه رصدیار" \
                  "".format(vet_farm.vet.user.fullname, poultry_hatching.poultry.unit_name, bars_details_rsi,
                            len(response.json()),
                            to_locale_str(int(rsi_quantity)),
                            bars_details,
                            len(kill_house_request), to_locale_str(int(accepted_real_quantity)),
                            new_message, vet_farm.vet.user.mobile,
                            poultry_hatching.poultry.breeding_unique_id, poultry_hatching.licence_number, new_message1)

        user = SystemUserProfile.objects.filter(trash=False, mobile=request.GET['mobile']).last()
        new_ticket = TicketSupport(
            user=user,
            title="گزارش کشتار جوجه ریزی",
            status='open',
            read_only=True,
            type_ticket='single',
            parent=None,
            last_message='Admin',
        )
        new_ticket.save()
        new_ticket.to_user.add(user)
        msg = MessageSupport(
            ticket=new_ticket,
            message=message,
            created_by=user,
            sender='Admin'
        )
        msg.save()
    return Response('ok', status=status.HTTP_200_OK)


def delete_kill_req_cron():
    current_time = datetime.datetime.now()
    kill_requests = KillRequest.objects.filter(Q(market_final_accept=True, market_code_status=True,
                                                 input_market_code__isnull=True) | Q(market_final_accept=False),
                                               trash=False,
                                               market=True,
                                               market_state='pending',
                                               market_expire_date_time__lt=current_time
                                               ).select_related('poultry_request')
    for kill_request in kill_requests:
        kill_request.trash = True
        kill_request.market_state_message = {
            "fullname": "سیستمی",
            "mobile": "سیستمی",
            "date": str(datetime.datetime.now())
        }
        kill_request.market_state = 'deleted'
        kill_request.save()
        market_poultry_request_remain_quantity(kill_request.poultry_request)


def delete_steward_allocation_cron():
    current_time = datetime.datetime.now().date()
    # allow=AllowRegisterCodeForStewardAllocation.objects.filter(trash=False,active=True).first()
    # if allow:
    steward_allocation = StewardAllocation.objects.filter(trash=False,
                                                          date__date=current_time,
                                                          receiver_state='pending',
                                                          active_expire_date_time=True,
                                                          logged_registration_code__isnull=True,
                                                          kill_house__isnull=False,
                                                          return_trash=False).order_by('id')
    for allocation in steward_allocation:
        product = allocation.product
        seller_type = allocation.seller_type
        to_cold_house = allocation.to_cold_house
        other_cold_house = allocation.other_cold_house if allocation.other_cold_house else None
        allocation.trash = True
        allocation.save()
        if seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(product)
            if to_cold_house and to_cold_house.kill_house == product.kill_house:
                kill_house_cold_house_allocations(to_cold_house)

        elif seller_type == 'ColdHouse':
            cold_house_warehousing(to_cold_house)
            if other_cold_house:
                cold_house_warehousing(other_cold_house)

        else:
            guild_steward_allocations_product_warehousing(product)


def archive_kill_house_remain_limitation_weight_cron():
    production_date = (datetime.datetime.now() - datetime.timedelta(days=3)).date()
    archive_date = (datetime.datetime.now() - datetime.timedelta(days=3))
    kill_houses = KillHouse.objects.filter(trash=False, out_province=False)
    for kill_house in kill_houses:
        kill_house_requests = KillHouseRequest.objects.filter(input_warehouse=kill_house,
                                                              province_request__poultry_request__free_sale_in_province=False,
                                                              kill_request__recive_date__date=production_date,
                                                              ware_house_confirmation=True, trash=False,
                                                              calculate_status=True, warehouse=True)

        kill_house_allocations = StewardAllocation.objects.filter(
            kill_house=kill_house, trash=False, calculate_status=True, warehouse=True, system_registration_code=True,
            receiver_state__in=('pending', 'accepted'), production_date__date=production_date, quota='governmental')

        kill_house_free_sale_bars = KillHouseFreeSaleBarInformation.objects.filter(kill_house=kill_house,
                                                                                   quota='governmental',
                                                                                   production_date__date=production_date,
                                                                                   trash=False,
                                                                                   calculate_status=True,
                                                                                   warehouse=True)
        segmentations = PosSegmentation.objects.filter(kill_house=kill_house, production_date__date=production_date,
                                                       trash=False, warehouse=True,
                                                       quota='governmental')

        kill_house_requests_weight = kill_house_requests.aggregate(total=Sum('ware_house_accepted_real_weight'))[
                                         'total'] or 0
        kill_house_allocations_weight = \
            kill_house_allocations.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0
        kill_house_free_sale_bars_weight = kill_house_free_sale_bars.aggregate(total=Sum('real_weight_of_carcasses'))[
                                               'total'] or 0

        segmentation_weight = \
            segmentations.aggregate(total=Sum('weight'))[
                'total'] or 0

        archives = WarehouseArchive.objects.filter(kill_house=kill_house, date__date=production_date,
                                                   quota='governmental',
                                                   trash=False)

        archives_governmental_weight = \
            archives.aggregate(total=Sum('weight'))[
                'total'] or 0

        total_input = kill_house_requests_weight
        total_output = kill_house_allocations_weight + kill_house_free_sale_bars_weight + segmentation_weight + archives_governmental_weight
        total_remain = total_input - total_output

        if total_remain > 0:
            if kill_house.ware_house_remaining_weight_archive_percent > 0:
                percent_limitation_weight = total_input * (kill_house.ware_house_remaining_weight_archive_percent / 100)
                if percent_limitation_weight >= total_remain:
                    archive = WarehouseArchive(
                        kill_house=kill_house,
                        date=archive_date,
                        quota='governmental',
                        weight=total_remain,
                        registerer='سیستم',
                        registerer_mobile='سیستم',
                        registerer_role='سیستم',
                        description='مانده کمتر از استاندارد  تعیین شده',
                    )
                    archive.save()
                    kill_house_archive_warehousing(archive.kill_house)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def hatching_unknown(request):
    age_range = ChickenAgeRange.objects.filter(active=True, trash=False).first()
    if age_range:
        hatchings = PoultryHatching.objects.filter(
            state='pending',
            archive=False,
            allow_hatching='pending',
            trash=False,
            unknown=False,
            chicken_age__gt=age_range.maximum
        )
        poultries = Poultry.objects.filter(id__in=hatchings.values_list('poultry__id', flat=True)).update(
            order_limit=True)
        hatchings.update(unknown=True)

    return Response("done!")


def hatching_unknown_cron():
    age_range = ChickenAgeRange.objects.filter(active=True, trash=False).first()
    if age_range:
        hatchings = PoultryHatching.objects.filter(
            state='pending',
            archive=False,
            allow_hatching='pending',
            trash=False,
            unknown=False,
            chicken_age__gt=age_range.maximum
        )
        poultries = Poultry.objects.filter(id__in=hatchings.values_list('poultry__id', flat=True)).update(
            order_limit=True)
        hatchings.update(unknown=True)


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def management_kill_house_dashboard(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()
    poultry_hatching = PoultryHatching.objects.filter(Q(date__date__gte=date1, date__date__lte=date2) |
                                                      Q(date__date__lte=date1,
                                                        archive_date__isnull=True) | Q(date__date__lte=date1,
                                                                                       archive_date__gte=date1,
                                                                                       archive_date__isnull=False),
                                                      trash=False).select_related('poultry', 'poultry__user__city')
    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        kill_request__recive_date__date__gte=date1,
        kill_request__recive_date__date__lte=date2,
        temporary_trash=False,
        temporary_deleted=False
    ).select_related('killhouse_user')
    aggregate_kill_house_request = kill_house_request.aggregate(
        total_id=Count('id'),
        total_accepted_real_quantity=Sum('accepted_real_quantity'),
        total_accepted_real_weight=Sum('accepted_real_weight'),
        total_quantity_has_quarantine=Sum('accepted_real_quantity', filter=Q(quarantine_quantity__gt=0)),
        total_count_has_quarantine=Count('id', filter=Q(quarantine_quantity__gt=0)),
        total_quarantine_quantity=Sum('quarantine_quantity', filter=Q(quarantine_quantity__gt=0)),

        total_id_hasnt_code=Count('id', filter=Q(clearance_code__isnull=True)),
        total_quantity_hasnt_code=Sum('accepted_real_quantity', filter=Q(clearance_code__isnull=True)),
        total_weight_hasnt_code=Sum('accepted_real_weight', filter=Q(clearance_code__isnull=True)),
        total_id_hasnt_warehouse=Count('id', filter=Q(ware_house_confirmation=False)),
        total_quantity_hasnt_warehouse=Sum('accepted_real_quantity', filter=Q(ware_house_confirmation=False)),
        total_weight_hasnt_warehouse=Sum('accepted_real_weight', filter=Q(ware_house_confirmation=False)),
        total_id_hasnt_assignment_state_archive=Count('id', filter=Q(assignment_state_archive='pending')),
        total_quantity_hasnt_assignment_state_archive=Sum('accepted_real_quantity',
                                                          filter=Q(assignment_state_archive='pending')),
        total_weight_hasnt_assignment_state_archive=Sum('accepted_real_weight',
                                                        filter=Q(assignment_state_archive='pending')),
        total_id_hasnt_killing_age=Count('id', filter=Q(province_request__poultry_request__killing_age__gte=60)),
        total_quantity_hasnt_killing_age=Sum('accepted_real_quantity',
                                             filter=Q(province_request__poultry_request__killing_age__gte=60)),
        total_weight_hasnt_killing_age=Sum('accepted_real_weight',
                                           filter=Q(province_request__poultry_request__killing_age__gte=60)),

    )
    kill_house_req_stats = kill_house_request.values('killhouse_user__name').annotate(
        total_quantity=Sum('accepted_real_quantity'),
        transaction_count=Count('id')
    ).order_by('-total_quantity')
    top_kill_house_req = kill_house_req_stats.first() if kill_house_req_stats else None
    kill_house_name_req = "-"
    total_quantity_top_inner = 0
    if top_kill_house_req:
        kill_house_name_req = top_kill_house_req['killhouse_user__name']
        total_quantity_top_inner = top_kill_house_req['total_quantity']

    poultry_req_stats = kill_house_request.values(
        'province_request__poultry_request__hatching__poultry__unit_name',
        'province_request__poultry_request__hatching__poultry__user__city__name') \
        .annotate(total_quantity=Sum('accepted_real_quantity'),
                  ).order_by('-total_quantity')
    top_poultry_req_stats = poultry_req_stats.first() if poultry_req_stats else None
    top_poultry_req_stats_total_quantity = 0
    poultry_req_name_req = "-"
    poultry_city_req_name_req = "-"
    if top_poultry_req_stats:
        poultry_req_name_req = top_poultry_req_stats['province_request__poultry_request__hatching__poultry__unit_name']
        poultry_city_req_name_req = top_poultry_req_stats[
            'province_request__poultry_request__hatching__poultry__user__city__name']
        top_poultry_req_stats_total_quantity = to_locale_str(top_poultry_req_stats['total_quantity'] or 0)

    aggregate_hatching = poultry_hatching.aggregate(
        total_quantity=Sum('quantity'),
        total_losses_vet=Sum('losses'),
        total_losses_union=Sum('direct_losses'),
        total_losses=Sum('total_losses'),
        killed_quantity=Sum('killed_quantity'),
        total_killed_weight=Sum('total_killed_weight'),
        left_over=Sum('left_over'),
        total_killing_ave_age=Avg('poultry__killing_ave_age')
    )
    top_total_killed_weight = poultry_hatching.values('id').annotate(
        total_killed_weight=Sum('total_killed_weight'),
    ).order_by('-total_killed_weight')
    top_total_killed_weight_first = top_total_killed_weight.first() if top_total_killed_weight else None

    free_bars = KillHouseFreeBarInformation.objects.filter(date__date__gte=date1,
                                                           date__date__lte=date2,
                                                           trash=False, buy_type='live').select_related('kill_house')
    kill_house_stats = free_bars.values('kill_house__name').annotate(
        total_quantity=Sum('quantity'),
        total_live_weight=Sum('live_weight'),
        transaction_count=Count('id')
    ).order_by('-total_quantity')

    top_kill_house = kill_house_stats.first() if kill_house_stats else None
    kill_house_name = "-"
    total_quantity_top_out = 0
    transaction_count = "-"
    if top_kill_house:
        kill_house_name = top_kill_house['kill_house__name']
        transaction_count = to_locale_str(top_kill_house['transaction_count'] or 0)
        total_quantity_top_out = to_locale_str(top_kill_house['total_quantity'] or 0)
    #
    out_poultry_req_stats = free_bars.values('poultry_name', 'province', 'city').annotate(
        total_quantity=Sum('quantity'),
    ).order_by('-total_quantity')
    top_out_poultry_req_stats = out_poultry_req_stats.first() if out_poultry_req_stats else None
    out_top_poultry_req_stats_total_quantity = 0
    out_poultry_req_name_req = "-"
    out_poultry_city_req_name_req = "-"
    out_poultry_province_req_name_req = "-"
    if top_out_poultry_req_stats:
        out_poultry_req_name_req = top_out_poultry_req_stats['poultry_name']
        out_poultry_city_req_name_req = top_out_poultry_req_stats['city']
        out_poultry_province_req_name_req = top_out_poultry_req_stats['province']
        out_top_poultry_req_stats_total_quantity = to_locale_str(top_out_poultry_req_stats['total_quantity'] or 0)

    #
    aggregate_free_bars = free_bars.aggregate(
        id=Count('id'),
        quantity=Sum('quantity'),
        live_weight=Sum('live_weight'),
    )

    max_kill_day = free_bars.values('date__date').annotate(
        daily_quantity=Sum('quantity')
    ).order_by('-daily_quantity').first()
    persian_date = '-'
    daily_quantity = '-'
    if max_kill_day:
        persian_date = shamsi_date(max_kill_day['date__date'])
        daily_quantity = to_locale_str(max_kill_day['daily_quantity'])

    max_kill_day_req = kill_house_request.values('kill_request__recive_date__date').annotate(
        daily_quantity=Sum('accepted_real_quantity')
    ).order_by('-daily_quantity').first()
    persian_date_req = '-'
    daily_quantity_req = '-'
    if max_kill_day_req:
        persian_date_req = shamsi_date(max_kill_day_req['kill_request__recive_date__date'])
        daily_quantity_req = to_locale_str(max_kill_day_req['daily_quantity'])

    kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('name')
    kill_house_data = []
    duc_kill_house_data = []

    for kh in kill_houses:
        new_steward_allocations = StewardAllocation.objects.filter(
            trash=False,
            date__date__gte=date1,
            date__date__lte=date2,
            kill_house=kh
        )
        in_province_data = kill_house_request.filter(
            killhouse_user=kh
        ).aggregate(
            load_count=Count('id'),
            quantity=Sum('accepted_real_quantity'),
            weight=Sum('accepted_real_weight')
        )

        out_province_data = free_bars.filter(
            kill_house=kh
        ).aggregate(
            load_count=Count('id'),
            quantity=Sum('quantity'),
            live_weight=Sum('live_weight'),
        )

        in_qty = in_province_data.get('quantity', 0) or 0
        in_weight = in_province_data.get('weight', 0) or 0
        out_qty = out_province_data.get('quantity', 0) or 0
        out_weight = out_province_data.get('live_weight', 0) or 0
        total_quantity = in_qty + out_qty
        total_weight = in_weight + out_weight
        wight_of_steward = new_steward_allocations.filter(to_steward__isnull=False).aggregate(
            total_quantity=Sum('real_weight_of_carcasses')
        )
        len_of_steward = new_steward_allocations.filter(to_steward__isnull=False).count()
        len_of_guild = new_steward_allocations.filter(to_guilds__isnull=False).count()
        wight_of_guild = new_steward_allocations.filter(to_guilds__isnull=False).aggregate(
            total_quantity=Sum('real_weight_of_carcasses')
        )

        in_loads = in_province_data.get('load_count', 0) or 0
        out_loads = out_province_data.get('load_count', 0) or 0
        total_loads = in_loads + out_loads

        # if in_qty > 0 or out_qty > 0 or in_loads > 0 or out_loads > 0:
        kill_house_data.append({
            'name': kh.name,
            'load_count': to_locale_str(total_loads or 0),
            'in_province_quantity': to_locale_str(in_qty or 0),
            'in_province_wight': to_locale_str(in_weight or 0),
            'out_province_quantity': to_locale_str(out_qty or 0),
            'out_province_weight': to_locale_str(out_weight or 0),
            'total_quantity': to_locale_str(total_quantity or 0),
            'total_weight': to_locale_str(total_weight or 0),

            'wight_of_steward': to_locale_str(wight_of_steward['total_quantity'] or 0),
            'wight_of_guild': to_locale_str(wight_of_guild['total_quantity'] or 0),
            'len_of_steward': to_locale_str(len_of_steward),
            'len_of_guild': to_locale_str(len_of_guild),
        })
    free_bars = KillHouseFreeSaleBarInformation.objects.filter(
        trash=False,
        date__date__gte=date1,
        date__date__lte=date2,
        kill_house__in=kill_houses
    ).values('kill_house_id', 'kill_house__name').annotate(
        total_quantity=Sum('weight_of_carcasses')
    ).order_by('-total_quantity')

    bar_assigment_pending_count1 = kill_house_request.filter(assignment_state_archive='True') \
        .exclude(bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count()
    steward_allocations = StewardAllocation.objects.filter(
        trash=False,
        date__date__gte=date1,
        date__date__lte=date2,
        kill_house__in=kill_houses
    ).values('kill_house_id').annotate(
        total_quantity=Sum('real_weight_of_carcasses')
    )
    in_province_data = kill_house_request.filter(
        killhouse_user__in=kill_houses
    ).values('killhouse_user_id').annotate(
        total_quantity=Sum('accepted_real_weight')
    )

    in_warehouse_data = kill_house_request.filter(
        killhouse_user__in=kill_houses,
        ware_house_confirmation=True
    ).values('killhouse_user_id').annotate(
        total_quantity=Sum('ware_house_accepted_real_weight')
    )

    products = RolesProducts.objects.filter(
        trash=False,
        kill_house__in=kill_houses
    ).values('kill_house_id', 'total_remain_weight')

    steward_dict = {item['kill_house_id']: item['total_quantity'] for item in steward_allocations}
    free_bar_dict = {item['kill_house_id']: item['total_quantity'] for item in free_bars}
    in_province_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_province_data}
    in_warehouse_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_warehouse_data}
    product_dict = {item['kill_house_id']: item['total_remain_weight'] for item in products}

    management_kill_house_data = []
    for kh in kill_houses:
        kh_id = kh.id

        steward_qty = steward_dict.get(kh_id, 0) or 0
        free_bar_qty = free_bar_dict.get(kh_id, 0) or 0
        in_province_qty = in_province_dict.get(kh_id, 0) or 0
        in_warehouse_qty = in_warehouse_dict.get(kh_id, 0) or 0
        product_weight = product_dict.get(kh_id, 0) or 0

        # if any([in_province_qty, in_warehouse_qty, steward_qty, free_bar_qty]):
        total = free_bar_qty + steward_qty
        percent = round(total * 100 / in_province_qty, 1) if in_province_qty else 0

        management_kill_house_data.append({
            'name': kh.name,
            'in_province_quantity': to_locale_str(in_province_qty),
            'in_ware_house_quantity': to_locale_str(in_warehouse_qty),
            'steward_allocation_quantity': to_locale_str(steward_qty),
            'kill_house_free_bar_quantity': to_locale_str(free_bar_qty),
            'all_quantity': to_locale_str(total),
            'product': to_locale_str(product_weight),
            'percent': percent
        })
    n_steward_allocations_n = StewardAllocation.objects.filter(
        trash=False,
        date__date__gte=date1,
        date__date__lte=date2,
        kill_house__in=kill_houses
    )
    n_steward_allocations = n_steward_allocations_n.aggregate(
        total_quantity=Sum('real_weight_of_carcasses')
    )
    n_steward_allocations_to_steward = n_steward_allocations_n.filter(to_steward__isnull=False)
    aggregate_n_steward_allocations_to_steward = n_steward_allocations_to_steward.aggregate(
        total_quantity=Sum('real_weight_of_carcasses')
    )

    n_steward_allocations_to_guild = n_steward_allocations_n.filter(to_guilds__isnull=False)
    aggregate_n_steward_allocations_to_guild = n_steward_allocations_to_guild.aggregate(
        total_quantity=Sum('real_weight_of_carcasses')
    )
    steward_and_guild = {
        'len_of_steward': n_steward_allocations_to_steward.count(),
        'wight_of_steward': aggregate_n_steward_allocations_to_steward['total_quantity'] or 0,
        'len_of_guild': n_steward_allocations_to_guild.count(),
        'wight_of_guild': aggregate_n_steward_allocations_to_guild['total_quantity'] or 0,
        'total_weight': n_steward_allocations['total_quantity'] or 0,
    }
    n_free_bars = KillHouseFreeSaleBarInformation.objects.filter(
        trash=False,
        date__date__gte=date1,
        date__date__lte=date2,
        kill_house__in=kill_houses
    ).aggregate(
        total_quantity=Sum('weight_of_carcasses')
    )

    n_in_province_data = kill_house_request.filter(
        killhouse_user__in=kill_houses
    ).aggregate(
        total_quantity=Sum('accepted_real_weight')
    )

    n_in_warehouse_data = kill_house_request.filter(
        killhouse_user__in=kill_houses,
        ware_house_confirmation=True
    ).aggregate(
        total_quantity=Sum('ware_house_accepted_real_weight')
    )

    n_products = RolesProducts.objects.filter(
        trash=False,
        kill_house__in=kill_houses
    ).aggregate(
        total_quantity=Sum('total_remain_weight')
    )
    all_management_kill_house_data = {
        'in_province': n_in_province_data['total_quantity'] or 0,
        'in_warehouse': n_in_warehouse_data['total_quantity'] or 0,
        'steward_allocations': n_steward_allocations['total_quantity'] or 0,
        'free_bars': n_free_bars['total_quantity'] or 0,
        'total': (n_free_bars['total_quantity'] or 0) + (n_steward_allocations['total_quantity'] or 0),
        'products': n_products['total_quantity'] or 0,
    }

    for kh in kill_houses:
        kill_house_request1 = kill_house_request.filter(
            killhouse_user=kh
        )

        bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True')
        bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count()
        bar_document_status_accepted = bar_assigment_true_count.filter(
            bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count()
        bar_document_status_rejected = bar_assigment_true_count.exclude(
            bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count()

        # if bar_assigment_true_count.count() > 0 or bar_assigment_pending_count > 0:
        duc_kill_house_data.append({
            'name': kh.name,
            'kill_house_request1_count': kill_house_request1.count(),
            "bar_assigment_true_count": bar_assigment_true_count.count(),
            "bar_assigment_pending_count": bar_assigment_pending_count,
            "bar_document_status_accepted": bar_document_status_accepted,
            "percent_bar_document_status_accepted": int((bar_document_status_accepted /
                                                         bar_assigment_true_count.count()) * 100) if
            bar_assigment_true_count.count() > 0 else 0,
            "bar_document_status_rejected": bar_document_status_rejected,
            "percent_bar_document_status_rejected": int((bar_document_status_rejected /
                                                         bar_assigment_true_count.count()) * 100) if
            bar_assigment_true_count.count() > 0 else 0,

        })

    different_bar = (aggregate_kill_house_request['total_quantity_has_quarantine'] or 0) \
                    - (aggregate_kill_house_request['total_quarantine_quantity'] or 0)
    different_bar_percent = int(different_bar / (aggregate_kill_house_request['total_quarantine_quantity'] or 0) * 100) \
        if (aggregate_kill_house_request['total_quarantine_quantity'] or 0) > 0 else 0

    result = {
        'all_management_kill_house_data': all_management_kill_house_data,
        'management_kill_house_data': management_kill_house_data,

        "poultry_hatching_total_killed_weight": aggregate_hatching['total_killed_weight'] or 0,
        "total_weight_hasnt_warehouse": aggregate_kill_house_request['total_weight_hasnt_warehouse'] or 0,
        'kill_houses_data': kill_house_data,

        #
        "kill_house_request_count": to_locale_str(aggregate_kill_house_request['total_id'] or 0),
        "kill_house_request_quantity": to_locale_str(aggregate_kill_house_request['total_accepted_real_quantity'] or 0),
        "kill_house_request_weight": to_locale_str(aggregate_kill_house_request['total_accepted_real_weight'] or 0),
        "kill_house_request_average_weight": round(
            aggregate_kill_house_request['total_accepted_real_weight'] / aggregate_kill_house_request[
                'total_accepted_real_quantity'], 1)
        if (aggregate_kill_house_request['total_accepted_real_quantity'] or 0) > 0 else 0,
        "free_bars_count": to_locale_str(aggregate_free_bars['id'] or 0),
        "free_bars_quantity": to_locale_str(aggregate_free_bars['quantity'] or 0),
        "free_bars_live_weight": to_locale_str(aggregate_free_bars['live_weight'] or 0),
        "kill_house_name": kill_house_name,
        "transaction_count": transaction_count,
        "persian_date": persian_date,
        "daily_quantity": daily_quantity,
        "persian_date_req": persian_date_req,
        "daily_quantity_req": daily_quantity_req,
        'kill_house_name_req': kill_house_name_req,
        'poultry_req_name_req': poultry_req_name_req,
        'top_poultry_req_stats_total_quantity': top_poultry_req_stats_total_quantity,
        'poultry_city_req_name_req': poultry_city_req_name_req,
        'out_poultry_req_name_req': out_poultry_req_name_req,
        'out_poultry_city_req_name_req': out_poultry_city_req_name_req,
        'out_poultry_province_req_name_req': out_poultry_province_req_name_req,
        'out_top_poultry_req_stats_total_quantity': out_top_poultry_req_stats_total_quantity,
        'duc_kill_house_data': duc_kill_house_data,
        'avg_losses': to_locale_str(int((aggregate_hatching['total_losses'] or 0) / poultry_hatching.count())),
        'avg_total_killed_weight': round(
            (aggregate_hatching['total_killed_weight'] or 0) / (aggregate_hatching['killed_quantity'] or 0), 1),
        'total_killing_ave_age': int(aggregate_hatching['total_killing_ave_age'] or 0),
        'top_total_killed_weight': to_locale_str(top_total_killed_weight_first['total_killed_weight'] or 0),
        'total_quantity_top_inner': to_locale_str(total_quantity_top_inner),
        'total_quantity_top_out': total_quantity_top_out,
        'bar_assigment_pending_count1': to_locale_str(bar_assigment_pending_count1 or 0),
        'base_url': base_url_for_sms_report,
        "total_quarantine_quantity": to_locale_str(aggregate_kill_house_request['total_quarantine_quantity'] or 0),
        "total_count_has_quarantine": to_locale_str(aggregate_kill_house_request['total_count_has_quarantine'] or 0),
        "total_quantity_has_quarantine": to_locale_str(
            aggregate_kill_house_request['total_quantity_has_quarantine'] or 0),
        "different": to_locale_str(different_bar or 0),
        "total_weight_hasnt_code": to_locale_str(aggregate_kill_house_request['total_weight_hasnt_code'] or 0),
        "total_quantity_hasnt_code": to_locale_str(aggregate_kill_house_request['total_quantity_hasnt_code'] or 0),
        "total_id_hasnt_code": to_locale_str(aggregate_kill_house_request['total_id_hasnt_code'] or 0),

        "total_quantity_hasnt_warehouse": to_locale_str(
            aggregate_kill_house_request['total_quantity_hasnt_warehouse'] or 0),
        "total_id_hasnt_warehouse": to_locale_str(aggregate_kill_house_request['total_id_hasnt_warehouse'] or 0),
        "total_weight_hasnt_assignment_state_archive": to_locale_str(
            aggregate_kill_house_request['total_weight_hasnt_assignment_state_archive'] or 0),
        "total_quantity_hasnt_assignment_state_archive": to_locale_str(
            aggregate_kill_house_request['total_quantity_hasnt_assignment_state_archive'] or 0),
        "total_id_hasnt_assignment_state_archive": to_locale_str(
            aggregate_kill_house_request['total_id_hasnt_assignment_state_archive'] or 0),
        "total_weight_hasnt_killing_age": to_locale_str(
            aggregate_kill_house_request['total_weight_hasnt_killing_age'] or 0),
        "total_quantity_hasnt_killing_age": to_locale_str(
            aggregate_kill_house_request['total_quantity_hasnt_killing_age'] or 0),
        "total_id_hasnt_killing_age": to_locale_str(aggregate_kill_house_request['total_id_hasnt_killing_age'] or 0),
        'different_bar_percent': different_bar_percent,
        "steward_and_guild": steward_and_guild

    }
    return Response(result)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def periodic_performance_report_dashboard(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()
    poultry_hatching = PoultryHatching.objects.filter(Q(date__date__gte=date1, date__date__lte=date2) |
                                                      Q(date__date__lte=date1,
                                                        archive_date__isnull=True) | Q(date__date__lte=date1,
                                                                                       archive_date__gte=date1,
                                                                                       archive_date__isnull=False),
                                                      trash=False).select_related('poultry', 'poultry__user__city')
    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        kill_request__recive_date__date__gte=date1,
        kill_request__recive_date__date__lte=date2,
        temporary_trash=False,
        temporary_deleted=False
    ).select_related('killhouse_user')
    aggregate_kill_house_request = kill_house_request.aggregate(
        total_id=Count('id'),
        total_accepted_real_quantity=Sum('accepted_real_quantity'),
        total_accepted_real_weight=Sum('accepted_real_weight'),
        total_quantity_has_quarantine=Sum('accepted_real_quantity', filter=Q(quarantine_quantity__gt=0)),
        total_count_has_quarantine=Count('id', filter=Q(quarantine_quantity__gt=0)),
        total_quarantine_quantity=Sum('quarantine_quantity', filter=Q(quarantine_quantity__gt=0)),

        total_id_hasnt_code=Count('id', filter=Q(clearance_code__isnull=True)),
        total_quantity_hasnt_code=Sum('accepted_real_quantity', filter=Q(clearance_code__isnull=True)),
        total_weight_hasnt_code=Sum('accepted_real_weight', filter=Q(clearance_code__isnull=True)),
        total_id_hasnt_warehouse=Count('id', filter=Q(ware_house_confirmation=False)),
        total_quantity_hasnt_warehouse=Sum('accepted_real_quantity', filter=Q(ware_house_confirmation=False)),
        total_weight_hasnt_warehouse=Sum('accepted_real_weight', filter=Q(ware_house_confirmation=False)),
        total_id_hasnt_assignment_state_archive=Count('id', filter=Q(assignment_state_archive='pending')),
        total_quantity_hasnt_assignment_state_archive=Sum('accepted_real_quantity',
                                                          filter=Q(assignment_state_archive='pending')),
        total_weight_hasnt_assignment_state_archive=Sum('accepted_real_weight',
                                                        filter=Q(assignment_state_archive='pending')),
        total_id_hasnt_killing_age=Count('id', filter=Q(province_request__poultry_request__killing_age__gte=60)),
        total_quantity_hasnt_killing_age=Sum('accepted_real_quantity',
                                             filter=Q(province_request__poultry_request__killing_age__gte=60)),
        total_weight_hasnt_killing_age=Sum('accepted_real_weight',
                                           filter=Q(province_request__poultry_request__killing_age__gte=60)),

    )
    kill_house_req_stats = kill_house_request.values('killhouse_user__name').annotate(
        total_quantity=Sum('accepted_real_quantity'),
        transaction_count=Count('id')
    ).order_by('-total_quantity')
    top_kill_house_req = kill_house_req_stats.first() if kill_house_req_stats else None
    kill_house_name_req = "-"
    total_quantity_top_inner = 0
    if top_kill_house_req:
        kill_house_name_req = top_kill_house_req['killhouse_user__name']
        total_quantity_top_inner = top_kill_house_req['total_quantity']

    poultry_req_stats = kill_house_request.values(
        'province_request__poultry_request__hatching__poultry__unit_name',
        'province_request__poultry_request__hatching__poultry__user__city__name') \
        .annotate(total_quantity=Sum('accepted_real_quantity'),
                  ).order_by('-total_quantity')
    top_poultry_req_stats = poultry_req_stats.first() if poultry_req_stats else None
    top_poultry_req_stats_total_quantity = 0
    poultry_req_name_req = "-"
    poultry_city_req_name_req = "-"
    if top_poultry_req_stats:
        poultry_req_name_req = top_poultry_req_stats['province_request__poultry_request__hatching__poultry__unit_name']
        poultry_city_req_name_req = top_poultry_req_stats[
            'province_request__poultry_request__hatching__poultry__user__city__name']
        top_poultry_req_stats_total_quantity = to_locale_str(top_poultry_req_stats['total_quantity'] or 0)

    poultry_hatching_gt_60 = poultry_hatching.filter(chicken_age__gt=60)
    poultry_hatching_has_killed = PoultryRequest.objects.filter(state_process__in=('pending', 'accepted'),
                                                                province_state__in=('pending', 'accepted'),
                                                                trash=False, out=False, hatching__in=poultry_hatching)
    if poultry_hatching_has_killed:
        max_age_poultry = poultry_hatching_has_killed.order_by('-killing_age').first()
        min_age_poultry = poultry_hatching_has_killed.order_by('killing_age').first()
        max_and_min_dict = {"max_age_poultry": max_age_poultry.killing_age or 0,
                            "max_age_poultry_name": max_age_poultry.hatching.poultry.unit_name or '-',
                            "max_age_poultry_city": max_age_poultry.hatching.poultry.user.city.name if max_age_poultry.hatching.poultry.user.city else '-',
                            "max_age_poultry_quantity": max_age_poultry.hatching.quantity or 0,
                            "max_age_poultry_killed_quantity": max_age_poultry.hatching.killed_quantity or 0,
                            "max_age_poultry_left_over": max_age_poultry.hatching.left_over or 0,
                            "min_age_poultry": min_age_poultry.killing_age or 0,
                            "min_age_poultry_name": min_age_poultry.hatching.poultry.unit_name or '-',
                            "min_age_poultry_city": min_age_poultry.hatching.poultry.user.city.name if min_age_poultry.hatching.poultry.user.city else '-',
                            "min_age_poultry_quantity": min_age_poultry.hatching.quantity or 0,
                            "min_age_poultry_killed_quantity": min_age_poultry.hatching.killed_quantity or 0,
                            "min_age_poultry_left_over": min_age_poultry.hatching.left_over or 0}
    else:
        max_and_min_dict = {"max_age_poultry": 0,
                            "max_age_poultry_name": '-',
                            "max_age_poultry_city": '-',
                            "max_age_poultry_quantity": 0,
                            "max_age_poultry_killed_quantity": 0,
                            "max_age_poultry_left_over": 0,
                            "min_age_poultry": 0,
                            "min_age_poultry_name": '-',
                            "min_age_poultry_city": '-',
                            "min_age_poultry_quantity": 0,
                            "min_age_poultry_killed_quantity": 0,
                            "min_age_poultry_left_over": 0}

    aggregate_poultry_hatching_gt_60 = poultry_hatching_gt_60.aggregate(
        total_quantity=Sum('quantity'),
        left_over=Sum('left_over'),
    )
    aggregate_hatching = poultry_hatching.aggregate(
        total_quantity=Sum('quantity'),
        total_losses_vet=Sum('losses'),
        total_losses_union=Sum('direct_losses'),
        total_losses=Sum('total_losses'),
        killed_quantity=Sum('killed_quantity'),
        total_killed_weight=Sum('total_killed_weight'),
        left_over=Sum('left_over'),
        total_killing_ave_age=Avg('poultry__killing_ave_age')
    )
    top_total_killed_weight = poultry_hatching.values('id').annotate(
        total_killed_weight=Sum('total_killed_weight'),
    ).order_by('-total_killed_weight')
    top_total_killed_weight_first = top_total_killed_weight.first() if top_total_killed_weight else None

    free_bars = KillHouseFreeBarInformation.objects.filter(date__date__gte=date1,
                                                           date__date__lte=date2,
                                                           trash=False, buy_type='live').select_related('kill_house')
    kill_house_stats = free_bars.values('kill_house__name').annotate(
        total_quantity=Sum('quantity'),
        total_live_weight=Sum('live_weight'),
        transaction_count=Count('id')
    ).order_by('-total_quantity')

    top_kill_house = kill_house_stats.first() if kill_house_stats else None
    kill_house_name = "-"
    total_quantity_top_out = 0
    transaction_count = "-"
    if top_kill_house:
        kill_house_name = top_kill_house['kill_house__name']
        transaction_count = to_locale_str(top_kill_house['transaction_count'] or 0)
        total_quantity_top_out = to_locale_str(top_kill_house['total_quantity'] or 0)
    #
    out_poultry_req_stats = free_bars.values('poultry_name', 'province', 'city').annotate(
        total_quantity=Sum('quantity'),
    ).order_by('-total_quantity')
    top_out_poultry_req_stats = out_poultry_req_stats.first() if out_poultry_req_stats else None
    out_top_poultry_req_stats_total_quantity = 0
    out_poultry_req_name_req = "-"
    out_poultry_city_req_name_req = "-"
    out_poultry_province_req_name_req = "-"
    if top_out_poultry_req_stats:
        out_poultry_req_name_req = top_out_poultry_req_stats['poultry_name']
        out_poultry_city_req_name_req = top_out_poultry_req_stats['city']
        out_poultry_province_req_name_req = top_out_poultry_req_stats['province']
        out_top_poultry_req_stats_total_quantity = to_locale_str(top_out_poultry_req_stats['total_quantity'] or 0)

    #
    aggregate_free_bars = free_bars.aggregate(
        id=Count('id'),
        quantity=Sum('quantity'),
        live_weight=Sum('live_weight'),
    )

    max_kill_day = free_bars.values('date__date').annotate(
        daily_quantity=Sum('quantity')
    ).order_by('-daily_quantity').first()
    persian_date = '-'
    daily_quantity = '-'
    if max_kill_day:
        persian_date = shamsi_date(max_kill_day['date__date'])
        daily_quantity = to_locale_str(max_kill_day['daily_quantity'])

    max_kill_day_req = kill_house_request.values('kill_request__recive_date__date').annotate(
        daily_quantity=Sum('accepted_real_quantity')
    ).order_by('-daily_quantity').first()
    persian_date_req = '-'
    daily_quantity_req = '-'
    if max_kill_day_req:
        persian_date_req = shamsi_date(max_kill_day_req['kill_request__recive_date__date'])
        daily_quantity_req = to_locale_str(max_kill_day_req['daily_quantity'])

    kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('-name')
    kill_house_data = []
    duc_kill_house_data = []

    for kh in kill_houses:
        in_province_data = kill_house_request.filter(
            killhouse_user=kh
        ).aggregate(
            load_count=Count('id'),
            quantity=Sum('accepted_real_quantity'),
            weight=Sum('accepted_real_weight')
        )

        out_province_data = free_bars.filter(
            kill_house=kh
        ).aggregate(
            load_count=Count('id'),
            quantity=Sum('quantity'),
            live_weight=Sum('live_weight'),
        )

        in_qty = in_province_data.get('quantity', 0) or 0
        in_weight = in_province_data.get('weight', 0) or 0
        out_qty = out_province_data.get('quantity', 0) or 0
        out_weight = out_province_data.get('live_weight', 0) or 0
        total_quantity = in_qty + out_qty
        total_weight = in_weight + out_weight

        in_loads = in_province_data.get('load_count', 0) or 0
        out_loads = out_province_data.get('load_count', 0) or 0
        total_loads = in_loads + out_loads

        if in_qty > 0 or out_qty > 0 or in_loads > 0 or out_loads > 0:
            kill_house_data.append({
                'name': kh.name,
                'load_count': to_locale_str(total_loads or 0),
                'load_count_in_province': to_locale_str(in_loads or 0),
                'load_count_out_province': to_locale_str(out_loads or 0),
                'in_province_quantity': to_locale_str(in_qty or 0),
                'in_province_wight': to_locale_str(in_weight or 0),
                'out_province_quantity': to_locale_str(out_qty or 0),
                'out_province_weight': to_locale_str(out_weight or 0),
                'total_quantity': to_locale_str(total_quantity or 0),
                'total_weight': to_locale_str(total_weight or 0),
            })
    bar_assigment_pending_count1 = kill_house_request.filter(assignment_state_archive='True') \
        .exclude(bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count()
    tomorrow_of_date1 = date1 + datetime.timedelta(days=1)
    tomorrow_of_date2 = date2 + datetime.timedelta(days=1)
    steward_allocations = StewardAllocation.objects.filter(
        trash=False,
        date__date__gte=tomorrow_of_date1,
        date__date__lte=tomorrow_of_date2,
        kill_house__in=kill_houses
    ).values('kill_house_id').annotate(
        total_quantity=Sum('real_weight_of_carcasses')
    )

    free_bars = KillHouseFreeSaleBarInformation.objects.filter(
        trash=False,
        date__date__gte=tomorrow_of_date1,
        date__date__lte=tomorrow_of_date2,
        kill_house__in=kill_houses
    ).values('kill_house_id').annotate(
        total_quantity=Sum('weight_of_carcasses')
    )

    in_province_data = kill_house_request.filter(
        killhouse_user__in=kill_houses
    ).values('killhouse_user_id').annotate(
        total_quantity=Sum('accepted_real_weight')
    )

    in_warehouse_data = kill_house_request.filter(
        killhouse_user__in=kill_houses,
        ware_house_confirmation=True
    ).values('killhouse_user_id').annotate(
        total_quantity=Sum('ware_house_accepted_real_weight')
    )

    products = RolesProducts.objects.filter(
        trash=False,
        kill_house__in=kill_houses
    ).values('kill_house_id', 'total_remain_weight')

    steward_dict = {item['kill_house_id']: item['total_quantity'] for item in steward_allocations}
    free_bar_dict = {item['kill_house_id']: item['total_quantity'] for item in free_bars}
    in_province_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_province_data}
    in_warehouse_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_warehouse_data}
    product_dict = {item['kill_house_id']: item['total_remain_weight'] for item in products}

    management_kill_house_data = []
    management_kill_house_dict = {
        'max_percent': '-',
        'max_in_province': '-',
        'min_in_province': '-',
        'max_out_province': '-',
        'min_out_province': '-',
        'max_product': '-',
    }

    # نگه داشتن مقادیر بیشترین/کمترین
    max_percent_val = -1

    max_in_province_val = -1
    min_in_province_val = float("inf")

    max_out_province_val = -1
    min_out_province_val = float("inf")

    max_product_val = -1

    for kh in kill_houses:
        kh_id = kh.id

        steward_qty = steward_dict.get(kh_id, 0) or 0
        free_bar_qty = free_bar_dict.get(kh_id, 0) or 0
        in_province_qty = in_province_dict.get(kh_id, 0) or 0
        in_warehouse_qty = in_warehouse_dict.get(kh_id, 0) or 0
        product_weight = product_dict.get(kh_id, 0) or 0

        if any([in_province_qty, in_warehouse_qty, steward_qty, free_bar_qty]):
            total = free_bar_qty + steward_qty
            percent = round(total * 100 / in_province_qty, 1) if in_province_qty else 0

            # ==== بیشترین‌ها ====
            if percent > max_percent_val:
                max_percent_val = percent
                management_kill_house_dict['max_percent'] = kh.name

            if steward_qty > max_in_province_val:
                max_in_province_val = steward_qty
                management_kill_house_dict['max_in_province'] = kh.name

            if free_bar_qty > max_out_province_val:
                max_out_province_val = free_bar_qty
                management_kill_house_dict['max_out_province'] = kh.name

            if product_weight > max_product_val:
                max_product_val = product_weight
                management_kill_house_dict['max_product'] = kh.name

            # ==== کمترین‌ها ====
            if steward_qty < min_in_province_val:
                min_in_province_val = steward_qty
                management_kill_house_dict['min_in_province'] = kh.name

            if free_bar_qty < min_out_province_val:
                min_out_province_val = free_bar_qty
                management_kill_house_dict['min_out_province'] = kh.name

            management_kill_house_data.append({
                'name': kh.name,
                'in_province_quantity': to_locale_str(in_province_qty),
                'in_ware_house_quantity': to_locale_str(in_warehouse_qty),
                'steward_allocation_quantity': to_locale_str(steward_qty),
                'kill_house_free_bar_quantity': to_locale_str(free_bar_qty),
                'all_quantity': to_locale_str(total),
                'product': to_locale_str(product_weight),
                'percent': percent
            })
    max_and_min_assigment = {
        "max_duc_name": '-',
        "max_duc_accepted_name": '-',
        "max_duc_rejected_name": '-',
        "min_duc_name": '-',
        "min_duc_accepted_name": '-',
        "min_duc_rejected_name": '-',
    }

    # نگه داشتن مقادیر بیشترین/کمترین
    max_request_count = -1
    min_request_count = float("inf")

    max_true_count = -1
    min_true_count = float("inf")

    max_rejected_count = -1
    min_rejected_count = float("inf")

    for kh in kill_houses:
        kill_house_request1 = kill_house_request.filter(
            killhouse_user=kh
        )

        bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True')
        bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count()
        bar_document_status_accepted = bar_assigment_true_count.filter(
            bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')
        ).count()
        bar_document_status_rejected = bar_assigment_true_count.exclude(
            bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')
        ).count()

        if bar_assigment_true_count.count() > 0 or bar_assigment_pending_count > 0:
            req_count = kill_house_request1.count()
            true_count = bar_assigment_true_count.count()
            rejected_count = bar_document_status_rejected

            # === بیشترین‌ها ===
            if req_count > max_request_count:
                max_request_count = req_count
                max_and_min_assigment["max_duc_name"] = kh.name

            if true_count > max_true_count:
                max_true_count = true_count
                max_and_min_assigment["max_duc_accepted_name"] = kh.name

            if rejected_count > max_rejected_count:
                max_rejected_count = rejected_count
                max_and_min_assigment["max_duc_rejected_name"] = kh.name

            # === کمترین‌ها ===
            if req_count < min_request_count:
                min_request_count = req_count
                max_and_min_assigment["min_duc_name"] = kh.name

            if true_count < min_true_count:
                min_true_count = true_count
                max_and_min_assigment["min_duc_accepted_name"] = kh.name

            if rejected_count < min_rejected_count:
                min_rejected_count = rejected_count
                max_and_min_assigment["min_duc_rejected_name"] = kh.name

            duc_kill_house_data.append({
                'name': kh.name,
                'kill_house_request1_count': req_count,
                "bar_assigment_true_count": true_count,
                "bar_assigment_pending_count": bar_assigment_pending_count,
                "bar_document_status_accepted": bar_document_status_accepted,
                "percent_bar_document_status_accepted": int(
                    (bar_document_status_accepted / true_count) * 100) if true_count > 0 else 0,
                "bar_document_status_rejected": rejected_count,
                "percent_bar_document_status_rejected": int(
                    (rejected_count / true_count) * 100) if true_count > 0 else 0,
            })

    different_bar = (aggregate_kill_house_request['total_quantity_has_quarantine'] or 0) \
                    - (aggregate_kill_house_request['total_quarantine_quantity'] or 0)
    different_bar_percent = int(different_bar / (aggregate_kill_house_request['total_quarantine_quantity'] or 0) * 100) \
        if (aggregate_kill_house_request['total_quarantine_quantity'] or 0) > 0 else 0

    result = {  # noqa

        "poultry_count": len(poultry_hatching.values_list('poultry', flat=True).distinct()),
        "chain_count": len(
            poultry_hatching.filter(Q(UnionTypeName='زنجیره') |
                                    Q(chain_company__isnull=False)).values_list('poultry', flat=True).distinct()),
        "poultry_hatching_quantity": aggregate_hatching['total_quantity'] or 0,
        "poultry_hatching_losses_vet": aggregate_hatching['total_losses_vet'] or 0,
        "poultry_hatching_losses_union": aggregate_hatching['total_losses_union'] or 0,
        "poultry_hatching_total_losses": aggregate_hatching['total_losses'] or 0,
        "poultry_hatching_killed_quantity": aggregate_hatching['killed_quantity'] or 0,
        "poultry_hatching_total_killed_weight": int(aggregate_hatching['total_killed_weight'] or 0),
        "poultry_hatching_left_over": aggregate_hatching['left_over'] or 0,
        "poultry_hatching_gt_60": len(poultry_hatching_gt_60.values_list('poultry', flat=True).distinct()),
        "poultry_hatching_gt_60_quantity": aggregate_poultry_hatching_gt_60['total_quantity'] or 0,
        "poultry_hatching_gt_60_left_over": aggregate_poultry_hatching_gt_60['left_over'] or 0,
        **max_and_min_dict,
        "kill_house_request_count": aggregate_kill_house_request['total_id'] or 0,
        "kill_house_request_quantity": aggregate_kill_house_request['total_accepted_real_quantity'] or 0,
        "kill_house_request_weight": int(aggregate_kill_house_request['total_accepted_real_weight'] or 0),
        "kill_house_request_average_weight": round(
            aggregate_kill_house_request['total_accepted_real_weight'] / aggregate_kill_house_request[
                'total_accepted_real_quantity'], 1)
        if (aggregate_kill_house_request['total_accepted_real_quantity'] or 0) > 0 else 0,
        "free_bars_count": aggregate_free_bars['id'] or 0,
        "free_bars_quantity": aggregate_free_bars['quantity'] or 0,
        "free_bars_live_weight": aggregate_free_bars['live_weight'] or 0,
        "kill_house_name": kill_house_name,
        "transaction_count": transaction_count,
        "persian_date": persian_date,
        "daily_quantity": daily_quantity,
        "persian_date_req": persian_date_req,
        "daily_quantity_req": daily_quantity_req,
        'kill_houses_data': kill_house_data,
        'kill_house_name_req': kill_house_name_req,
        'poultry_req_name_req': poultry_req_name_req,
        'top_poultry_req_stats_total_quantity': top_poultry_req_stats_total_quantity,
        'poultry_city_req_name_req': poultry_city_req_name_req,
        'out_poultry_req_name_req': out_poultry_req_name_req,
        'out_poultry_city_req_name_req': out_poultry_city_req_name_req,
        'out_poultry_province_req_name_req': out_poultry_province_req_name_req,
        'out_top_poultry_req_stats_total_quantity': out_top_poultry_req_stats_total_quantity,
        'management_kill_house_data': management_kill_house_data,
        'duc_kill_house_data': duc_kill_house_data,
        'avg_losses': int((aggregate_hatching['total_losses'] or 0) / poultry_hatching.count()),
        'avg_total_killed_weight': round(
            (aggregate_hatching['total_killed_weight'] or 0) / (aggregate_hatching['killed_quantity'] or 0), 1),
        'total_killing_ave_age': int(aggregate_hatching['total_killing_ave_age'] or 0),
        'top_total_killed_weight': top_total_killed_weight_first['total_killed_weight'] or 0,
        'total_quantity_top_inner': total_quantity_top_inner,
        'total_quantity_top_out': total_quantity_top_out,
        'bar_assigment_pending_count1': bar_assigment_pending_count1 or 0,
        'base_url': base_url_for_sms_report,
        "total_quarantine_quantity": aggregate_kill_house_request['total_quarantine_quantity'] or 0,
        "total_count_has_quarantine": aggregate_kill_house_request['total_count_has_quarantine'] or 0,
        "total_quantity_has_quarantine":
            aggregate_kill_house_request['total_quantity_has_quarantine'] or 0,
        "different": different_bar or 0,
        "total_weight_hasnt_code": aggregate_kill_house_request['total_weight_hasnt_code'] or 0,
        "total_quantity_hasnt_code": aggregate_kill_house_request['total_quantity_hasnt_code'] or 0,
        "total_id_hasnt_code": aggregate_kill_house_request['total_id_hasnt_code'] or 0,
        "total_weight_hasnt_warehouse":
            aggregate_kill_house_request['total_weight_hasnt_warehouse'] or 0,
        "total_quantity_hasnt_warehouse":
            aggregate_kill_house_request['total_quantity_hasnt_warehouse'] or 0,
        "total_id_hasnt_warehouse": aggregate_kill_house_request['total_id_hasnt_warehouse'] or 0,
        "total_weight_hasnt_assignment_state_archive":
            aggregate_kill_house_request['total_weight_hasnt_assignment_state_archive'] or 0,
        "total_quantity_hasnt_assignment_state_archive":
            aggregate_kill_house_request['total_quantity_hasnt_assignment_state_archive'] or 0,
        "total_id_hasnt_assignment_state_archive":
            aggregate_kill_house_request['total_id_hasnt_assignment_state_archive'] or 0,
        "total_weight_hasnt_killing_age":
            aggregate_kill_house_request['total_weight_hasnt_killing_age'] or 0,
        "total_quantity_hasnt_killing_age":
            aggregate_kill_house_request['total_quantity_hasnt_killing_age'] or 0,
        "total_id_hasnt_killing_age": aggregate_kill_house_request['total_id_hasnt_killing_age'] or 0,
        'different_bar_percent': different_bar_percent,
        'max_and_min_assigment': max_and_min_assigment,
        'management_kill_house_dict': management_kill_house_dict,

    }
    return Response(result)


def create_update_chicken_commission_prices_cron():
    now = datetime.datetime.now().date()
    for day in range(7):
        past_date = now - timedelta(days=day)
        past_datetime = datetime.datetime.combine(past_date, datetime.time.min)

        chicken_commission = ChickenCommissionPrices.objects.get_or_create(date__date=past_date,
                                                                           defaults={'date': past_datetime,
                                                                                     'kill_house_price': kill_house_price})[
            0]
        # # poultry_request
        poultry_request = PoultryRequest.objects.filter(trash=False, send_date__date=past_date,
                                                        state_process__in=('pending', 'accepted'),
                                                        province_state__in=('pending', 'accepted'), out=False,
                                                        amount__gt=0).only(
            'amount')
        print(len(poultry_request))
        poultry_request_amount = poultry_request.aggregate(total=Sum('amount'))[
                                     'total'] or 0
        # ProvinceKillRequest
        province_kill_req = ProvinceKillRequest.objects.filter(trash=False, kill_request__recive_date__date=past_date,
                                                               state__in=('pending', 'accepted'),
                                                               kill_house_price__gt=0).only(
            'kill_house_price')

        province_kill_req_kill_house_price = province_kill_req.aggregate(total=Sum('kill_house_price'))[
                                                 'total'] or 0

        # KillRequest
        kill_req = KillRequest.objects.filter(trash=False, recive_date__date=past_date,
                                              province_state__in=('accepted', 'pending')
                                              , poultry__isnull=False,
                                              direct_buying_state__in=('accepted', 'pending'), amount__gt=0).only(
            'amount')
        kill_req_amount = kill_req.aggregate(total=Sum('amount'))[
                              'total'] or 0

        kill_request_amount = round(
            kill_req_amount / kill_req.count()) if kill_req.count() > 0 else 0

        province_kill_request_amount = round(province_kill_req_kill_house_price / province_kill_req.count()) \
            if province_kill_req.count() > 0 else 0

        poultry_req_amount = round(poultry_request_amount / poultry_request.count()) if poultry_request.count() > 0 \
            else 0

        amount = round(
            kill_req_amount + province_kill_req_kill_house_price + poultry_request_amount)

        counts = poultry_request.count() + province_kill_req.count() + kill_req.count()

        chicken_commission.chicken_average_price = round(amount / counts) if counts > 0 else 0
        chicken_commission.kill_request_amount = kill_request_amount
        chicken_commission.province_kill_request_amount = province_kill_request_amount
        chicken_commission.poultry_request_amount = poultry_req_amount

        chicken_commission.save()


def fix_amount(request):
    my_tuple = (
        31160, 31310, 31311, 31508, 31509, 31558, 31559, 31642, 31643, 31755, 31756, 31817, 31818, 31850, 31852, 31912,
        31913, 32019, 32020)

    steward_allocations = StewardAllocation.objects.filter(id__in=my_tuple)
    for steward_allocation in steward_allocations:
        amount = steward_allocation.amount - 20000
        total_amount = amount * steward_allocation.real_weight_of_carcasses
        steward_allocation.amount = amount
        steward_allocation.total_amount = total_amount
        steward_allocation.total_amount_remain = total_amount
        steward_allocation.save()
    return HttpResponse('ok')


def fix_killing_age(request):
    poultry_request = PoultryRequest.objects.filter(trash=False, killing_age=1).only('killing_age')
    for p in poultry_request:
        p.killing_age = (p.send_date.date() - p.hatching.date.date()).days + 1
        p.save()
    return HttpResponse('ok')


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def get_bar_from_rsi_with_hatching(request):
    page = ''
    search_filter = ''
    search = request.GET.get('search')
    value = request.GET.get('value')
    if search:
        if search != 'undefined' and value.strip():
            search_filter = f'&search={search}&value={value}'
    date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
    poultry_hatching = PoultryHatching.objects.filter(
        key=request.GET['key']
    ).first()
    kill_house_request = KillHouseRequest.objects.filter(
        trash=False,
        temporary_trash=False,
        temporary_deleted=False,
        clearance_code__isnull=False, province_request__poultry_request__hatching=poultry_hatching
    ).values_list('clearance_code', flat=True).distinct()

    kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True,
                                                         hatching=poultry_hatching) \
        .values_list('quarantine_code', flat=True).distinct()

    result = list(kill_house_request) + list(kill_house_free_sale)
    if 'page' in request.GET:
        page = f'&page={request.GET["page"]}&page_size={request.GET["page_size"]}'

    response = requests.get(
        f'https://rsibackend.rasadyar.com/app/api_send_different_bar-from-hatching/?{page}'
        f'{search_filter}'
        f'&date1={date1}&date2={date2}&licence_number={poultry_hatching.licence_number}',
        json=result,
        headers={'Content-Type': 'application/json'}
    )

    return Response(response.json(), status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def driver_from_rsi_excel(request):
    response = requests.get(
        f'https://rsibackend.rasadyar.com/app/driver/?all'
    )
    kill_house = KillHouse.objects.filter(trash=False, out_province=False).values_list('unique_identifier', flat=True)

    excel_options = [
        'ردیف',
        'نام راننده',
        'نام مالک',
        'شهر',
        'رهگیری خودرو',
        'نوع ماشین',
        'پلاک',
        'محصول',
        'کد کشتارگاه',
        'نام کشتارگاه',
        'شماره موبایل راننده',

    ]

    output = BytesIO()
    workbook = Workbook()
    worksheet = workbook.active
    worksheet.sheet_view.rightToLeft = True
    worksheet.insert_rows(1)
    m = 1
    create_header_freez(worksheet, excel_options, 1, 1, 2, 20, width=30)

    l = 2
    for data in response.json():
        if data['part_id_code'] in kill_house:
            list1 = [
                m,
                data['driver_name'],
                data['owner_name'],
                data['city'],
                data['tracking_code'],
                data['car_type'],
                data['pelak'],
                data['product'],
                data['part_id_code'],
                data['kill_house_name'],

            ]
            create_value(worksheet, list1, l, 1, m=m, border_style='thin')
            m += 1
            l += 1
    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([TokenHasReadWriteScope])
@csrf_exempt
def send_again_sms_for_register_code_guild(request):
    guild = Guilds.objects.get(trash=False, key=request.data['key'])
    if guild.is_registered == False and not guild.register_date_register_code:
        number = random.randint(10000, 99000)
        guild.register_code = number
        guild.active_register_code = True
        guild.register_date_register_code = datetime.datetime.now()
        guild.save()
        send_sms_for_guild_for_register(guild)

    elif datetime.datetime.now() > (guild.register_date_register_code + timedelta(minutes=10)):
        number = random.randint(10000, 99000)
        guild.register_code = number
        guild.register_date_register_code = datetime.datetime.now()
        guild.save()
        send_sms_for_guild(guild)
    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


def delete_free_bar_info(request):
    kill_house_free_bar = KillHouseFreeBarInformation.objects.filter(trash=False, ware_house=False)
    bar_clearance_code = kill_house_free_bar.values_list('bar_clearance_code', flat=True)

    bars = requests.post('https://rsibackend.rasadyar.com/app/delete_free_bar_from_rasadyaar/', data=bar_clearance_code)
    if bars.json():
        for bar in bars.json():
            delete_kill_req = kill_house_free_bar.filter(bar_clearance_code=bar['TrackingCode']).first()
            delete_kill_req.trash = True
            delete_kill_req.save()
            product = delete_kill_req.product
            kill_house_free_buying_product_warehousing(product)


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def send_again_sms_steward_allocation(request):
    steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False)
    if steward_allocation.to_guilds:
        mobile = steward_allocation.to_guilds.user.mobile
        buyer = steward_allocation.to_guilds.guilds_name
    else:
        mobile = steward_allocation.to_steward.user.mobile
        buyer = steward_allocation.to_steward.guilds_name

    if steward_allocation.kill_house:
        seller = steward_allocation.kill_house.name
    else:
        seller = steward_allocation.guilds.guilds_name
    date = shamsi_date(steward_allocation.date)
    weight = steward_allocation.weight_of_carcasses
    amount = steward_allocation.amount
    number = str(steward_allocation.registration_code)

    if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > (
            steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \
            not steward_allocation.expire_time_ten_minute:
        steward_allocation.expire_time_ten_minute = datetime.datetime.now()
        steward_allocation.save()
        steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount)

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


@api_view(["POST"])
@permission_classes([AllowAny])
@csrf_exempt
def pos_send_again_sms_steward_allocation(request):
    steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False)
    if steward_allocation.to_guilds:
        mobile = steward_allocation.to_guilds.user.mobile
        buyer = steward_allocation.to_guilds.guilds_name
    else:
        mobile = steward_allocation.to_steward.user.mobile
        buyer = steward_allocation.to_steward.guilds_name

    if steward_allocation.kill_house:
        seller = steward_allocation.kill_house.name
    else:
        seller = steward_allocation.guilds.guilds_name
    date = shamsi_date(steward_allocation.date)
    weight = steward_allocation.weight_of_carcasses
    amount = steward_allocation.amount
    number = str(steward_allocation.registration_code)

    if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > (
            steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \
            not steward_allocation.expire_time_ten_minute:
        steward_allocation.expire_time_ten_minute = datetime.datetime.now()
        steward_allocation.save()
        steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount)

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


@api_view(["POST"])
@permission_classes([AllowAny])
@csrf_exempt
def new_pos_send_again_sms_steward_allocation(request):
    steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False)
    if steward_allocation.to_guilds:
        mobile = steward_allocation.to_guilds.user.mobile
        buyer = steward_allocation.to_guilds.guilds_name
    else:
        mobile = steward_allocation.to_stewards.user.mobile
        buyer = steward_allocation.to_stewards.name

    if steward_allocation.kill_house:
        seller = steward_allocation.kill_house.name
    else:
        seller = steward_allocation.guilds.guilds_name
    date = shamsi_date(steward_allocation.date)
    weight = steward_allocation.weight_of_carcasses
    amount = steward_allocation.amount
    number = str(steward_allocation.registration_code)

    if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > (
            steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \
            not steward_allocation.expire_time_ten_minute:
        steward_allocation.expire_time_ten_minute = datetime.datetime.now()
        steward_allocation.save()
        steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount)

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def fix_number_from_rsi(request):
    poultry = Poultry.objects.filter(trash=False).select_related('user').only('user__mobile', 'breeding_unique_id')

    result = {
        str(p.breeding_unique_id): p.user.mobile
        for p in poultry
        if p.user and p.user.mobile
    }

    response = requests.post(
        f'https://rsibackend.rasadyar.com/app/fix_number/',
        json=result,
        headers={'Content-Type': 'application/json'}
    )
    for r in response.json():
        for k, v in r.items():
            poultry = Poultry.objects.filter(breeding_unique_id=k).first()
            if poultry:
                if v is not None:
                    data = {
                        "first_mobile_number": poultry.user.mobile,
                        "second_mobile_number": v,
                    }
                    req = requests.post(
                        url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                        data=data,
                        verify=False
                    )
                    if req.status_code == 200:
                        second_mobile_number = v
                        user = User.objects.get(username=poultry.user.mobile)
                        user.username = second_mobile_number
                        user.save()
                        user_profile = SystemUserProfile.objects.filter(user=user).first()
                        user_profile.mobile = second_mobile_number
                        user_profile.save()

    return Response(response.json())


def send_credit_sahandsms_sms():
    filters = {}
    if base_url_for_sms_report == 'ha':
        filters['username'] = 'hamedan'
    elif base_url_for_sms_report == 'ku':
        filters['username'] = 'kurdistan'
    elif base_url_for_sms_report == 'ma':
        filters['username__in'] = ['markazi', 'senfmarkazi']
    managements = ManagementSendSms.objects.filter(**filters) \
        .values('username') \
        .annotate(min_id=Min('id')) \
        .values_list('min_id', flat=True)

    managements = ManagementSendSms.objects.filter(id__in=managements)

    for management in managements:
        r = requests.get(
            f"http://webservice.sahandsms.com/newsmswebservice.asmx/GetUserCredit?username={management.username}"
            f"&password={management.password}")

        url = f'https://eitaayar.ir/api/{token}/sendMessage'
        date = datetime.datetime.now().date()
        if base_url_for_sms_report == 'ma':
            province = 'مرکزی'
        elif base_url_for_sms_report == 'ha':
            province = 'همدان'
        elif base_url_for_sms_report == 'ku':
            province = 'کردستان'
        elif base_url_for_sms_report == 'bu':
            province = 'بوشهر'
        else:
            province = 'تست'
        date_shamsi = shamsi_date(date).replace('-', '_')
        base_message = '🗓📢❗ سامانه رصدیار، زنجیره تامین،تولید و توزیع مرغ گوشتی📢❗\n'
        base_message += f' #گزارش_مانده_حساب_پنل_پیامکی #{date_shamsi}\n'
        base_message += f' #استان_{province}\n\n'
        base_message += f'➖➖➖➖➖➖➖➖➖➖\n'

        messages = []
        current_message = base_message

        root = ET.fromstring(r.content)
        credit_amount = int(root.text)
        amount = "{:,}".format(credit_amount)

        new_message_part = "🔸 نام کاربری پنل : {0}  \n".format(management.username)
        new_message_part += "🔸 مانده حساب پنل : {0} ریال \n".format(amount)
        # new_message_part = "🔸 نام کاربری پنل {0}: {1} ریال \n".format(management.username, amount)
        if credit_amount < 1000000:
            new_message_part += "‼توجه: لطفا برای شارژ پنل پیامکی خود اقدام فرمایید‼"

        new_message_part += '\n➖➖➖➖➖➖➖➖➖➖\n'

        if len(current_message) + len(new_message_part) > 4000:
            messages.append(current_message)
            current_message = base_message

        current_message += new_message_part

        if current_message and current_message != base_message:
            messages.append(current_message)

        for message in messages:
            data = {
                'chat_id': chat_id_mali,
                'text': message,
            }
            response = requests.post(url, data=data, verify=False)


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def send_again_sms_steward_free_sale_bar(request):
    steward_allocation = StewardFreeSaleBarInformation.objects.get(key=request.data['key'], trash=False)

    if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() >
        (steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \
            not steward_allocation.expire_time_ten_minute:
        steward_allocation.expire_time_ten_minute = datetime.datetime.now()
        steward_allocation.save()
        send_sms_for_sale_bar_for_steward(steward_allocation)

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def send_again_sms_kill_house_free_sale_bar(request):
    steward_allocation = KillHouseFreeSaleBarInformation.objects.get(key=request.data['key'], trash=False)

    if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() >
        (steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \
            not steward_allocation.expire_time_ten_minute:
        steward_allocation.expire_time_ten_minute = datetime.datetime.now()
        steward_allocation.save()
        send_sms_for_sale_bar(steward_allocation)

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def send_again_sms_direct_buying_code(request):
    kill_request = KillRequest.objects.get(key=request.data['key'], trash=False)

    if (kill_request.expire_time_ten_minute and datetime.datetime.now() >
        (kill_request.expire_time_ten_minute + timedelta(minutes=10))) or \
            not kill_request.expire_time_ten_minute:
        kill_request.expire_time_ten_minute = datetime.datetime.now()
        kill_request.save()

        # Get required data for SMS
        from authentication.sms_management import confirm_price_poultry_request_direct_buying_sms
        from panel.helper_excel import shamsi_date

        mobile = kill_request.poultry.user.mobile
        poultry_fullname = kill_request.poultry.user.fullname
        quantity = "{:,}".format(int(kill_request.kill_capacity))
        chicken_breed = kill_request.chicken_breed
        send_date = shamsi_date(kill_request.recive_date.date())
        free_sale_in_province = kill_request.poultry_request.free_sale_in_province if kill_request.poultry_request else False
        amount = kill_request.amount
        request_kill_house = kill_request.kill_house.name
        confirm_code = kill_request.direct_buying_code

        confirm_price_poultry_request_direct_buying_sms(
            mobile,
            poultry_fullname,
            quantity,
            chicken_breed,
            send_date,
            free_sale_in_province,
            amount,
            request_kill_house,
            confirm_code
        )

    else:
        return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN)
    return Response({'result': 'باموفقیت ارسال شد.'})


def delete_sale_bar():
    steward_sale_bar = StewardFreeSaleBarInformation.objects.filter(trash=False, logged_registration_code__isnull=True,
                                                                    system_registration_code=True,
                                                                    active_expire_date_time=True,
                                                                    registration_code__isnull=False)

    for free_sale_bar in steward_sale_bar:
        free_sale_bar.trash = True
        free_sale_bar.save()
        guild_steward_free_sale_product_warehousing(free_sale_bar.product)

    kill_house_sale_bar = KillHouseFreeSaleBarInformation.objects.filter(trash=False,
                                                                         logged_registration_code__isnull=True,
                                                                         system_registration_code=True,
                                                                         active_expire_date_time=True,
                                                                         registration_code__isnull=False)

    for free_sale_bar_kill_house in kill_house_sale_bar:
        product = free_sale_bar_kill_house.product
        free_sale_bar_kill_house.trash = True
        free_sale_bar_kill_house.save()
        kill_house_free_sale_product_warehousing(product)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def delete_guilds_without_allocation(request):
    # 1. اول همه صنف‌ها رو می‌گیریم
    guilds = Guilds.objects.filter(trash=False, active=True).order_by('id')

    # 2. صنف‌هایی که توزیع دارند رو پیدا می‌کنیم
    guilds_with_allocation = StewardAllocation.objects.filter(
        trash=False
    ).values_list('to_steward_id', 'to_guilds_id')

    allocated_guild_ids = set()
    for to_steward_id, to_guilds_id in guilds_with_allocation:
        if to_steward_id:
            allocated_guild_ids.add(to_steward_id)
        if to_guilds_id:
            allocated_guild_ids.add(to_guilds_id)

    # 3. از صنف‌ها، فقط اونایی که توزیع ندارند رو می‌گیریم
    guilds_without_allocation = guilds.exclude(id__in=allocated_guild_ids)

    # 4. از صنف‌های بدون توزیع، اونایی که اصلاً دستگاه پز ندارند رو پیدا می‌کنیم
    guilds_without_pos = guilds_without_allocation.annotate(
        has_pos_machine=Count('guild_pos', filter=Q(guild_pos__trash=False))
    ).filter(has_pos_machine=0)

    deleted_count = 0

    # 5. صنف‌هایی که هم توزیع ندارند و هم دستگاه پز ندارند رو حذف می‌کنیم
    for guild in guilds_without_pos:
        guild.trash = True
        guild.save()
        deleted_count += 1

    return Response({
        'result': 'باموفقیت انجام شد.',
        'deleted_count': deleted_count,
    }, status=status.HTTP_200_OK)


def get_evacuation_detail_by_request_code(rcode):
    if not rcode:
        raise ValueError("پارامتر code الزامی است.")

    payload = {"RequestCode": rcode}
    try:
        external_response = requests.post(
            "https://rsibackend.rasadyar.com/app/get-evacuation-detail-by-request-code/",
            json=payload,
            timeout=15,
        )
        external_response.raise_for_status()
    except requests.RequestException as exc:
        raise RuntimeError("عدم امکان اتصال به سرویس تخلیه.") from exc

    try:
        return external_response.json()
    except ValueError as exc:
        raise ValueError(
            f"پاسخ نامعتبر از سرویس تخلیه: {external_response.text}"
        ) from exc


def save_mobile_numbers(request):
    mobile_numbers = [
        '09188176737',
        '09011110919',
        '09181112717',
        '09185914818',
        '09187040838',
        '09393946626',
        '09127687317',
        '09033073493',
    ]

    for number in mobile_numbers:
        SmsRecipient.objects.get_or_create(
            phone_number=number,
            defaults={'is_active': True}
        )
    return HttpResponse('ok')


def _process_auto_warehouse_steward_allocations():
    now = datetime.datetime.now()
    threshold = now - timedelta(hours=8)

    total_updated = 0

    guilds = Guilds.objects.filter(trash=False, active=True).order_by('id')
    for guild in guilds:
        allocations = StewardAllocation.objects.filter(
            trash=False,
            receiver_state__in=['accepted', 'pending'],
            create_date__lte=threshold
        ).filter(
            Q(to_steward=guild) | Q(to_guilds=guild),
            Q(warehouse=False) | Q(steward_warehouse=False)
        )

        for allocation in allocations:
            if allocation.warehouse is False:
                allocation.warehouse = True
                allocation.steward_warehouse = True
                allocation.save()

            seller_product = allocation.product

            buyer_product = None
            try:
                if allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(
                        guild=allocation.to_steward,
                        parent_product=seller_product.parent_product
                    )
                elif allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(
                        guild=allocation.to_guilds,
                        parent_product=seller_product.parent_product
                    )
            except RolesProducts.DoesNotExist:
                buyer_product = None

            if allocation.seller_type == 'KillHouse':
                if seller_product:
                    kill_house_allocations_product_warehousing(seller_product)
                if buyer_product:
                    guild_steward_allocations_product_warehousing(buyer_product)
            else:
                if seller_product:
                    guild_steward_allocations_product_warehousing(seller_product)
                if buyer_product:
                    guild_steward_allocations_product_warehousing(buyer_product)

            total_updated += 1

    return total_updated


@api_view(['POST', 'GET'])
@permission_classes([AllowAny])
def auto_warehouse_steward_allocations(request):
    updated = _process_auto_warehouse_steward_allocations()
    return Response({
        'result': 'done',
        'updated_allocations': updated
    }, status=status.HTTP_200_OK)


def auto_warehouse_steward_allocations_cron():
    try:
        _process_auto_warehouse_steward_allocations()
        return HttpResponse('ok')
    except Exception as e:
        return HttpResponse(f'error: {e}', status=500)


@api_view(["POST"])
@permission_classes([AllowAny])
@csrf_exempt
def import_poultry_science_from_excel(request):
    file_obj = request.FILES.get('file')
    if not file_obj:
        return Response({"result": "فایل ارسال نشده است."}, status=status.HTTP_400_BAD_REQUEST)

    try:
        workbook = openpyxl.load_workbook(BytesIO(file_obj.read()), data_only=True)
    except Exception:
        return Response({"result": "امکان خواندن فایل وجود ندارد."}, status=status.HTTP_400_BAD_REQUEST)

    sheet = workbook.active
    rows = list(sheet.iter_rows(values_only=True))
    if not rows:
        return Response({"result": "فایل خالی است."}, status=status.HTTP_400_BAD_REQUEST)

    expected_headers = ["ردیف", "نام", "نام خانوادگی", "شهرستان کاربر", "کد ملی", "کد نظام مهندسی", "شماره همراه"]
    header_row = [
        str(value).strip() if value is not None else ""
        for value in rows[0][:len(expected_headers)]
    ]
    if header_row != expected_headers:
        return Response(
            {
                "result": "هدر فایل با قالب مورد انتظار همخوانی ندارد.",
                "expected_headers": expected_headers,
                "received_headers": header_row
            },
            status=status.HTTP_400_BAD_REQUEST
        )

    group = Group.objects.filter(name__exact="PoultryScience").first()
    if not group:
        return Response({"result": "نقش PoultryScience تعریف نشده است."},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    latest_base_order = SystemUserProfile.objects.filter(trash=False).order_by('-base_order') \
        .values_list('base_order', flat=True).first()
    next_base_order = (latest_base_order + 1) if latest_base_order else 1000

    stats = {
        "processed_rows": 0,
        "created_profiles": 0,
        "updated_profiles": 0,
        "created_poultry_science": 0,
        "skipped_rows": 0
    }
    errors = []

    def clean_text(value):
        if value is None:
            return None
        text = str(value).strip()
        return text or None

    def clean_digits(value):
        if value is None:
            return None
        digits = re.sub(r'\D', '', str(value))
        return digits or None

    def normalize_mobile(value):
        digits = clean_digits(value)
        if not digits:
            return None
        if digits.startswith('98') and len(digits) == 12:
            digits = digits[2:]
        if len(digits) == 10:
            digits = f'0{digits}'
        if len(digits) == 11 and not digits.startswith('0'):
            digits = f'0{digits[1:]}'
        return digits if check_mobile_number(digits) else None

    def find_city(name):
        if not name:
            return None
        return City.objects.filter(
            trash=False
        ).filter(
            Q(name__iexact=name) | Q(city_name__iexact=name)
        ).select_related('province').first()

    for row_index, row in enumerate(rows[1:], start=2):
        if not row or not any(row):
            continue

        stats["processed_rows"] += 1
        first_name = clean_text(row[1])
        last_name = clean_text(row[2])
        city_name = clean_text(row[3])
        national_code = clean_digits(row[4])
        engineering_code = clean_digits(row[5])
        mobile = normalize_mobile(row[6])

        if not mobile:
            stats["skipped_rows"] += 1
            errors.append({"row": row_index, "reason": "شماره همراه نامعتبر است."})
            continue

        city = find_city(city_name)
        if not city:
            stats["skipped_rows"] += 1
            errors.append({"row": row_index, "reason": "شهرستان یافت نشد.", "city": city_name})
            continue

        system_profile = SystemUserProfile.objects.filter(trash=False, mobile=mobile).last()

        if not system_profile:
            password = '2025'
            register_payload = {
                "username": mobile,
                "first_name": first_name or "",
                "last_name": last_name or "",
                "password": password,
                "national_code": national_code or '0',
                "role": "PoultryScience",
                "api_key": PROJECT_API_KEY
            }
            try:
                arta_response = requests.post(
                    url=ARTA_REGISTER,
                    data=register_payload,
                    verify=False,
                    timeout=20
                )
            except requests.RequestException as exc:
                stats["skipped_rows"] += 1
                errors.append({"row": row_index, "reason": f"خطا در ثبت در آرتا: {exc}"})
                continue

            if arta_response.status_code not in (200, 201):
                stats["skipped_rows"] += 1
                errors.append(
                    {"row": row_index, "reason": f"ثبت کاربر در آرتا انجام نشد ({arta_response.status_code})."})
                continue

            hashed_password = hashlib.sha256(password.encode()).hexdigest()
            user, _ = User.objects.get_or_create(
                username=mobile,
                defaults={
                    "first_name": first_name or "",
                    "last_name": last_name or "",
                    "password": hashed_password
                }
            )
            if first_name and user.first_name != first_name:
                user.first_name = first_name
            if last_name and user.last_name != last_name:
                user.last_name = last_name
            user.save()

            fullname = f"{first_name or ''} {last_name or ''}".strip() or None
            system_profile = SystemUserProfile.objects.create(
                mobile=mobile,
                first_name=first_name,
                last_name=last_name,
                fullname=fullname,
                user=user,
                base_order=next_base_order,
                password=password,
                national_code=national_code,
                city=city,
                province=city.province,
                city_name=city.name,
                province_name=city.province.name if city.province else None,
                city_number=city.city_number,
                province_number=city.province.province_number if city.province else None
            )
            next_base_order += 1
            stats["created_profiles"] += 1
        else:
            updated = False
            if first_name and system_profile.first_name != first_name:
                system_profile.first_name = first_name
                updated = True
            if last_name and system_profile.last_name != last_name:
                system_profile.last_name = last_name
                updated = True
            if national_code and system_profile.national_code != national_code:
                system_profile.national_code = national_code
                updated = True
            if engineering_code and system_profile.system_code != engineering_code:
                system_profile.system_code = engineering_code
                updated = True
            if system_profile.city_id != city.id:
                system_profile.city = city
                system_profile.city_name = city.name
                system_profile.city_number = city.city_number
                updated = True
            if system_profile.province_id != (city.province.id if city.province else None):
                system_profile.province = city.province
                system_profile.province_name = city.province.name if city.province else None
                system_profile.province_number = city.province.province_number if city.province else None
                updated = True

            fullname = f"{system_profile.first_name or ''} {system_profile.last_name or ''}".strip()
            if fullname and system_profile.fullname != fullname:
                system_profile.fullname = fullname
                updated = True

            if not system_profile.user:
                hashed_password = hashlib.sha256('123456'.encode()).hexdigest()
                user, _ = User.objects.get_or_create(
                    username=mobile,
                    defaults={
                        "first_name": first_name or system_profile.first_name or "",
                        "last_name": last_name or system_profile.last_name or "",
                        "password": hashed_password
                    }
                )
                system_profile.user = user
                updated = True
            else:
                user = system_profile.user
                if first_name and user.first_name != first_name:
                    user.first_name = first_name
                    user.save(update_fields=["first_name"])
                if last_name and user.last_name != last_name:
                    user.last_name = last_name
                    user.save(update_fields=["last_name"])

            if updated:
                system_profile.save()
                stats["updated_profiles"] += 1

        if not system_profile.role.filter(id=group.id).exists():
            system_profile.role.add(group)

        poultry_science = PoultryScience.objects.filter(trash=False, user=system_profile).first()
        if not poultry_science:
            PoultryScience.objects.create(user=system_profile, engineering_code=engineering_code)
            stats["created_poultry_science"] += 1
        else:
            updated_fields = []
            if engineering_code and poultry_science.engineering_code != engineering_code:
                poultry_science.engineering_code = engineering_code
                updated_fields.append("engineering_code")
            if updated_fields:
                poultry_science.save(update_fields=updated_fields)

    return Response(
        {
            "result": "done",
            "summary": stats,
            "errors": errors
        },
        status=status.HTTP_200_OK
    )


@api_view(["GET"])
@permission_classes([AllowAny])
def sync_guilds_user_profile_from_inquiry(request):
    """
    برگرداندن لیست صنف‌هایی که:
      - برای کاربرشان کد ملی ثبت شده است (user__national_id خالی/NULL نیست)
      - هنوز استعلام نشده‌اند (has_inquiry = False)

    علاوه بر لیست، برای هر صنف استعلام «شخص» و «صنف» انجام می‌شود
    و فقط اطلاعات کاربر (SystemUserProfile) به‌روزرسانی می‌شود.
    در صورت موفقیت، روی خود صنف فقط has_inquiry=True ست می‌شود.
    """
    queryset = Guilds.objects.filter(
        trash=False,
        user__national_id__isnull=False,
        steward=True
    ).exclude(user__national_id__exact="")

    failed_records = []
    updated_ids = []

    # کش شهرها برای بهبود کارایی جستجوی شهر
    all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name'))

    def _normalize_fa_ar(text):
        if not text:
            return text
        mapping = {
            'ك': 'ک',
            'ي': 'ی',
            'ى': 'ی',
            '\u0649': 'ی',
            '\u06CC': 'ی',
            '\u064A': 'ی',
            'ۀ': 'ه',
            'ة': 'ه',
            'ؤ': 'و',
            'أ': 'ا',
            'إ': 'ا',
            'ٱ': 'ا',
            '\u200c': ' ',
        }
        out = str(text)
        for src, dst in mapping.items():
            out = out.replace(src, dst)
        return out.strip()

    def parse_yes_no(val):
        if not val:
            return False
        return str(val).strip() == 'بله'

    for guild in queryset:
        national_id = getattr(getattr(guild, "user", None), "national_id", None)
        if not national_id:
            failed_records.append(
                {"guild_id": guild.id, "reason": "کد ملی برای کاربر این صنف ثبت نشده است"}
            )
            continue

        try:
            # دریافت اطلاعات شخص
            try:
                person_response = requests.get(
                    f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person"
                )
                person_data = person_response.json()
                if not person_data.get('status'):
                    failed_records.append(
                        {"guild_id": guild.id, "national_id": national_id, "reason": "اطلاعات شخص یافت نشد"}
                    )
                    continue
                person_info = person_data.get('data', {})
            except Exception as e:
                failed_records.append(
                    {
                        "guild_id": guild.id,
                        "national_id": national_id,
                        "reason": f"خطا در دریافت اطلاعات شخصی: {str(e)}",
                    }
                )
                continue

            # دریافت اطلاعات صنفی
            try:
                guild_response = requests.get(
                    f"https://pay.rasadyar.net/national-documents?info={national_id}&type=guild"
                )
                guild_data = guild_response.json()
                if not guild_data.get('status') or not guild_data.get('data'):
                    failed_records.append(
                        {"guild_id": guild.id, "national_id": national_id, "reason": "اطلاعات صنفی یافت نشد"}
                    )
                    continue

                guild_list = guild_data.get('data', [])
                guild_info = None

                for g in guild_list:
                    license_status_value = g.get('licenseStatus', '')
                    if license_status_value and 'فعال' in license_status_value:
                        guild_info = g
                        break

                if not guild_info:
                    failed_records.append(
                        {
                            "guild_id": guild.id,
                            "national_id": national_id,
                            "reason": "هیچ پروانه کسب فعالی برای این کد ملی یافت نشد (تمام پروانه‌ها ابطال شده‌اند)",
                        }
                    )
                    continue

                guild_layer_two = guild_info.get('layerTwo', {})
            except Exception as e:
                failed_records.append(
                    {
                        "guild_id": guild.id,
                        "national_id": national_id,
                        "reason": f"خطا در دریافت اطلاعات صنفی: {str(e)}",
                    }
                )
                continue

            # مقادیر مورد نیاز برای به‌روزرسانی
            first_name = person_info.get('firstName')
            last_name = person_info.get('lastName')
            father_name = person_info.get('fatherName')
            gender = person_info.get('gender')
            identity_no = person_info.get('identityNo')
            is_alive = person_info.get('isLive', True)
            birth_date = person_info.get('birthDate')

            try:
                jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date()
                birthday_str = jalali_date.strftime("%Y-%m-%d")
            except Exception:
                birthday_str = None

            city_name = guild_info.get('city')
            mobile_from_guild = guild_layer_two.get('mobilenumber')

            has_partner = parse_yes_no(guild_layer_two.get('hasPartner'))
            is_foreign_national = parse_yes_no(guild_layer_two.get('isForeigner'))

            # پیدا کردن شهر (همان منطق قبلی)
            city = City.objects.filter(name__icontains=city_name, trash=False).first()
            if not city:
                normalized_city = _normalize_fa_ar(city_name)
                city = City.objects.filter(name__icontains=normalized_city, trash=False).first()
            if not city:
                alt_city = str(city_name or '')
                alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي')
                city = City.objects.filter(name__icontains=alt_city, trash=False).first()
            if not city:
                try:
                    target = _normalize_fa_ar(city_name or '')
                    best_id = None
                    best_ratio = 0.0
                    for c in all_cities_cache:
                        cand = _normalize_fa_ar(c.get('name', '') or '')
                        ratio = difflib.SequenceMatcher(None, target, cand).ratio()
                        if ratio > best_ratio:
                            best_ratio = ratio
                            best_id = c['id']
                    if best_id is not None and best_ratio >= 0.72:
                        city = City.objects.filter(id=best_id, trash=False).first()
                except Exception:
                    city = None

            # به‌روزرسانی اطلاعات کاربر و فلگ استعلام صنف (بدون دست‌زدن به سایر فیلدهای صنف)
            try:
                user_profile = guild.user
                if user_profile:
                    # اگر شماره موبایل در استعلام صنفی وجود دارد و با موبایل فعلی فرق می‌کند
                    if mobile_from_guild and mobile_from_guild != user_profile.mobile:
                        first_mobile_number = user_profile.mobile
                        second_mobile_number = mobile_from_guild

                        # شماره جدید قبلا برای شخص دیگری ثبت نشده باشد
                        if SystemUserProfile.objects.filter(mobile=second_mobile_number) \
                                .exclude(id=user_profile.id).exists():
                            failed_records.append(
                                {
                                    "guild_id": guild.id,
                                    "national_id": national_id,
                                    "reason": "این شماره در سامانه به نام شخص دیگری است",
                                }
                            )
                            continue

                        data = {
                            "first_mobile_number": first_mobile_number,
                            "second_mobile_number": second_mobile_number,
                        }
                        req = requests.post(
                            url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                            data=data,
                            verify=False
                        )
                        if req.status_code == 200:
                            user = User.objects.get(id=user_profile.user.id)
                            user.username = second_mobile_number
                            user.save()
                            user_profile.mobile = second_mobile_number
                        else:
                            failed_records.append(
                                {
                                    "guild_id": guild.id,
                                    "national_id": national_id,
                                    "reason": "در تغییر شماره موبایل در آرتا مشکلی به‌وجود آمده است",
                                }
                            )
                            continue

                    user_profile.national_id = national_id
                    user_profile.national_code = identity_no
                    user_profile.first_name = first_name
                    user_profile.last_name = last_name
                    user_profile.fullname = f"{first_name} {last_name}".strip()
                    user_profile.father_name = father_name
                    user_profile.gender = gender
                    if birthday_str:
                        user_profile.birthday = birthday_str
                    user_profile.is_alive = is_alive
                    if city:
                        user_profile.city = city
                        user_profile.province = city.province
                    user_profile.save()

                guild.has_inquiry = True
                guild.save(update_fields=["has_inquiry"])
                updated_ids.append(guild.id)
            except Exception as e:
                failed_records.append(
                    {"guild_id": guild.id, "national_id": national_id, "reason": f"خطا در آپدیت صنف/کاربر: {str(e)}"}
                )
                continue

        except Exception as e:
            failed_records.append(
                {"guild_id": guild.id, "national_id": national_id, "reason": f"خطای کلی: {str(e)}"}
            )
            continue

    updated_guilds = Guilds.objects.filter(id__in=updated_ids)
    serializer = GuildsSerializer(updated_guilds, many=True)

    return Response(
        {
            "result": "پردازش کامل شد",
            "updated_count": len(updated_ids),
            "failed_count": len(failed_records),
            "failed_records": failed_records,
            "guilds": serializer.data,
        },
        status=status.HTTP_200_OK,
    )


@api_view(["GET"])
@permission_classes([AllowAny])
def report_guilds_without_national_or_pos_transactions(request):
    """
    برگرداندن لیست صنف‌هایی که:
      - کاربرشان کد ملی ندارد (national_id خالی/NULL است)
      - یا هیچ تراکنش فعالی در جدول PosMachineTransactions برای آن‌ها ثبت نشده است
    """
    # ۱) ابتدا برای همه صنف‌ها has_inquiry را False می‌کنیم
    Guilds.objects.filter(trash=False).update(has_inquiry=False)

    # ۲) فقط صنف‌های فعال و غیرحذف‌شده را برای بررسی انتخاب می‌کنیم
    queryset = Guilds.objects.filter(trash=False, active=True)

    result_guilds = []
    missing_national_id_count = 0
    missing_pos_txn_count = 0
    deactivated_count = 0

    for guild in queryset:
        national_id = getattr(getattr(guild, "user", None), "national_id", None)
        has_national_id = bool(national_id)

        transactions = PosMachineTransactions.objects.filter(
            trash=False,
            pos__guild=guild,
            paid=True
        ).order_by('-date')
        has_pos_transactions = transactions.exists()

        # صنف‌هایی که یا کد ملی ندارند یا هیچ تراکنش فعالی ندارند
        if (not has_national_id) or (not has_pos_transactions):
            result_guilds.append(guild)
            if not has_national_id:
                missing_national_id_count += 1
            if not has_pos_transactions:
                missing_pos_txn_count += 1

            # صنف‌هایی که نه کد ملی دارند و نه تراکنش => غیرفعال می‌شوند
            if (not has_national_id) and (not has_pos_transactions) and guild.active:
                guild.active = False
                guild.save(update_fields=["active"])
                deactivated_count += 1

    total = len(result_guilds)
    serializer = GuildsSerializer(result_guilds, many=True)

    return Response(
        {
            "result": "ok",
            "total": total,
            "missing_national_id_count": missing_national_id_count,
            "missing_pos_transactions_count": missing_pos_txn_count,
            "deactivated_count": deactivated_count,
            "guilds": serializer.data,
        },
        status=status.HTTP_200_OK,
    )


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
def get_guilds_for_update_or_create(request):
    national_code = request.GET['national_code']
    role = request.GET.get('role')
    update_flag = request.GET.get('update', '').lower() == 'true'
    users = SystemUserProfile.objects.filter(trash=False, national_id=national_code, active=True).order_by('id')
    _guilds = Guilds.objects.filter(
        trash=False,
        user__national_id=national_code,
        active=True
    ).order_by('id')
    api_data = {"dbRegister": False}
    if (not users.exists() or not _guilds.exists()) or update_flag:
        try:
            person_response = requests.get(
                f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person"
            )
            person_data = person_response.json()
            person_info = person_data.get('data', {})
            api_data['user'] = person_info
        except Exception as e:
            return Response({"result": f"خطا در دریافت اطلاعات شخصی: {str(e)}"},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        try:
            guild_response = requests.get(
                f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild"
            )
            guild_data = guild_response.json()
            if (not guild_data.get('status') or not guild_data.get('data')) and role == 'AdminX':
                return Response(api_data, status=status.HTTP_200_OK)
            if (not guild_data.get('status') or not guild_data.get('data')) and role != 'AdminX':
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            guild_list = guild_data.get('data', [])

            if not guild_list or len(guild_list) == 0:
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            has_valid_guild = False
            for guild in guild_list:
                layer_two = guild.get('layerTwo', {})
                if layer_two and layer_two.get('licenseIssueDate'):
                    has_valid_guild = True
                    break

            if not has_valid_guild:
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            guild_info = None
            active_guilds = []
            inactive_guilds = []

            for guild in guild_list:
                layer_two = guild.get('layerTwo', {})
                license_status_value = layer_two.get('licenseStatus', '') if layer_two else ''
                if license_status_value and 'فعال' in license_status_value:
                    active_guilds.append(guild)
                else:
                    inactive_guilds.append(guild)

            if not active_guilds and inactive_guilds:
                def parse_persian_date(date_str):
                    if not date_str:
                        return None
                    try:
                        date_str = date_str.strip()
                        parts = date_str.split('/')
                        if len(parts) == 3:
                            year = int(parts[0])
                            month = int(parts[1])
                            day = int(parts[2])
                            return jdatetime.date(year, month, day)
                    except:
                        pass
                    return None

                latest_guild = None
                latest_date = None

                for guild in inactive_guilds:
                    layer_two = guild.get('layerTwo', {})
                    license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else ''
                    parsed_date = parse_persian_date(license_issue_date)
                    if parsed_date:
                        if latest_date is None or parsed_date > latest_date:
                            latest_date = parsed_date
                            latest_guild = guild

                if latest_guild:
                    guild_info = latest_guild

            if not guild_info and guild_list:
                guild_info = guild_list[0]

            if active_guilds:
                api_data['guild'] = active_guilds
            elif guild_info:
                api_data['guild'] = guild_info
        except Exception as e:
            if 'active_guilds' in locals() and active_guilds:
                api_data['guild'] = active_guilds
            elif 'guild_info' in locals() and guild_info:
                api_data['guild'] = guild_info
            elif 'guild_list' in locals() and guild_list:
                api_data['guild'] = guild_list[0]

    if users.count() > 1:
        users_with_valid_guilds = []

        for user in users:
            guilds = Guilds.objects.filter(trash=False, user=user, active=True)

            if guilds.exists():
                has_steward_guild = guilds.filter(steward=True).exists()

                has_allocation = False
                if not has_steward_guild:
                    for guild in guilds:
                        latest_allocation = StewardAllocation.objects.filter(
                            Q(to_steward=guild) | Q(to_guilds=guild),
                            trash=False
                        ).order_by('-date').first()
                        if latest_allocation:
                            has_allocation = True
                            break

                if has_steward_guild or has_allocation:
                    users_with_valid_guilds.append(user)

        if users_with_valid_guilds:
            if len(users_with_valid_guilds) > 1:
                valid_user_ids = [u.id for u in users_with_valid_guilds]
                latest_user = SystemUserProfile.objects.filter(id__in=valid_user_ids).order_by('-id').first()
                if latest_user:
                    users_with_valid_guilds = [latest_user]
                else:
                    users_with_valid_guilds = users_with_valid_guilds[:1]

            valid_user_ids = [u.id for u in users_with_valid_guilds]
            guilds = Guilds.objects.filter(trash=False, user__in=users, active=True).exclude(
                user__id__in=valid_user_ids).update(active=False)
            users.exclude(id__in=valid_user_ids).update(active=False, national_id=0)
            users = SystemUserProfile.objects.filter(id__in=valid_user_ids, trash=False, active=True)

        else:
            latest_user = users.order_by('-id').first()
            users.exclude(id=latest_user.id).update(active=False, national_id=0)
            users = SystemUserProfile.objects.filter(id=latest_user.id, trash=False, active=True)

    for user in users:
        guilds = Guilds.objects.filter(trash=False, user=user, active=True)

        if guilds.count() > 1:
            guilds_to_keep_active = set()

            steward_guilds = guilds.filter(steward=True)
            guilds_to_keep_active.update(steward_guilds.values_list('id', flat=True))

            guilds_with_allocation_info = []
            for guild in guilds:
                latest_allocation = StewardAllocation.objects.filter(
                    Q(to_steward=guild) | Q(to_guilds=guild),
                    trash=False
                ).order_by('-date').first()

                if latest_allocation:
                    allocation_date = latest_allocation.date if latest_allocation.date else latest_allocation.created_at
                    guilds_with_allocation_info.append({
                        'guild_id': guild.id,
                        'allocation_date': allocation_date,
                        'allocation': latest_allocation
                    })

            if guilds_with_allocation_info:
                valid_allocation_info = [item for item in guilds_with_allocation_info if item['allocation_date']]
                if valid_allocation_info:
                    max_date = max(item['allocation_date'] for item in valid_allocation_info)
                    for item in valid_allocation_info:
                        if item['allocation_date'] == max_date:
                            guilds_to_keep_active.add(item['guild_id'])

            if not guilds_to_keep_active:
                latest_guild = guilds.order_by('-created_at', '-updated_at').first()
                if latest_guild:
                    guilds_to_keep_active.add(latest_guild.id)

            guilds.exclude(id__in=guilds_to_keep_active).update(active=False)

    if api_data and any(key != 'dbRegister' for key in api_data.keys()):
        return Response(api_data, status=status.HTTP_200_OK)
    final_guilds = Guilds.objects.filter(
        trash=False,
        user__national_id=national_code,
        active=True
    )

    serializer = GuildsSerializer(final_guilds.first())
    return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
def get_guilds_for_update_or_create_new(request):
    national_code = request.GET['national_code']
    role = request.GET.get('role')
    update_flag = request.GET.get('update', '').lower() == 'true'
    users = SystemUserProfile.objects.filter(trash=False, national_id=national_code, active=True).order_by('id')
    _guilds = Guilds.objects.filter(
        trash=False,
        user__national_id=national_code,
        active=True
    ).order_by('id')
    api_data = {"dbRegister": False}
    if (not users.exists() or not _guilds.exists()) or update_flag:
        try:
            person_response = requests.get(
                f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person"
            )
            person_data = person_response.json()
            person_info = person_data.get('data', {})
            api_data['user'] = person_info
        except Exception as e:
            return Response({"result": f"خطا در دریافت اطلاعات شخصی: {str(e)}"},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        try:
            guild_response = requests.get(
                f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild"
            )
            guild_data = guild_response.json()
            if (not guild_data.get('status') or not guild_data.get('data')) and role == 'AdminX':
                return Response(api_data, status=status.HTTP_200_OK)
            if (not guild_data.get('status') or not guild_data.get('data')) and role != 'AdminX':
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            guild_list = guild_data.get('data', [])

            if not guild_list or len(guild_list) == 0:
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            has_valid_guild = False
            for guild in guild_list:
                layer_two = guild.get('layerTwo', {})
                if layer_two and layer_two.get('licenseIssueDate'):
                    has_valid_guild = True
                    break

            if not has_valid_guild:
                return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."},
                                status=status.HTTP_403_FORBIDDEN)

            guild_info = None
            active_guilds = []
            inactive_guilds = []

            for guild in guild_list:
                layer_two = guild.get('layerTwo', {})
                license_status_value = layer_two.get('licenseStatus', '') if layer_two else ''
                if license_status_value and 'فعال' in license_status_value:
                    active_guilds.append(guild)
                else:
                    inactive_guilds.append(guild)

            if not active_guilds and inactive_guilds:
                def parse_persian_date(date_str):
                    if not date_str:
                        return None
                    try:
                        date_str = date_str.strip()
                        parts = date_str.split('/')
                        if len(parts) == 3:
                            year = int(parts[0])
                            month = int(parts[1])
                            day = int(parts[2])
                            return jdatetime.date(year, month, day)
                    except:
                        pass
                    return None

                latest_guild = None
                latest_date = None

                for guild in inactive_guilds:
                    layer_two = guild.get('layerTwo', {})
                    license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else ''
                    parsed_date = parse_persian_date(license_issue_date)
                    if parsed_date:
                        if latest_date is None or parsed_date > latest_date:
                            latest_date = parsed_date
                            latest_guild = guild

                if latest_guild:
                    guild_info = latest_guild

            if not guild_info and guild_list:
                guild_info = guild_list[0]

            if active_guilds:
                api_data['guild'] = active_guilds
            elif guild_info:
                api_data['guild'] = guild_info
        except Exception as e:
            if 'active_guilds' in locals() and active_guilds:
                api_data['guild'] = active_guilds
            elif 'guild_info' in locals() and guild_info:
                api_data['guild'] = guild_info
            elif 'guild_list' in locals() and guild_list:
                api_data['guild'] = guild_list[0]

    if users.count() > 1:
        users_with_valid_guilds = []

        for user in users:
            guilds = Guilds.objects.filter(trash=False, user=user, active=True)

            if guilds.exists():
                has_steward_guild = guilds.filter(steward=True).exists()

                has_allocation = False
                if not has_steward_guild:
                    for guild in guilds:
                        latest_allocation = StewardAllocation.objects.filter(
                            Q(to_steward=guild) | Q(to_guilds=guild),
                            trash=False
                        ).order_by('-date').first()
                        if latest_allocation:
                            has_allocation = True
                            break

                if has_steward_guild or has_allocation:
                    users_with_valid_guilds.append(user)

        if users_with_valid_guilds:
            if len(users_with_valid_guilds) > 1:
                valid_user_ids = [u.id for u in users_with_valid_guilds]
                latest_user = SystemUserProfile.objects.filter(id__in=valid_user_ids).order_by('-id').first()
                if latest_user:
                    users_with_valid_guilds = [latest_user]
                else:
                    users_with_valid_guilds = users_with_valid_guilds[:1]

            valid_user_ids = [u.id for u in users_with_valid_guilds]
            guilds = Guilds.objects.filter(trash=False, user__in=users, active=True).exclude(
                user__id__in=valid_user_ids).update(active=False)
            users.exclude(id__in=valid_user_ids).update(active=False, national_id=0)
            users = SystemUserProfile.objects.filter(id__in=valid_user_ids, trash=False, active=True)

        else:
            latest_user = users.order_by('-id').first()
            users.exclude(id=latest_user.id).update(active=False, national_id=0)
            users = SystemUserProfile.objects.filter(id=latest_user.id, trash=False, active=True)

    for user in users:
        guilds = Guilds.objects.filter(trash=False, user=user, active=True)

        if guilds.count() > 1:
            guilds_to_keep_active = set()

            steward_guilds = guilds.filter(steward=True)
            guilds_to_keep_active.update(steward_guilds.values_list('id', flat=True))

            guilds_with_allocation_info = []
            for guild in guilds:
                latest_allocation = StewardAllocation.objects.filter(
                    Q(to_steward=guild) | Q(to_guilds=guild),
                    trash=False
                ).order_by('-date').first()

                if latest_allocation:
                    allocation_date = latest_allocation.date if latest_allocation.date else latest_allocation.created_at
                    guilds_with_allocation_info.append({
                        'guild_id': guild.id,
                        'allocation_date': allocation_date,
                        'allocation': latest_allocation
                    })

            if guilds_with_allocation_info:
                valid_allocation_info = [item for item in guilds_with_allocation_info if item['allocation_date']]
                if valid_allocation_info:
                    max_date = max(item['allocation_date'] for item in valid_allocation_info)
                    for item in valid_allocation_info:
                        if item['allocation_date'] == max_date:
                            guilds_to_keep_active.add(item['guild_id'])

            if not guilds_to_keep_active:
                latest_guild = guilds.order_by('-created_at', '-updated_at').first()
                if latest_guild:
                    guilds_to_keep_active.add(latest_guild.id)

            guilds.exclude(id__in=guilds_to_keep_active).update(active=False)

    if api_data and any(key != 'dbRegister' for key in api_data.keys()):
        return Response(api_data, status=status.HTTP_200_OK)
    final_guilds = Guilds.objects.filter(
        trash=False,
        user__national_id=national_code,
        active=True
    )

    serializer = GuildsSerializer(final_guilds.first())
    return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
def get_legal_person_unit_info(request):
    national_code = request.GET.get('national_code')

    if not national_code:
        return Response({"result": "کد ملی الزامی است"}, status=status.HTTP_400_BAD_REQUEST)

    existing_user = SystemUserProfile.objects.filter(
        trash=False,
        national_id=national_code,
        active=True
    ).first()

    if existing_user:
        return Response({
            "result": "کاربر در سیستم وجود دارد!"
        }, status=status.HTTP_403_FORBIDDEN)

    try:
        unit_response = requests.get(
            f"https://pay.rasadyar.net/national-documents?info={national_code}&type=unit"
        )
        unit_data = unit_response.json()

        if not unit_data.get('status') or not unit_data.get('data'):
            return Response({"result": "اطلاعات واحد صنفی یافت نشد"}, status=status.HTTP_403_FORBIDDEN)

        unit_info = unit_data.get('data', {})
        unit_name = unit_info.get('name', '')
        unit_national_code = unit_info.get('nationalCode', '')
        unit_address = unit_info.get('address', '')
        city_name = None
        province_name = None

        if unit_address:
            address_parts = unit_address.split()
            if 'استان' in address_parts:
                province_idx = address_parts.index('استان')
                if province_idx + 1 < len(address_parts):
                    province_parts = []
                    for i in range(province_idx + 1, len(address_parts)):
                        if address_parts[i] in ['شهرستان', 'شهر', 'بخش']:
                            break
                        province_parts.append(address_parts[i])
                    if province_parts:
                        province_name = ' '.join(province_parts)

            if 'شهرستان' in address_parts:
                city_idx = address_parts.index('شهرستان')
                if city_idx + 1 < len(address_parts):
                    city_parts = []
                    for i in range(city_idx + 1, len(address_parts)):
                        if address_parts[i] in ['بخش', 'شهر']:
                            break
                        city_parts.append(address_parts[i])
                    if city_parts:
                        city_name = ' '.join(city_parts)

            if not city_name and 'شهر' in address_parts:
                city_idx = address_parts.index('شهر')
                if city_idx + 1 < len(address_parts):
                    city_parts = []
                    for i in range(city_idx + 1, len(address_parts)):
                        if address_parts[i] in ['بخش', 'کوچه', 'خیابان', 'پلاک']:
                            break
                        city_parts.append(address_parts[i])
                    if city_parts:
                        city_name = ' '.join(city_parts)

        first_name = unit_name.split(' ')[0]
        last_name = unit_name.split(' ')[1]
        result_data = {
            "is_real_person": False,
            "first_name": first_name or "",
            "last_name": last_name or "",
            "national_id": unit_national_code,
            "province": province_name or "",
            "address": unit_address,
            "unit_name": unit_name,

        }

        return Response(result_data, status=status.HTTP_200_OK)

    except requests.RequestException as e:
        return Response({"result": f"خطا در ارتباط با API: {str(e)}"},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    except Exception as e:
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f"خطا در پردازش اطلاعات واحد صنفی: {str(e)}")
        return Response({"result": f"خطا در پردازش اطلاعات: {str(e)}"},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(["GET"])
@permission_classes([AllowAny])
def update_all_active_guilds_from_api(request):
    """
    دریافت تمام guild های فعال و آپدیت آن‌ها از API
    """
    import logging
    logger = logging.getLogger(__name__)

    # دریافت تمام guild های فعال
    active_guilds = Guilds.objects.filter(trash=False, active=True)

    success_count = 0
    failed_count = 0
    skipped_count = 0
    failed_records = []

    def _normalize_fa_ar(text):
        """نرمالایز کردن متن فارسی/عربی"""
        if not text:
            return text
        mapping = {
            'ك': 'ک',
            'ي': 'ی',
            'ى': 'ی',
            '\u0649': 'ی',
            '\u06CC': 'ی',
            '\u064A': 'ی',
            'ۀ': 'ه',
            'ة': 'ه',
            'ؤ': 'و',
            'أ': 'ا',
            'إ': 'ا',
            'ٱ': 'ا',
            '\u200c': ' ',
        }
        out = str(text)
        for src, dst in mapping.items():
            out = out.replace(src, dst)
        return out.strip()

    def parse_yes_no(val):
        """تبدیل مقدار به boolean"""
        if isinstance(val, bool):
            return val
        if isinstance(val, str):
            return False if val == 'خیر' else True
        return bool(val)

    def persian_date_to_datetime(persian_date_str):
        """تبدیل تاریخ فارسی به datetime"""
        if not persian_date_str:
            return None
        try:
            persian_numbers = '۰۱۲۳۴۵۶۷۸۹'
            english_numbers = '0123456789'
            translation_table = str.maketrans(persian_numbers, english_numbers)
            english_date = persian_date_str.translate(translation_table)
            parts = english_date.split('/')
            if len(parts) != 3:
                return None
            year = int(parts[0])
            month = int(parts[1])
            day = int(parts[2])
            return convert_to_miladi(year=year, month=month, day=day)
        except:
            return None

    all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name'))

    for guild in active_guilds:
        try:
            # دریافت کد ملی کاربر
            user = guild.user
            if not user or not user.national_id:
                skipped_count += 1
                continue

            national_code = user.national_id

            # دریافت اطلاعات شخصی از API
            try:
                person_response = requests.get(
                    f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person"
                )
                person_data = person_response.json()
                if not person_data.get('status') or not person_data.get('data'):
                    failed_count += 1
                    failed_records.append({
                        'guild_id': guild.id,
                        'national_id': national_code,
                        'error': 'اطلاعات شخصی یافت نشد'
                    })
                    continue
                person_info = person_data.get('data', {})
            except Exception as e:
                failed_count += 1
                failed_records.append({
                    'guild_id': guild.id,
                    'national_id': national_code,
                    'error': f'خطا در دریافت اطلاعات شخصی: {str(e)}'
                })
                continue

            # دریافت اطلاعات صنفی از API
            try:
                guild_response = requests.get(
                    f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild"
                )
                guild_data = guild_response.json()
                if not guild_data.get('status') or not guild_data.get('data'):
                    failed_count += 1
                    failed_records.append({
                        'guild_id': guild.id,
                        'national_id': national_code,
                        'error': 'اطلاعات صنفی یافت نشد'
                    })
                    continue

                guild_list = guild_data.get('data', [])
                if not guild_list or len(guild_list) == 0:
                    failed_count += 1
                    failed_records.append({
                        'guild_id': guild.id,
                        'national_id': national_code,
                        'error': 'لیست صنف‌ها خالی است'
                    })
                    continue

                # انتخاب guild مناسب (فعال یا جدیدترین)
                guild_info = None
                active_guilds_list = []
                inactive_guilds_list = []

                for g in guild_list:
                    layer_two = g.get('layerTwo', {})
                    license_status_value = layer_two.get('licenseStatus', '') if layer_two else ''
                    if license_status_value and 'فعال' in license_status_value:
                        active_guilds_list.append(g)
                    else:
                        inactive_guilds_list.append(g)

                if active_guilds_list:
                    guild_info = active_guilds_list[0]
                elif inactive_guilds_list:
                    def parse_persian_date(date_str):
                        if not date_str:
                            return None
                        try:
                            date_str = date_str.strip()
                            parts = date_str.split('/')
                            if len(parts) == 3:
                                year = int(parts[0])
                                month = int(parts[1])
                                day = int(parts[2])
                                return jdatetime.date(year, month, day)
                        except:
                            pass
                        return None

                    latest_guild = None
                    latest_date = None
                    for g in inactive_guilds_list:
                        layer_two = g.get('layerTwo', {})
                        license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else ''
                        parsed_date = parse_persian_date(license_issue_date)
                        if parsed_date:
                            if latest_date is None or parsed_date > latest_date:
                                latest_date = parsed_date
                                latest_guild = g

                    if latest_guild:
                        guild_info = latest_guild

                if not guild_info:
                    guild_info = guild_list[0]

            except Exception as e:
                failed_count += 1
                failed_records.append({
                    'guild_id': guild.id,
                    'national_id': national_code,
                    'error': f'خطا در دریافت اطلاعات صنفی: {str(e)}'
                })
                continue

            # استخراج اطلاعات از API
            layer_one = guild_info.get('layerOne', {})
            layer_two = guild_info.get('layerTwo', {})

            # اطلاعات شخصی
            first_name = person_info.get('firstName', '')
            last_name = person_info.get('lastName', '')
            father_name = person_info.get('fatherName', '')
            gender = person_info.get('gender', '')
            identity_no = person_info.get('identityNo', '')
            birth_date = person_info.get('birthDate', '')
            city_name = layer_two.get('city', '')
            address_text = layer_two.get('address', '')
            postal_code = layer_two.get('postalcode', '')
            mobile = person_info.get('mobile', '') or person_info.get('mobilenumber', '')

            # اطلاعات صنفی
            title = layer_one.get('title', '') or layer_two.get('title', '') or guild_info.get('title', '')
            license_number = guild_info.get('licenseNumber', '')
            license_type = guild_info.get('licenseType', '')
            license_status = guild_info.get('licenseStatus', '')
            license_issue_date = layer_two.get('licenseIssueDate', '')
            license_expire_date = guild_info.get('licenseExpireDate', '')
            type_activity_name = layer_one.get('isicname', '') or layer_two.get('isicname', '')
            company_name = layer_one.get('corporationName', '') or layer_two.get('corporationName', '')
            company_identifier = layer_one.get('nationalId', '') or layer_two.get('nationalId', '')
            union_name = layer_one.get('unionName', '') or layer_two.get('unionName', '')
            phone = layer_one.get('phonenumber', '') or layer_two.get('phonenumber', '')
            has_partner_val = layer_one.get('hasPartner', '') or layer_two.get('hasPartner', '')
            is_foreigner_val = layer_one.get('isForeigner', '') or layer_two.get('isForeigner', '')
            steward = guild.steward  # حفظ مقدار فعلی

            # تبدیل تاریخ تولد
            birthday_str = None
            if birth_date:
                try:
                    jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date()
                    birthday_str = jalali_date.strftime("%Y-%m-%d")
                except:
                    pass

            # تبدیل boolean ها
            has_partner = parse_yes_no(has_partner_val)
            is_foreign_national = parse_yes_no(is_foreigner_val)

            # پیدا کردن شهر
            city = City.objects.filter(name__icontains=city_name, trash=False).first()
            if not city:
                normalized_city = _normalize_fa_ar(city_name)
                city = City.objects.filter(name__icontains=normalized_city, trash=False).first()
            if not city:
                alt_city = str(city_name or '')
                alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي')
                city = City.objects.filter(name__icontains=alt_city, trash=False).first()
            if not city:
                try:
                    target = _normalize_fa_ar(city_name or '')
                    best_id = None
                    best_ratio = 0.0
                    for c in all_cities_cache:
                        cand = _normalize_fa_ar(c.get('name', '') or '')
                        ratio = difflib.SequenceMatcher(None, target, cand).ratio()
                        if ratio > best_ratio:
                            best_ratio = ratio
                            best_id = c['id']
                    if best_id is not None and best_ratio >= 0.72:
                        city = City.objects.filter(id=best_id, trash=False).first()
                except Exception:
                    city = None

            if not city:
                failed_count += 1
                failed_records.append({
                    'guild_id': guild.id,
                    'national_id': national_code,
                    'error': f"شهر '{city_name}' یافت نشد"
                })
                continue

            province = city.province

            # آپدیت اطلاعات کاربر
            if user:
                user.national_id = national_code
                user.national_code = identity_no
                user.father_name = father_name
                user.gender = gender
                user.birthday = birthday_str
                if city:
                    user.city = city
                    user.province = province
                if first_name:
                    user.first_name = first_name
                if last_name:
                    user.last_name = last_name
                    user.fullname = f"{first_name} {last_name}".strip()
                if mobile and not user.mobile:
                    user.mobile = mobile
                user.save()

            # ایجاد یا آپدیت آدرس
            if address_text:
                address = SystemAddress(city=city, province=province, address=address_text, postal_code=postal_code)
                address.save()
            else:
                address = guild.address if guild.address else None

            # پیدا کردن TypeActivity و AreaActivity
            from panel.models import TypeActivity, AreaActivity
            type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first()
            if not type_activity:
                type_activity = TypeActivity.objects.filter(trash=False).first()

            area_activity = AreaActivity.objects.filter(trash=False).first()

            # آپدیت guild
            guild.guilds_name = title
            guild.license_number = license_number
            guild.license_type = license_type
            guild.license_status = license_status
            guild.is_foreign_national = is_foreign_national
            guild.has_partner = has_partner
            guild.has_inquiry = True
            guild.company_name = company_name
            guild.company_identifier = company_identifier
            if address:
                guild.address = address
            guild.type_activity = type_activity.title if type_activity else type_activity_name
            guild.area_activity = area_activity.title if area_activity else ''
            guild.guild_type_activity = type_activity
            guild.guild_area_activity = area_activity
            guild.union_name = union_name
            guild.phone_number = phone
            guild.active = True

            if license_issue_date:
                converted_date = persian_date_to_datetime(license_issue_date)
                if converted_date:
                    guild.license_issue_date = converted_date

            if license_expire_date:
                converted_date = persian_date_to_datetime(license_expire_date)
                if converted_date:
                    guild.license_expire_date = converted_date

            guild.save()
            success_count += 1

        except Exception as e:
            failed_count += 1
            failed_records.append({
                'guild_id': guild.id,
                'national_id': getattr(guild.user, 'national_id', '') if guild.user else '',
                'error': f'خطای کلی: {str(e)}'
            })
            logger.error(f"خطا در آپدیت guild {guild.id}: {str(e)}")
            continue

    return Response({
        'result': 'پردازش کامل شد',
        'total_guilds': active_guilds.count(),
        'success_count': success_count,
        'failed_count': failed_count,
        'skipped_count': skipped_count,
        'failed_records': failed_records[:100]  # فقط 100 مورد اول خطاها
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def find_users_with_duplicate_national_id(request):
    users = SystemUserProfile.objects.filter(
        trash=False,
        national_id__isnull=False,
        role__name__in=['Guilds', 'Steward']
    ).exclude(national_id__exact='').exclude(national_id__exact='0').distinct()

    national_id_dict = {}
    for user in users:
        nid = str(user.national_id).strip()
        if nid.isdigit() and len(nid) == 10:
            if nid not in national_id_dict:
                national_id_dict[nid] = []
            national_id_dict[nid].append(user)

    result = []
    for nid, user_list in national_id_dict.items():
        if len(user_list) > 1:
            users_data = []
            for user in user_list:
                users_data.append({
                    'id': user.id,
                    'mobile': user.mobile,
                    'first_name': user.first_name,
                    'last_name': user.last_name,
                    'fullname': user.fullname,
                    'national_id': user.national_id
                })
            result.append({
                'national_id': nid,
                'count': len(user_list),
                'users': users_data
            })

    result.sort(key=lambda x: x['count'], reverse=True)

    total_duplicate = len(result)
    total_users = 0
    for item in result:
        total_users += item['count']

    return Response({
        'result': 'ok',
        'total_duplicate_national_ids': total_duplicate,
        'total_users_with_duplicate': total_users,
        'duplicate_national_ids': result
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def fix_duplicate_national_id_users(request):
    users = SystemUserProfile.objects.filter(
        trash=False,
        national_id__isnull=False,
        role__name__in=['Guilds', 'Steward']
    ).exclude(national_id__exact='').exclude(national_id__exact='0')

    national_id_dict = {}
    for user in users:
        nid = str(user.national_id).strip()
        if nid.isdigit() and len(nid) == 10:
            if nid not in national_id_dict:
                national_id_dict[nid] = []
            national_id_dict[nid].append(user)

    duplicate_national_ids = {}
    for nid, user_list in national_id_dict.items():
        if len(user_list) > 1:
            duplicate_national_ids[nid] = user_list

    all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name'))

    def _normalize_fa_ar(text):
        if not text:
            return text
        mapping = {
            'ك': 'ک',
            'ي': 'ی',
            'ى': 'ی',
            '\u0649': 'ی',
            '\u06CC': 'ی',
            '\u064A': 'ی',
            'ۀ': 'ه',
            'ة': 'ه',
            'ؤ': 'و',
            'أ': 'ا',
            'إ': 'ا',
            'ٱ': 'ا',
            '\u200c': ' ',
        }
        out = str(text)
        for src, dst in mapping.items():
            out = out.replace(src, dst)
        return out.strip()

    def parse_yes_no(val):
        if isinstance(val, bool):
            return val
        if isinstance(val, str):
            x = False if val.strip() == 'خیر' else True
            return x
        return bool(val)

    def find_city(city_name):
        if not city_name:
            return None
        city = City.objects.filter(name__icontains=city_name, trash=False).first()
        if not city:
            normalized_city = _normalize_fa_ar(city_name)
            city = City.objects.filter(name__icontains=normalized_city, trash=False).first()
        if not city:
            alt_city = str(city_name or '')
            alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي')
            city = City.objects.filter(name__icontains=alt_city, trash=False).first()
        if not city:
            try:
                target = _normalize_fa_ar(city_name or '')
                best_id = None
                best_ratio = 0.0
                for c in all_cities_cache:
                    cand = _normalize_fa_ar(c.get('name', '') or '')
                    ratio = difflib.SequenceMatcher(None, target, cand).ratio()
                    if ratio > best_ratio:
                        best_ratio = ratio
                        best_id = c['id']
                if best_id is not None and best_ratio >= 0.72:
                    city = City.objects.filter(id=best_id, trash=False).first()
            except Exception:
                city = None
        return city

    def generate_random_mobile():
        while True:
            random_num = ''.join([str(random.randint(0, 9)) for _ in range(9)])
            mobile = '08' + random_num
            if not SystemUserProfile.objects.filter(mobile=mobile).exists():
                try:
                    check_response = requests.get(
                        f"{ARTA_URL_CHECK_USER_EXISTS}?username={mobile}",
                        verify=False
                    )
                    if check_response.status_code == 200:
                        return mobile
                except Exception:
                    continue

    processed = []
    failed = []

    for national_id, user_list in duplicate_national_ids.items():
        try:
            guild_response = requests.get(
                f"https://pay.rasadyar.net/national-documents?info={national_id}&type=guild"
            )
            guild_data = guild_response.json()

            if not guild_data.get('status') or not guild_data.get('data'):
                failed.append({
                    'national_id': national_id,
                    'reason': 'اطلاعات صنفی یافت نشد'
                })
                continue

            guild_list = guild_data.get('data', [])
            guild_info = None

            for g in guild_list:
                license_status_value = g.get('licenseStatus', '')
                if license_status_value and 'فعال' in license_status_value:
                    guild_info = g
                    break

            if not guild_info and guild_list:
                guild_info = guild_list[0]

            if not guild_info:
                failed.append({
                    'national_id': national_id,
                    'reason': 'اطلاعات صنفی یافت نشد'
                })
                continue

            guild_layer_two = guild_info.get('layerTwo', {})
            mobile_from_api = guild_layer_two.get('mobilenumber')
            steward_from_api = guild_layer_two.get('steward', False)

            if isinstance(steward_from_api, str):
                steward_value = steward_from_api.strip().lower() in ('true', 'بله', '1', 'yes')
            else:
                steward_value = bool(steward_from_api)

            if not mobile_from_api:
                failed.append({
                    'national_id': national_id,
                    'reason': 'شماره موبایل در API یافت نشد'
                })
                continue

            existing_user = SystemUserProfile.objects.filter(
                trash=False,
                mobile=mobile_from_api
            ).first()

            if existing_user:
                has_killhouse = existing_user.role.filter(name='KillHouse').exists()
                if not has_killhouse:
                    person_response = requests.get(
                        f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person"
                    )
                    person_data = person_response.json()

                    if not person_data.get('status'):
                        failed.append({
                            'national_id': national_id,
                            'reason': 'اطلاعات شخص یافت نشد'
                        })
                        continue

                    person_info = person_data.get('data', {})

                    first_name = person_info.get('firstName')
                    last_name = person_info.get('lastName')
                    father_name = person_info.get('fatherName')
                    gender = person_info.get('gender')
                    identity_no = person_info.get('identityNo')
                    is_alive = person_info.get('isLive', True)
                    birth_date = person_info.get('birthDate')

                    try:
                        jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date()
                        birthday_str = jalali_date.strftime("%Y-%m-%d")
                    except Exception:
                        birthday_str = None

                    city_name = guild_info.get('city')
                    city = find_city(city_name)

                    existing_user.national_id = national_id
                    existing_user.national_code = identity_no
                    existing_user.first_name = first_name
                    existing_user.last_name = last_name
                    existing_user.fullname = f"{first_name} {last_name}".strip()
                    existing_user.father_name = father_name
                    existing_user.gender = gender
                    if birthday_str:
                        existing_user.birthday = birthday_str
                    existing_user.is_alive = is_alive
                    if city:
                        existing_user.city = city
                        existing_user.province = city.province
                    existing_user.save()

                for user in user_list:
                    has_killhouse = user.role.filter(name='KillHouse').exists()
                    if user.id != existing_user.id:
                        user_guilds = Guilds.objects.filter(trash=False, user=user)
                        if user_guilds.exists():
                            user_guilds.update(active=False)

                        has_killhouse = user.role.filter(name='KillHouse').exists()
                        if not has_killhouse:
                            random_mobile = generate_random_mobile()
                            data = {
                                "first_mobile_number": user.mobile,
                                "second_mobile_number": random_mobile,
                            }
                            user.national_id = '0'
                            req = requests.post(
                                url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                                data=data,
                                verify=False
                            )
                            if req.status_code == 200:
                                user.user.username = random_mobile
                                user.user.save()
                                user.mobile = random_mobile
                                user.save()

                        else:
                            user_guilds = Guilds.objects.filter(trash=False, user=user)
                            if user_guilds.exists():
                                user_guilds.update(active=False)
                            user.national_id = '0'
                            user.save()
                    else:
                        if has_killhouse:
                            user_guilds = Guilds.objects.filter(trash=False, user=user)
                            if user_guilds.exists():
                                user_guilds.update(active=False)
                            user.national_id = '0'
                            user.save()

                processed.append({
                    'national_id': national_id,
                    'action': 'updated_existing_user',
                    'user_id': existing_user.id
                })
            else:
                for user in user_list:
                    has_killhouse = existing_user.role.filter(name='KillHouse').exists()
                    if not has_killhouse:
                        user.active = False
                        user.save()

                    user_guilds = Guilds.objects.filter(trash=False, user=user)
                    user_guilds.update(active=False)

                person_response = requests.get(
                    f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person"
                )
                person_data = person_response.json()

                if not person_data.get('status'):
                    failed.append({
                        'national_id': national_id,
                        'reason': 'اطلاعات شخص یافت نشد'
                    })
                    continue

                person_info = person_data.get('data', {})

                first_name = person_info.get('firstName')
                last_name = person_info.get('lastName')
                father_name = person_info.get('fatherName')
                gender = person_info.get('gender')
                identity_no = person_info.get('identityNo')
                is_alive = person_info.get('isLive', True)
                birth_date = person_info.get('birthDate')

                try:
                    jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date()
                    birthday_str = jalali_date.strftime("%Y-%m-%d")
                except Exception:
                    birthday_str = None

                city_name = guild_info.get('city')
                city = find_city(city_name)

                role_name = "Steward" if steward_value else "Guilds"

                password = '123456'
                register_payload = {
                    "username": mobile_from_api,
                    "first_name": first_name or "",
                    "last_name": last_name or "",
                    "password": password,
                    "national_code": identity_no or '0',
                    "role": role_name,
                    "api_key": PROJECT_API_KEY
                }

                req = requests.post(
                    url=ARTA_REGISTER,
                    data=register_payload,
                    verify=False
                )

                if req.status_code == 200:
                    hashed_password = hashlib.sha256(password.encode()).hexdigest()
                    user = User.objects.filter(username=mobile_from_api).first()
                    if not user:
                        user = User(
                            username=mobile_from_api,
                            first_name=first_name or "",
                            last_name=last_name or "",
                            password=hashed_password
                        )
                        user.save()

                    base_id = SystemUserProfile.objects.all()
                    if base_id.count() > 0:
                        base_id = int(base_id.last().base_order) + 1
                    else:
                        base_id = 1000

                    new_user = SystemUserProfile(
                        mobile=mobile_from_api,
                        first_name=first_name,
                        last_name=last_name,
                        fullname=f"{first_name} {last_name}".strip(),
                        user=user,
                        base_order=base_id,
                        password=password,
                        national_id=national_id,
                        national_code=identity_no,
                        father_name=father_name,
                        gender=gender,
                        birthday=birthday_str if birthday_str else str(datetime.datetime.now().date()),
                        is_alive=is_alive,
                        city=city,
                        province=city.province if city else None
                    )
                    new_user.save()

                    if steward_value:
                        group = Group.objects.get(name__exact="Steward")
                    else:
                        group = Group.objects.get(name__exact="Guilds")
                    new_user.role.add(group)

                    wallet = Wallet()
                    wallet.save()

                    address = SystemAddress(
                        province=city.province if city else None,
                        city=city,
                        address=city_name or ''
                    )
                    address.save()

                    title = guild_info.get('title', f"{first_name} {last_name}".strip())
                    license_number = guild_info.get('licenseNumber', '')
                    license_type = guild_info.get('licenseType', '')
                    license_status = guild_info.get('licenseStatus', '')
                    type_activity_name = guild_info.get('isicname', '')
                    company_name = guild_info.get('corporationName', '')
                    company_identifier = guild_info.get('nationalId', '')
                    union_name = guild_info.get('unionName', '')
                    phone = guild_layer_two.get('phonenumber', '')
                    has_partner_val = guild_layer_two.get('hasPartner', False)
                    is_foreigner_val = guild_layer_two.get('isForeigner', False)

                    has_partner = parse_yes_no(has_partner_val)
                    is_foreign_national = parse_yes_no(is_foreigner_val)

                    from panel.models import TypeActivity, AreaActivity
                    type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name,
                                                                trash=False).first()
                    if not type_activity:
                        type_activity = TypeActivity.objects.filter(trash=False).first()

                    area_activity = AreaActivity.objects.filter(trash=False).first()

                    new_guild = Guilds(
                        user=new_user,
                        guilds_name=title,
                        license_number=license_number,
                        license_type=license_type,
                        license_status=license_status,
                        is_foreign_national=is_foreign_national,
                        has_partner=has_partner,
                        has_inquiry=True,
                        steward=steward_value,
                        company_name=company_name,
                        company_identifier=company_identifier,
                        address=address,
                        wallet=wallet,
                        type_activity=type_activity.title if type_activity else type_activity_name,
                        area_activity=area_activity.title if area_activity else '',
                        guild_type_activity=type_activity,
                        guild_area_activity=area_activity,
                        union_name=union_name,
                        phone_number=phone,
                        active=True,
                        province_accept_state='pending'
                    )
                    new_guild.save()

                    from panel.models import NewProduct, BroadcastPrice
                    parent_product = NewProduct.objects.all().first()
                    price = BroadcastPrice.objects.filter(trash=False).first()

                    if parent_product and price:
                        approved_price = price.steward_price if steward_value else price.guild_price
                        approved_type = price.active if approved_price > 0 else False

                        product = RolesProducts(
                            parent_product=parent_product,
                            guild=new_guild,
                            name='مرغ گرم',
                            approved_price_status=approved_type,
                            approved_price=approved_price,
                        )
                        product.save()

                    processed.append({
                        'national_id': national_id,
                        'action': 'created_new_user',
                        'user_id': new_user.id
                    })
                else:
                    failed.append({
                        'national_id': national_id,
                        'reason': 'خطا در ثبت کاربر در آرتا'
                    })
        except Exception as e:
            failed.append({
                'national_id': national_id,
                'reason': f'خطا: {str(e)}'
            })
            continue

    return Response({
        'result': 'ok',
        'processed_count': len(processed),
        'failed_count': len(failed),
        'processed': processed,
        'failed': failed
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def fix_duplicate_guilds_steward_allocation(request):
    users_with_multiple_guilds = SystemUserProfile.objects.filter(
        trash=False,
        role__name__in=['Guilds', 'Steward']
    ).annotate(
        guilds_count=Count('guilds_user', filter=Q(guilds_user__trash=False))
    ).filter(guilds_count__gt=1)

    processed = []
    failed = []

    for user in users_with_multiple_guilds:
        try:
            user_guilds = Guilds.objects.filter(
                user=user,
                trash=False,
            ).order_by('-active', '-create_date')

            if user_guilds.count() <= 1:
                continue

            active_guild = user_guilds.filter(active=True).first()

            if not active_guild:
                continue

            inactive_guilds = user_guilds.exclude(id=active_guild.id).filter(active=False)

            if not inactive_guilds.exists():
                continue

            allocations_to_move = StewardAllocation.objects.filter(
                trash=False
            ).filter(
                Q(guilds__in=inactive_guilds) |
                Q(to_guilds__in=inactive_guilds) |
                Q(to_steward__in=inactive_guilds)
            )

            allocations_moved_count = 0
            steward_updated = False
            for allocation in allocations_to_move:
                if allocation.guilds and allocation.guilds in inactive_guilds:
                    allocation.guilds = active_guild
                if allocation.to_guilds and allocation.to_guilds in inactive_guilds:
                    allocation.to_guilds = active_guild
                if allocation.to_steward and allocation.to_steward in inactive_guilds:
                    allocation.to_steward = active_guild
                    if not active_guild.steward:
                        active_guild.steward = True
                        active_guild.save()
                        steward_updated = True
                allocation.save()
                allocations_moved_count += 1

            if steward_updated:
                try:
                    steward_group = Group.objects.get(name__exact="Steward")
                    if not user.role.filter(id=steward_group.id).exists():
                        user.role.add(steward_group)
                except Group.DoesNotExist:
                    pass

            pos_machines_to_move = POSMachine.objects.filter(
                trash=False,
                guild__in=inactive_guilds
            )

            pos_machines_moved_count = 0
            for pos_machine in pos_machines_to_move:
                pos_machine.guild = active_guild
                pos_machine.save()
                pos_machines_moved_count += 1

            pos_segmentations_to_move = PosSegmentation.objects.filter(
                trash=False
            ).filter(
                Q(guild__in=inactive_guilds) |
                Q(to_guild__in=inactive_guilds)
            )

            pos_segmentations_moved_count = 0
            for pos_segmentation in pos_segmentations_to_move:

                if pos_segmentation.guild and pos_segmentation.guild in inactive_guilds:
                    pos_segmentation.guild = active_guild
                if pos_segmentation.to_guild and pos_segmentation.to_guild in inactive_guilds:
                    pos_segmentation.to_guild = active_guild
                pos_segmentation.save()
                pos_segmentations_moved_count += 1

            roles_products_to_trash = RolesProducts.objects.filter(
                trash=False,
                guild__in=inactive_guilds
            )

            roles_products_trashed_count = 0
            for roles_product in roles_products_to_trash:
                roles_product.trash = True
                roles_product.save()
                roles_products_trashed_count += 1

            for inactive_guild in inactive_guilds:
                inactive_guild.trash = True
                inactive_guild.save()

            active_guild_products = RolesProducts.objects.get(
                trash=False,
                guild=active_guild
            )

            try:
                guild_steward_allocations_product_warehousing(active_guild_products)
            except Exception:
                pass

            processed.append({
                'user_id': user.id,
                'user_mobile': user.mobile,
                'user_national_id': user.national_id,
                'active_guild_id': active_guild.id,
                'active_guild_name': active_guild.guilds_name,
                'inactive_guilds_count': inactive_guilds.count(),
                'inactive_guild_ids': list(inactive_guilds.values_list('id', flat=True)),
                'allocations_moved': allocations_moved_count,
                'pos_machines_moved': pos_machines_moved_count,
                'pos_segmentations_moved': pos_segmentations_moved_count,
                'roles_products_trashed': roles_products_trashed_count
            })

        except Exception as e:
            failed.append({
                'user_id': user.id,
                'user_mobile': user.mobile,
                'reason': f'خطا: {str(e)}'
            })
            continue

    return Response({
        'result': 'ok',
        'processed_count': len(processed),
        'failed_count': len(failed),
        'processed': processed,
        'failed': failed
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def fetch_evacuation_details_for_unknown_hatchings(request):
    hatchings = (
        PoultryHatching.objects
            .filter(
            Q(unknown=True) | Q(state='pending', allow_hatching='pending', archive=False),
            trash=False,
            licence_number__isnull=False,
        )
    )

    licence_numbers = list(hatchings.values_list('licence_number', flat=True).distinct())

    try:
        payload = {"codes": licence_numbers}
        external_response = requests.post(
            "http://rsibackend.rasadyaar.ir/app/get-evacuation-details-by-request-codes/",
            json=payload,
        )
        external_response.raise_for_status()
        external_data = external_response.json() or {}
    except Exception as exc:
        return Response(
            {"result": f"خطا در ارتباط با سرویس تلفات: {str(exc)}"},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR,
        )

    created_count = 0
    updated_count = 0
    skipped_no_data = 0

    report_type_field_map = {
        'تلفات ناشی از بیماری': 'total_disease_losses',
        'معدوم سازی گله': 'total_flock_destruction',
        'تلفات عادی گله': 'total_normal_flock_losses',
        'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses',
        'تلفات ناشی از آتش سوزی': 'total_fire_losses',
    }
    report_type_fields = list(set(report_type_field_map.values()))

    evacuation_detail_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',
    ]

    def build_unique_key(detail_payload):
        external_id = detail_payload.get('ExternalId')
        if external_id:
            return f"external:{external_id}"
        string_id = detail_payload.get('StringId')
        if string_id:
            return f"string:{string_id}"
        return "fallback:" + "|".join(
            str(detail_payload.get(key) or '') for key in ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate')
        )

    def normalize_good_count(value):
        if value in (None, ''):
            return None
        try:
            return int(value)
        except (TypeError, ValueError):
            try:
                return int(float(value))
            except (TypeError, ValueError):
                return None

    def apply_evacuation_losses(instance):
        totals = {field: 0 for field in report_type_fields}
        detail_qs = instance.evacuation_details.filter(trash=False, IsDeleted=False)
        for detail in detail_qs:
            report_type = (detail.ReportTypeString or '').strip()
            field_name = report_type_field_map.get(report_type)
            if not field_name:
                continue
            totals[field_name] += detail.GoodCount or 0
        for field, value in totals.items():
            setattr(instance, field, value)

    hatching_map = {h.licence_number: h for h in hatchings}

    for code, details in external_data.items():
        hatching = hatching_map.get(code)
        if not hatching:
            skipped_no_data += 1
            continue

        if not isinstance(details, list) or not details:
            skipped_no_data += 1
            continue

        seen_unique_keys = set()

        for detail in details:
            if not isinstance(detail, dict):
                continue

            detail_payload = {field: detail.get(field) for field in evacuation_detail_fields}
            detail_payload['GoodCount'] = normalize_good_count(detail_payload.get('GoodCount'))
            if not any(value not in (None, '') for value in detail_payload.values()):
                continue

            unique_key = build_unique_key(detail_payload)
            if unique_key in seen_unique_keys:
                continue
            seen_unique_keys.add(unique_key)

            external_id = detail_payload.get('ExternalId')
            string_id = detail_payload.get('StringId')
            lookup_kwargs = {'hatching': hatching}
            if external_id:
                lookup_kwargs['ExternalId'] = external_id
            elif string_id:
                lookup_kwargs['StringId'] = string_id
            else:
                lookup_key_fields = ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate')
                lookup_kwargs.update({field: detail_payload.get(field) for field in lookup_key_fields})

            defaults = detail_payload.copy()
            defaults['hatching'] = hatching
            lookup_kwargs['trash'] = False

            obj, created = EvacuationHatchingDetail.objects.update_or_create(
                defaults=defaults,
                **lookup_kwargs,
            )
            if created:
                created_count += 1
            else:
                updated_count += 1

        apply_evacuation_losses(hatching)
        hatching.save()

    return Response(
        {
            "result": "ثبت تلفات برای جوجه‌ریزی‌های unknown انجام شد.",
            "created_details": created_count,
            "updated_details": updated_count,
            "skipped_already_had_details": updated_count,
            "skipped_no_data": skipped_no_data,
            "processed_hatchings": len(licence_numbers),
        },
        status=status.HTTP_200_OK,
    )


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def upload_image_to_server_for_poultry_science(request):
    files = request.FILES.getlist('file')
    if not files:
        single_file = request.FILES.get('file')
        if single_file:
            files = [single_file]

    uploaded_urls = []

    for idx, f in enumerate(files):
        now = datetime.datetime.now()
        name = now.strftime('%Y%m%d%H%M%S')
        name = f"{name}{idx}.jpg"

        url = send_image_to_server_for_poultry_science(f, name)
        uploaded_urls.append(url)

    return Response({
        'urls': uploaded_urls
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def poultry_science_for_bazresi(request):
    query = PoultryScienceReport.objects.filter(trash=False).order_by('-id')

    value = request.GET.get('value')
    search = request.GET.get('search')
    if value and search == 'filter':
        if search != 'undefined' and search.strip():
            query = query.filter(
                build_query(PoultryScienceReportFilterSet.Meta.fields, value)
            )

    serializer = PoultryScienceReportSerializer(query, many=True)
    return Response(serializer.data, status=status.HTTP_200_OK)