from django.contrib.auth.models import Group
from django.db.models import Sum, Q, F, Prefetch
from rest_framework import serializers
# from rest_framework.response import Response
from rest_framework.response import Response
from authentication.models import UserProfile, SystemUserProfile, CityUnit, SystemAddress
from authentication.serializer.serializer import SystemUserProfileSerializer, \
    SystemUserProfileForAutoAllocationSerializer, SystemUserProfileForPoultryLocSerializer, \
    SystemUserProfileForGuildSerializer, SystemUserProfileForPoultryScienceWithoutRoleSerializer
from authentication.serializers import UserProfileSerializer, SystemAddressSerializer, \
    SystemAddressForLocSerializer, CityForLocSerializer
from authentication.serializer.serializer import BankCardSerializer
# from panel.KillHouse.serializers import KillHouseRequestExchangeReserveSerializer
# from panel.VetFarm.serializers import VetFarmForPoultrySerializer
from panel.models import PoultryRequest, PoultryAssignmentInformation, KillHouseRequest, KillHouseCheckRequest, \
    CityOperatorCheckRequest, ProvinceCheckOperatorRequest, KillHouseAssignmentInformation, ProvinceFactorToKillHouse, \
    KillHouseFactorToProvince, DepositAllocation, PovinceInspector, VetCheckRequest, PoultryRequestExchange, \
    ProvinceKillRequest, Poultry, PoultryTenant, PoultryHatching, PoultryRequestAuction, Pricing, \
    KillHouseRequestAction, ProvinceRequestAction, ProvinceOperator, VetFarmInspection, InspectorOperator, \
    KillHouseRequestActionWinner, CityOperator, VetFarm, ShareOfAllocation, ProvinceFactorToKillHouseForPoultry, \
    KillHouseFactorToPoultry, KillHouseComplaint, CheckUnusualCasualties, PercentageOfLosses, \
    ProvinceImportKillHouseOutFactors, TotalPoultryRequestQuantity, PoultryAllowCityProvince, \
    ProvinceAllowPoultryChooseKillHouse, ProvinceAllowPoultrySellFree, Vet, LastUpdate, ChainCompany, ChainAllocation, \
    ChainCompanyTransaction, InternalTransaction, KillHouseOperator, KillHouse, OutProvincePoultryRequestBuyer, \
    PoultryExport, PoultryOutProvinceRequest, FreeSaleWithinprovince, PoultryPrediction, HatchingIncreaseRequest, \
    ChickenCommissionPrices, PoultryRequestQuarantineCode, ManagementHatchingAgeRange, PoultryScienceReport, \
    EvacuationHatchingDetail
# PoultryRequestExchangeAccept
from datetime import datetime
import pytz
from num2fawords import words, ordinal_words

utc = pytz.UTC


class OutProvincePoultryRequestBuyerSerializer(serializers.ModelSerializer):
    class Meta:
        model = OutProvincePoultryRequestBuyer
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'created_by',
            'modified_by'
        )


class OutProvincePoultryRequestBuyerForBuyerRequestSerializer(serializers.ModelSerializer):
    requests_info = serializers.SerializerMethodField('get_requests_info')

    class Meta:
        model = OutProvincePoultryRequestBuyer
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'created_by',
            'modified_by'
        )

    def get_requests_info(self, obj):
        total_quantity = 0
        total_weight = 0
        poultry_requests = PoultryRequest.objects.filter(
            Q(state_process='accepted', province_state='accepted', final_state='archive', has_wage=True,
              wage_pay=True, out_province_request_cancel=False) | Q(state_process='accepted', province_state='accepted',
                                                                    final_state='archive',
                                                                    has_wage=False, wage_pay=False,
                                                                    out_province_request_cancel=False), trash=False,
            out=True, out_province_poultry_request_buyer=obj)

        total_quantity = poultry_requests.aggregate(total=Sum('quantity'))[
                             'total'] or 0
        total_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                           'total'] or 0

        return {
            "number_of_requests": len(poultry_requests),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
        }


class ChainCompanySerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = ChainCompany
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'created_by',
            'modified_by'
        )


class ChainCompanyForCompanyRequestSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)
    requests_info = serializers.SerializerMethodField('get_requests_info')

    class Meta:
        model = ChainCompany
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'created_by',
            'modified_by'
        )

    def get_requests_info(self, obj):
        total_quantity = 0
        total_weight = 0
        chain_allocations = ChainAllocation.objects.filter(chain_company=obj, state='accepted', trash=False).order_by(
            '-id')

        total_quantity = chain_allocations.aggregate(total=Sum('quantity'))[
                             'total'] or 0
        total_weight = chain_allocations.aggregate(total=Sum('weight'))[
                           'total'] or 0

        return {
            "number_of_requests": len(chain_allocations),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
        }


class ChainCompanyForTotalWageAllocationWithDAteSerializer(serializers.ModelSerializer):
    info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = ChainCompany
        fields = ['key', 'info']

    def get_info(self, obj):
        total_quantity = 0
        total_weight = 0
        total_wage = 0
        date1 = datetime.strptime(str(self.context.get('request').GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(self.context.get('request').GET['date2']), '%Y-%m-%d').date()
        role = self.context.get('request').GET['role']
        if role in ['ChainCompany', 'SuperAdmin', 'AdminX', 'Supporter']:
            wage_type = 'total_wage_amount'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'ProvinceOperator':
            wage_type = 'union_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                union_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'Company':
            wage_type = 'company_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                company_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'Guilds':
            wage_type = 'guilds_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                guilds_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        else:
            wage_type = 'wallet_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                archive_wage=False,
                trash=False).order_by('id')

        total_quantity += chain_allocations.aggregate(total=Sum('quantity'))[
                              'total'] or 0
        total_weight += chain_allocations.aggregate(total=Sum('weight'))[
                            'total'] or 0
        total_wage += chain_allocations.aggregate(total=Sum(wage_type))[
                          'total'] or 0

        return {
            "company": obj.name,
            "company_user_fullname": obj.user.fullname,
            "company_user_mobile": obj.user.mobile,
            "company_user_city": obj.user.city.name,
            "total_count": len(chain_allocations),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
            "total_wage": total_wage,

        }


class ChainCompanyForTotalWageTransactionSerializer(serializers.ModelSerializer):
    info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = ChainCompany
        fields = ['key', 'info']

    def get_info(self, obj):
        total_paid_wage = 0
        role = self.context.get('request').GET['role']
        if role in ['ChainCompany', 'SuperAdmin', 'AdminX', 'Supporter']:
            wage_type = 'amount'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                status='completed',
                trash=False).order_by('id')
        elif role == 'ProvinceOperator':
            wage_type = 'union_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                status='completed',
                union_share__gt=0,
                trash=False).order_by('id')
        elif role == 'Company':
            wage_type = 'company_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                status='completed',
                company_share__gt=0,
                trash=False).order_by('id')
        elif role == 'Guilds':
            wage_type = 'guilds_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                status='completed',
                guilds_share__gt=0,
                trash=False).order_by('id')
        else:
            wage_type = 'wallet_share'

        total_paid_wage += transactions.aggregate(total=Sum(wage_type))[
                               'total'] or 0

        return {
            "company": obj.name,
            "company_user_fullname": obj.user.fullname,
            "company_user_mobile": obj.user.mobile,
            "company_user_city": obj.user.city.name,
            "total_paid_count": len(transactions),
            "total_paid_wage": total_paid_wage,

        }


class ChainCompanyForTotalWageTransactionTransactionWithDAteSerializer(serializers.ModelSerializer):
    info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = ChainCompany
        fields = ['key', 'info']

    def get_info(self, obj):
        total_paid_wage = 0
        date1 = datetime.strptime(str(self.context.get('request').GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(self.context.get('request').GET['date2']), '%Y-%m-%d').date()
        role = self.context.get('request').GET['role']
        if role in ['ChainCompany', 'SuperAdmin', 'AdminX', 'Supporter']:
            wage_type = 'amount'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                trash=False).order_by('id')
        elif role == 'ProvinceOperator':
            wage_type = 'union_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                union_share__gt=0,
                trash=False).order_by('id')
        elif role == 'Company':
            wage_type = 'company_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                company_share__gt=0,
                trash=False).order_by('id')
        elif role == 'Guilds':
            wage_type = 'guilds_share'
            transactions = InternalTransaction.objects.filter(
                chain_company=obj,
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                guilds_share__gt=0,
                trash=False).order_by('id')
        else:
            wage_type = 'wallet_share'

        total_paid_wage += transactions.aggregate(total=Sum(wage_type))[
                               'total'] or 0

        return {
            "company": obj.name,
            "company_user_fullname": obj.user.fullname,
            "company_user_mobile": obj.user.mobile,
            "company_user_city": obj.user.city.name,
            "total_paid_count": len(transactions),
            "total_paid_wage": total_paid_wage,

        }


class ChainCompanyForTotalWageAllocationSerializer(serializers.ModelSerializer):
    info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = ChainCompany
        fields = ['key', 'info']

    def get_info(self, obj):
        total_quantity = 0
        total_weight = 0
        total_wage = 0
        role = self.context.get('request').GET['role']
        if role in ['ChainCompany', 'SuperAdmin', 'AdminX', 'Supporter']:
            wage_type = 'total_wage_amount'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'ProvinceOperator':
            wage_type = 'union_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                union_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'Company':
            wage_type = 'company_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                company_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        elif role == 'Guilds':
            wage_type = 'guilds_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                guilds_share__gt=0,
                archive_wage=False,
                trash=False).order_by('id')
        else:
            wage_type = 'wallet_share'
            chain_allocations = ChainAllocation.objects.filter(
                chain_company=obj,
                archive_wage=False,
                trash=False).order_by('id')

        total_quantity += chain_allocations.aggregate(total=Sum('quantity'))[
                              'total'] or 0
        total_weight += chain_allocations.aggregate(total=Sum('weight'))[
                            'total'] or 0
        total_wage += chain_allocations.aggregate(total=Sum(wage_type))[
                          'total'] or 0

        return {
            "company": obj.name,
            "company_user_fullname": obj.user.fullname,
            "company_user_mobile": obj.user.mobile,
            "company_user_city": obj.user.city.name,
            "total_count": len(chain_allocations),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
            "total_wage": total_wage,

        }


class PoultryForAutoAllocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Poultry
        fields = ['unit_name']


class PoultryForPoultryRequestLetterSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = Poultry
        fields = ['unit_name', 'user', 'breeding_unique_id']


class PoultryForBarDifferenceRequestSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)

    class Meta:
        model = Poultry
        fields = ['unit_name', 'user']


class PoultryForBarManagementSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(required=False)

    class Meta:
        model = Poultry
        fields = ['unit_name', 'city_operator', 'user', 'total_capacity', 'address', 'breeding_unique_id',
                  'system_code']


class TotalPoultrySerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(required=False)
    hatching_info = serializers.SerializerMethodField('get_hatching_info')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')

    class Meta:
        model = Poultry
        fields = ['key', 'user', 'address', 'unit_name', 'breeding_unique_id', 'epidemiological_code', 'system_code',
                  'total_capacity', 'number_of_halls', 'health_certificate_number', 'city_operator', 'hatching_info',
                  'vet_farm', 'order_limit']

    def get_hatching_info(self, obj):
        hatching = PoultryHatching.objects.filter(poultry__exact=obj, state='pending', archive=False,
                                                  trash=False).last()
        period = None
        active_hatching = False
        if hatching:
            period = hatching.period
            if hatching.state == 'pending':
                active_hatching = True
        return {"period": period, "active_hatching": active_hatching}

    def get_vet_farm(self, obj):
        vet_farm_name = None
        vet_farm_mobile = None
        vet_farm = VetFarm.objects.filter(poultry__exact=obj, trash=False).select_related('vet__user').last()
        if vet_farm:
            vet_farm_name = vet_farm.vet.user.fullname
            vet_farm_mobile = vet_farm.vet.user.mobile

        return {"vet_farm_name": vet_farm_name, "vet_farm_mobile": vet_farm_mobile}


class PoultryForPoultryHatchingForKillInformationSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    last_hatching_remain_quantity = serializers.SerializerMethodField('get_last_hatching_remain_quantity')
    last_hatching_diffrent_request_quantity = serializers.SerializerMethodField(
        'get_last_hatching_diffrent_request_quantity')
    chain_company = serializers.SerializerMethodField('get_chain_company')
    province_allow_sell_free = serializers.SerializerMethodField('get_allow_sell_free')
    free_governmental_info = serializers.SerializerMethodField('get_free_governmental_info')

    address = SystemAddressSerializer(required=False)

    class Meta:
        model = Poultry
        fields = ['user', 'key', 'unit_name', 'address',
                  'last_hatching_remain_quantity', 'province_allow_sell_free', 'chain_company',
                  'last_hatching_diffrent_request_quantity', 'free_governmental_info']

    def get_last_hatching_remain_quantity(self, obj):
        hatching = PoultryHatching.objects.filter(poultry=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        remain = hatching.left_over if hatching else 0
        return remain

    def get_last_hatching_diffrent_request_quantity(self, obj):
        left_export_quantity = None
        left_poultry_out_province = None
        age = None
        breed = None
        left_over = 0

        hatching = PoultryHatching.objects.filter(poultry=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        poultry_export = PoultryExport.objects.get(trash=False)
        if poultry_export.limitation_status == True:
            total_export = int(hatching.quantity * (poultry_export.limitation / 100))
            hatching_export_quantity = hatching.export_killed_quantity
            left_export_quantity = hatching.left_over if hatching.left_over <= (
                    total_export - hatching_export_quantity) else total_export - hatching_export_quantity

        poultry_out_province = PoultryOutProvinceRequest.objects.get(trash=False)
        if poultry_out_province.limitation_status == True:
            total_poultry_out_province = int(hatching.quantity * (poultry_out_province.limitation / 100))
            hatching_poultry_out_province_quantity = hatching.out_province_killed_quantity
            left_poultry_out_province = hatching.left_over if hatching.left_over <= (
                    total_poultry_out_province - hatching_poultry_out_province_quantity) else total_poultry_out_province - hatching_poultry_out_province_quantity
        if hatching:
            age = hatching.chicken_age
            breed = hatching.chicken_breed
            left_over = hatching.left_over
        return {
            "left_export_quantity": left_export_quantity,
            "left_poultry_out_province": left_poultry_out_province,
            "age": age,
            "breed": breed,
            "left_over": left_over,
        }

    def get_chain_company(self, obj):
        hatching = PoultryHatching.objects.filter(poultry=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        chain_company = False if hatching.has_chain_company == False else True
        return {
            "chain_company": chain_company,
            "hatching-key": hatching.key
        }

    def get_allow_sell_free(self, instance):
        allow_state = None
        province_allow = ProvinceAllowPoultrySellFree.objects.filter(poultry=instance).first()
        if province_allow:
            allow_state = province_allow.allow
        return allow_state

    def get_free_governmental_info(self, obj):
        left_total_free_commitment_quantity = 0
        hatching = PoultryHatching.objects.filter(poultry=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    province_request__poultry_request__hatching=hatching)

        governmental_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=False)
        governmental_province_kill_requests_quantity = \
            governmental_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        free_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=True)

        free_province_kill_requests_quantity = \
            free_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        out_poultry_requests = PoultryRequest.objects.filter(trash=False, out=True, state_process='accepted',
                                                             province_state='accepted',
                                                             out_province_request_cancel=False, final_state='archive',
                                                             hatching=hatching)
        out_poultry_requests_quantity = out_poultry_requests.aggregate(total=Sum('quantity'))[
                                            'total'] or 0

        free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
        if free_sale_province.allow == False:
            left_total_free_commitment_quantity = hatching.left_over
        elif hatching.total_free_commitment_quantity == 0:
            left_total_free_commitment_quantity = 0
        else:
            if hatching.total_commitment_quantity == 0:
                left_total_free_commitment_quantity = hatching.left_over
            else:
                left_total_free_commitment_quantity = hatching.total_free_commitment_quantity - (
                        free_province_kill_requests_quantity + out_poultry_requests_quantity) if (
                                                                                                         hatching.total_free_commitment_quantity - (
                                                                                                         free_province_kill_requests_quantity + out_poultry_requests_quantity)) > 0 else 0

        return {
            "governmental_allocated_quantity": governmental_province_kill_requests_quantity,
            "total_commitment_quantity": hatching.total_commitment_quantity,
            "free_allocated_quantity": free_province_kill_requests_quantity + out_poultry_requests_quantity,
            "total_free_commitment_quantity": hatching.total_free_commitment_quantity,
            "left_total_free_commitment_quantity": left_total_free_commitment_quantity,

        }


class PoultryForPoultryHatchingSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(required=False)
    province_allow_choose_kill_house = serializers.SerializerMethodField('get_allow_choose_kill_house')
    last_hatching_remain_quantity = serializers.SerializerMethodField('get_last_hatching_remain_quantity')
    province_allow_sell_free = serializers.SerializerMethodField('get_allow_sell_free')
    hatching_age = serializers.SerializerMethodField('get_hatching_age')

    class Meta:
        model = Poultry
        fields = ['user', 'key', 'address', 'province_allow_choose_kill_house', 'unit_name',
                  'last_hatching_remain_quantity', 'province_allow_sell_free',
                  'hatching_age']

    def get_last_hatching_remain_quantity(self, obj):
        hatching = PoultryHatching.objects.filter(poultry__exact=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        remain = hatching.left_over if hatching else 0
        return remain

    def get_hatching_age(self, obj):
        hatching = PoultryHatching.objects.filter(poultry__exact=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).last()
        if hatching:
            date = datetime.strptime(str(hatching.date), '%Y-%m-%d %H:%M:%S')
            age = (datetime.now() - date).days + 1
            breed = hatching.chicken_breed
        else:
            age = None
            breed = None
        return {"age": age, "breed": breed}

    def get_allow_choose_kill_house(self, instance):
        allow_state = None
        mandatory = None
        province_allow = ProvinceAllowPoultryChooseKillHouse.objects.filter(poultry=instance).first()
        if province_allow:
            allow_state = province_allow.allow
            mandatory = province_allow.mandatory
        return {"allow_state": allow_state, "mandatory": mandatory}

    def get_allow_sell_free(self, instance):
        allow_state = None
        province_allow = ProvinceAllowPoultrySellFree.objects.filter(poultry=instance).first()
        if province_allow:
            allow_state = province_allow.allow
        return allow_state


# class PoultryForAllUserSerializer(serializers.ModelSerializer):
#     user_bank_info = BankCardSerializer(required=False)
#     address = SystemAddressSerializer(required=False)
#
#     class Meta:
#         model = Poultry
#         fields = ['breeding_unique_id', 'unit_name', 'address', 'number_of_halls', 'total_capacity',
#                   'user_bank_info', 'city_operator','active','identity_documents']


class VetForPoultrySerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = Vet
        fields = ['user']


class VetFarmForPoultrySerializer(serializers.ModelSerializer):
    vet = VetForPoultrySerializer(read_only=True)

    class Meta:
        model = VetFarm
        fields = ['vet']


class PoultryForAllUserSerializer(serializers.ModelSerializer):
    user_bank_info = BankCardSerializer(required=False)
    address = SystemAddressSerializer(required=False)
    tenants = serializers.SerializerMethodField('get_tenants')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')

    class Meta:
        model = Poultry

        fields = ['breeding_unique_id', 'unit_name', 'address', 'number_of_halls', 'total_capacity',
                  'user_bank_info', 'city_operator', 'active', 'identity_documents', 'tenants', 'vet_farm']

    def get_tenants(self, obj):
        owner_poultry = Poultry.objects.filter(owner__exact=obj)
        return PoultryForAllUserSerializer(owner_poultry, many=True).data

    def get_vet_farm(self, obj):
        vet_farm = VetFarm.objects.filter(poultry__exact=obj, trash=False)
        return VetFarmForPoultrySerializer(vet_farm, many=True).data


# سریالایزر مربوط به درخواست بورسی مرغدار
class PoultrySerializer(serializers.ModelSerializer):
    userprofile = serializers.SerializerMethodField('get_userprofile')
    address = SystemAddressSerializer(read_only=True)
    poultry_owner = serializers.SerializerMethodField('get_owner')
    poultry_tenant = serializers.SerializerMethodField('get_poultry_tenant')
    hatching = serializers.SerializerMethodField('get_hatching')
    register_vet_halls = serializers.SerializerMethodField('get_busy_halls')
    allow = serializers.SerializerMethodField('get_allow_city_province')
    province_allow_choose_kill_house = serializers.SerializerMethodField('get_allow_choose_kill_house')
    province_allow_sell_free = serializers.SerializerMethodField('get_allow_sell_free')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    last_hatching_diffrent_request_quantity = serializers.SerializerMethodField(
        'get_last_hatching_diffrent_request_quantity')
    user_bank_info = BankCardSerializer(required=False)
    left_over_own_hatching = serializers.SerializerMethodField('get_left_over_own_hatching')

    class Meta:
        model = Poultry
        exclude = (
            'user',
            'id',
            'create_date',
            'modify_date',
            # 'trash',
            'password',
            'created_by',
            'modified_by',
        )

    def get_userprofile(self, instance):
        user = SystemUserProfile.objects.get(id=instance.user.id, trash=False)
        internal_dictionary = {
            "user_key": user.key,
            "base_order": user.base_order,
            "full_name": user.fullname,
            "mobile": user.mobile,
            "city": user.city.name,
            "province": user.province.name,
            "breeding_unique_id": instance.breeding_unique_id,

        }

        return internal_dictionary

    def get_vet_farm(self, instance):
        internal_dictionary = {}
        vet_farm = VetFarm.objects.filter(poultry=instance, trash=False)
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()

            internal_dictionary = {
                "full_name": vet_farm.vet.user.fullname,
                "mobile": vet_farm.vet.user.mobile,
                "city": vet_farm.vet.user.city.name,
                "province": vet_farm.vet.user.province.name,

            }

        return internal_dictionary

    def get_allow_choose_kill_house(self, instance):
        allow_state = None
        mandatory = None
        province_allow = ProvinceAllowPoultryChooseKillHouse.objects.filter(poultry=instance).first()
        if province_allow:
            allow_state = province_allow.allow
            mandatory = province_allow.mandatory
        return {"allow_state": allow_state, "mandatory": mandatory}

    def get_allow_sell_free(self, instance):
        allow_state = None
        province_allow = ProvinceAllowPoultrySellFree.objects.filter(poultry=instance).first()
        if province_allow:
            allow_state = province_allow.allow
        return allow_state

    def get_allow_city_province(self, instance):
        internal_dictionary = {}
        allow = PoultryAllowCityProvince.objects.filter(poultry=instance, trash=False)
        if allow.count() > 0:
            allow = allow.last()
            internal_dictionary = {
                "city": allow.city,
                "province": allow.province,
            }

        return internal_dictionary

    def get_last_hatching_diffrent_request_quantity(self, obj):
        left_export_quantity = None
        left_poultry_out_province = None

        hatching = PoultryHatching.objects.filter(poultry=obj, state='pending', archive=False,
                                                  allow_hatching='pending', trash=False).order_by('left_over').last()
        if hatching:
            poultry_export = PoultryExport.objects.get(trash=False)
            if poultry_export.limitation_status == True:
                total_export = int(hatching.quantity * (poultry_export.limitation / 100))
                hatching_export_quantity = hatching.export_killed_quantity
                left_export_quantity = hatching.left_over if hatching.left_over <= (
                        total_export - hatching_export_quantity) else total_export - hatching_export_quantity

            poultry_out_province = PoultryOutProvinceRequest.objects.get(trash=False)
            if poultry_out_province.limitation_status == True:
                total_poultry_out_province = int(hatching.quantity * (poultry_out_province.limitation / 100))
                hatching_poultry_out_province_quantity = hatching.out_province_killed_quantity
                left_poultry_out_province = hatching.left_over if hatching.left_over <= (
                        total_poultry_out_province - hatching_poultry_out_province_quantity) else total_poultry_out_province - hatching_poultry_out_province_quantity
        remain = hatching.left_over if hatching else 0

        return {
            "left_export_quantity": left_export_quantity,
            "left_poultry_out_province": left_poultry_out_province,
            "last_hatching_remain_quantity": remain,
        }

    def get_busy_halls(self, instance):
        list1 = []
        vet_farms = VetFarm.objects.filter(poultry=instance, state='pending', trash=False)
        if vet_farms.count() > 0:
            for vet_farm in vet_farms:
                list1.append(vet_farm.hall)

        return list1

    def get_owner(self, instance):
        if instance.owner != None:
            owner = Poultry.objects.filter(id=instance.owner.id, trash=False)
            if owner.count() > 0:
                owner = owner.last()
                internal_dictionary = {
                    "full_name": owner.user.fullname,
                    "mobile": owner.user.mobile,
                    "unit_name": owner.unit_name,
                    "number_of_halls": owner.number_of_halls,
                    "breeding_unique_id": owner.breeding_unique_id,

                }
        else:
            internal_dictionary = {}

        return internal_dictionary

    def get_poultry_tenant(self, instance):
        tenant = Poultry.objects.filter(owner_id=instance.id, trash=False)
        if tenant.count() > 0:
            tenant = tenant.last()
            internal_dictionary = {
                "key": tenant.key,
                "first_name": tenant.user.first_name,
                "last_name": tenant.user.last_name,
                "full_name": tenant.user.first_name + " " + tenant.user.last_name,
                "mobile": tenant.user.mobile,
                "national_id": tenant.user.national_id,
                "breeding_unique_id": tenant.breeding_unique_id,
            }
        else:
            internal_dictionary = {}

        return internal_dictionary

    def get_hatching(self, instance):
        hatching_list = []
        for hatching in PoultryHatching.objects.filter(poultry=instance, trash=False):
            age = (datetime.now().date() - hatching.date.date()).days + 1
            internal_dictionary = {
                "poultry_key": hatching.poultry.key,
                "poultry_hatching_key": hatching.key,
                "poultry": hatching.poultry.unit_name,
                "quantity": hatching.quantity,
                "losses": hatching.losses,
                "left_over": hatching.left_over,
                "out_province_killed_quantity": hatching.out_province_killed_quantity,
                "export_killed_quantity": hatching.export_killed_quantity,
                "hall": hatching.hall,
                "date": hatching.date,
                "period": hatching.period,
                "state": hatching.state,
                "age": age,

            }
            hatching_list.append(internal_dictionary)

        return hatching_list

    def get_left_over_own_hatching(self, instance):
        hatching = PoultryHatching.objects.filter(state='pending', archive=False,
                                                  allow_hatching='pending', poultry=instance, trash=False).order_by(
            'chicken_age').first()
        if hatching:
            left_over = hatching.left_over
        else:
            left_over = None
        return left_over


class PoultryForPredictionSerializer(serializers.ModelSerializer):
    fullname = serializers.CharField(source='user.fullname')
    mobile = serializers.CharField(source='user.mobile')
    city = serializers.CharField(source='user.city.name')
    userprofile = serializers.SerializerMethodField('get_userprofile')


    class Meta:
        model = Poultry
        fields = ['key', 'fullname', 'mobile', 'city', 'unit_name', 'killing_ave_age', 'active_left_over',
                  'killing_ave_count', 'real_killing_ave_weight', 'real_killing_live_weight',
                  'real_killing_carcasses_weight', 'real_killing_loss_weight_percent','userprofile']

    def get_userprofile(self, instance):
        user = SystemUserProfile.objects.get(id=instance.user.id, trash=False)
        internal_dictionary = {
            "user_key": user.key,
            "base_order": user.base_order,
            "full_name": user.fullname,
            "mobile": user.mobile,
            "city": user.city.name,
            "province": user.province.name,
            "breeding_unique_id": instance.breeding_unique_id,

        }

        return internal_dictionary


class PoultryForDirectBuyingSerializer(serializers.ModelSerializer):
    fullname = serializers.CharField(source='user.fullname')
    mobile = serializers.CharField(source='user.mobile')
    province = serializers.CharField(source='user.province.name')
    city = serializers.CharField(source='user.city.name')

    class Meta:
        model = Poultry
        fields = ['key', 'fullname', 'mobile', 'province', 'city', 'unit_name']


# سریالایزر مربوط به مستاجر مرغدار
class PoultryTenantSerializer(serializers.ModelSerializer):
    poultry = PoultrySerializer(read_only=True)

    class Meta:
        model = PoultryTenant
        fields = '__all__'


class TotalPoultryRequestQuantitySerializer(serializers.ModelSerializer):
    class Meta:
        model = TotalPoultryRequestQuantity
        fields = '__all__'


# سریالایزر مربوط به درخواست بورسی مرغدار
class PoultryRequestExchangeSerializer(serializers.ModelSerializer):
    user = UserProfileSerializer(read_only=True)
    chicken_age = serializers.SerializerMethodField('age')

    class Meta:
        model = PoultryRequestExchange
        fields = '__all__'


# سریالایزر مربوط به ثبت جوجه ریزی مرغدار
class PoultryHatchingSerializer(serializers.ModelSerializer):
    poultry = PoultrySerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    age = serializers.SerializerMethodField('get_age')
    inspection_losses = serializers.SerializerMethodField('get_inspection')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    active_kill = serializers.SerializerMethodField('get_active_kill')
    killing_info = serializers.SerializerMethodField('get_killing_info')
    free_governmental_info = serializers.SerializerMethodField('get_free_governmental_info')
    management_hatching_age_range = serializers.SerializerMethodField('get_management_hatching_age_range')

    class Meta:
        model = PoultryHatching
        fields = '__all__'

    def get_management_hatching_age_range(self, obj):

        age_range = ManagementHatchingAgeRange.objects.filter(from_age__lte=obj.chicken_age,to_age__gte=obj.chicken_age).first()
        if age_range:
            return {
                'from_weight': age_range.from_weight,
                'to_weight':  age_range.to_weight,
            }
        else:
            return {
                'from_weight': 0,
                'to_weight': 5,
            }

    # تابع برای بدست آوردن سن مرع
    def get_age(self, instance):
        # date = datetime.strptime(str(instance.date), '%Y-%m-%d %H:%M:%S')
        # age = (datetime.now() - date).days + 1
        # hatching = PoultryHatching.objects.get(key=instance.key)
        # if hatching.archive == False and hatching.allow_hatching == 'pending':
        #     hatching.chicken_age = age
        #     hatching.save()
        return instance.chicken_age

    def get_inspection(self, instance):
        inspection = VetFarmInspection.objects.filter(poultry_hatching=instance)
        if inspection.count() > 0:
            inspections = 0
            for ins in inspection:
                if ins.Losses == 0:
                    pass
                else:
                    inspections += int(ins.Losses)
            return inspections

    def get_vet_farm(self, instance):
        vet = {
            "vet_farm_full_name": 'ندارد',
            "vet_farm_mobile": '',
        }
        vet_farm = VetFarm.objects.filter(poultry=instance.poultry)
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()
            vet = {
                "vet_farm_full_name": vet_farm.vet.user.fullname,
                "vet_farm_mobile": vet_farm.vet.user.mobile,
            }

        return vet

    def get_active_kill(self, instance):

        active_kill = False
        count_of_request = 0

        province_kill_request = ProvinceKillRequest.objects.filter(trash=False,
                                                                   province_request__poultry_request__hatching=instance,
                                                                   state='accepted')
        if province_kill_request.count() > 0:
            count_of_request = province_kill_request.count()

        if ProvinceKillRequest.objects.filter(trash=False, province_request__poultry_request__hatching=instance,
                                              state='pending').exists():
            active_kill = True
        info = {
            "active_kill": active_kill,
            "count_of_request": count_of_request,
        }

        return info

    def get_killing_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0,
                                                                    province_request__poultry_request__hatching=obj)
        province_kill_requests_quantity = \
            province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        province_kill_requests_weight = \
            province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0
        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=obj)
        first_quantity = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity') or 0
        first_weight = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        ware_house_bars = kill_house_requests.filter(ware_house_confirmation=True)
        ware_house_bars_quantity = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_quantity'))[
                                       'total'] or 0
        ware_house_bars_weight = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_weight'))[
                                     'total'] or 0

        ware_house_bars_weight_lose = ware_house_bars.aggregate(total=Sum('weight_loss'))[
                                          'total'] or 0
        bar_complete_with_kill_house = kill_house_requests.filter(
            assignment_state_archive='True')

        accepted_real_wight_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        accepted_real_quantity_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity', 0) or 0

        return {
            "violation_message": 'متخلف' + ' ' + '(مانده در سالن بیش از حد مجاز)' if obj.violation else 'عادی',
            "province_kill_requests": len(province_kill_requests),
            "province_kill_requests_quantity": province_kill_requests_quantity,
            "province_kill_requests_weight": province_kill_requests_weight,
            "kill_house_requests": len(kill_house_requests),
            "kill_house_requests_first_quantity": first_quantity,
            "kill_house_requests_first_weight": first_weight,
            "bar_complete_with_kill_house": len(bar_complete_with_kill_house),
            "accepted_real_quantity_final": accepted_real_quantity_final,
            "accepted_real_wight_final": accepted_real_wight_final,
            "ware_house_bars": len(ware_house_bars),
            "ware_house_bars_quantity": ware_house_bars_quantity,
            "ware_house_bars_weight": ware_house_bars_weight,
            'ware_house_bars_weight_lose': ware_house_bars_weight_lose / len(
                ware_house_bars) if ware_house_bars else 0,
        }

    def get_free_governmental_info(self, obj):
        left_total_free_commitment_quantity = 0
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    province_request__poultry_request__hatching=obj)

        governmental_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=False)
        governmental_province_kill_requests_quantity = \
            governmental_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        free_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=True)

        free_province_kill_requests_quantity = \
            free_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        out_poultry_requests = PoultryRequest.objects.filter(trash=False, out=True, state_process='accepted',
                                                             province_state='accepted',
                                                             out_province_request_cancel=False, final_state='archive',
                                                             hatching=obj)
        out_poultry_requests_quantity = out_poultry_requests.aggregate(total=Sum('quantity'))[
                                            'total'] or 0
        free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
        if free_sale_province.allow == False:
            left_total_free_commitment_quantity = obj.left_over

        elif obj.total_free_commitment_quantity == 0:
            left_total_free_commitment_quantity = 0
        else:
            if obj.total_commitment_quantity == 0:
                left_total_free_commitment_quantity = obj.left_over
            else:
                left_total_free_commitment_quantity = obj.total_free_commitment_quantity - (
                        free_province_kill_requests_quantity + out_poultry_requests_quantity) if (
                                                                                                         obj.total_free_commitment_quantity - (
                                                                                                         free_province_kill_requests_quantity + out_poultry_requests_quantity)) > 0 else 0

        return {
            "governmental_allocated_quantity": governmental_province_kill_requests_quantity,
            "total_commitment_quantity": obj.total_commitment_quantity,
            "free_allocated_quantity": free_province_kill_requests_quantity + out_poultry_requests_quantity,
            "total_free_commitment_quantity": obj.total_free_commitment_quantity,
            "left_total_free_commitment_quantity": left_total_free_commitment_quantity,

        }


class PoultryHatchingForPredictionSerializer(serializers.ModelSerializer):
    poultry = PoultryForPredictionSerializer(read_only=True)
    general_info = serializers.SerializerMethodField('get_general_info')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')


    class Meta:
        model = PoultryHatching
        fields = ['poultry', 'general_info', 'chicken_breed', 'date', 'quantity', 'left_over', 'period','chicken_age',
                  'losses','violation','vet_farm','licence_number']

    def get_general_info(self, obj):
        now_age = (datetime.now().date() - obj.date.date()).days + 1
        sum_age = 0
        ave_age = 0
        ave_weight = 0
        counter = 0
        poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
                                                         province_state__in=('pending', 'accepted'),
                                                         out_province_request_cancel=False,
                                                         hatching=obj)
        for poultry_request in poultry_requests:
            sum_age += (poultry_request.send_date.date() - obj.date.date()).days + 1
            counter += 1
        ave_age = int(sum_age / counter) if counter > 0 else 0

        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, state__in=('pending', 'accepted'),
                                                                    province_request__poultry_request__hatching=obj,
                                                                    first_car_allocated_quantity=0,
                                                                    return_to_province=False)

        province_kill_requests_quantity = \
            province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0

        province_kill_requests_weight = \
            province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0
        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=obj)

        kill_house_requests_quantity = kill_house_requests.aggregate(total=Sum('accepted_real_quantity'))['total'] or 0
        kill_house__requests_weight = kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0

        total_quantity = province_kill_requests_quantity + kill_house_requests_quantity
        total_weight = province_kill_requests_weight + kill_house__requests_weight

        ave_weight = round(total_weight / total_quantity, 2) if total_quantity > 0 else 0

        return {
            "ave_age": ave_age,
            "age": now_age,
            "ave_weight": ave_weight,
            "province_kill_requests": len(province_kill_requests),
            "province_kill_requests_quantity": province_kill_requests_quantity,
            "province_kill_requests_weight": province_kill_requests_weight,
            "kill_house_requests_quantity": kill_house_requests_quantity,
            "kill_house_requests": len(kill_house_requests),
            "kill_house__requests_weight": kill_house__requests_weight,
            "total_quantity": total_quantity,
            "total_weight": total_weight
        }

    def get_vet_farm(self, obj):

        vet_farm = VetFarm.objects.filter(poultry=obj.poultry, trash=False).first()
        vet_farm_fullname = vet_farm.vet.user.fullname if vet_farm else None
        vet_farm_mobile = vet_farm.vet.user.mobile if vet_farm else None

        return {
            "vet_farm_fullname": vet_farm_fullname,
            "vet_farm_mobile": vet_farm_mobile,
        }


class PoultryRequestForAutoAllocationSerializer(serializers.ModelSerializer):
    # user = SystemUserProfileSerializer(read_only=True)
    poultry = PoultryForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = PoultryRequest
        fields = ['poultry', 'payer_fullname']


class PoultryRequestForOutRequestTransactionsSerializer(serializers.ModelSerializer):
    poultry = PoultryForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = PoultryRequest
        fields = ['poultry', 'order_code']


class PoultryRequestForMarketSerializer(serializers.ModelSerializer):

    class Meta:
        model = PoultryRequest
        fields = ['killing_age']


class PoultryHatchingForChainAllocationSerializer(serializers.ModelSerializer):
    poultry = PoultryForPoultryRequestLetterSerializer(read_only=True)

    class Meta:
        model = PoultryHatching
        fields = '__all__'


class PoultryHatchingForBarDifferenceRequestSerializer(serializers.ModelSerializer):
    poultry = PoultryForBarDifferenceRequestSerializer(read_only=True)

    class Meta:
        model = PoultryHatching
        fields = ['key', 'poultry', 'quantity', 'left_over', 'chicken_age', 'now_age']


class ChainAllocationForWageSerializer(serializers.ModelSerializer):
    poultry_hatching = PoultryHatchingForChainAllocationSerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    total_wage_amount = serializers.SerializerMethodField('get_total_wage_amount')

    class Meta:
        model = ChainAllocation
        fields = '__all__'

    def get_total_wage_amount(self, obj):
        role = self.context.get('request').GET['role']

        if role in ['SuperAdmin', 'ChainCompany', 'AdminX', 'Supporter']:
            amount = obj.total_wage_amount
        elif role == 'ProvinceOperator':
            amount = obj.union_share

        elif role == 'Guilds':
            amount = obj.guilds_share
        elif role == 'Company':
            amount = obj.company_share
        else:
            amount = obj.total_wage_amount

        return amount


class KillHouseOperatorForChainAllocationsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = KillHouseOperator
        fields = ['user']


class KillHouseForChainAllocationSerializer(serializers.ModelSerializer):
    kill_house_operator = KillHouseOperatorForChainAllocationsSerializer(read_only=True)

    class Meta:
        model = KillHouse
        fields = ['kill_house_operator', 'name', 'killer', 'key']


class ChainAllocationSerializer(serializers.ModelSerializer):
    poultry_hatching = PoultryHatchingForChainAllocationSerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    kill_house = KillHouseForChainAllocationSerializer(read_only=True)

    class Meta:
        model = ChainAllocation
        fields = '__all__'


class ChainCompanyTransactionSerializer(serializers.ModelSerializer):
    chain_company = ChainCompanySerializer(read_only=True)

    class Meta:
        model = ChainCompanyTransaction
        fields = '__all__'


class PoultryRequestForKillingInformationSerializer(serializers.ModelSerializer):
    poultry = PoultryForBarManagementSerializer(read_only=True)
    hatching = serializers.SerializerMethodField('get_hatching')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    city_check_request = serializers.SerializerMethodField('get_city_check_request')

    class Meta:
        model = PoultryRequest
        fields = ['key', 'id', 'poultry', 'order_code', 'create_date', 'send_date', 'kill_house_list', 'first_quantity',
                  'quantity', 'direct_buying', 'union', 'amount', 'financial_operation',
                  'remain_quantity', 'Index_weight', 'hatching', 'final_state', 'losses', 'province_state',
                  'state_process', 'registrar', 'vet_farm', 'free_sale_in_province', 'freezing', 'export',
                  'city_check_request','market','killing_age']

    def get_hatching(self, obj):
        file_state = 'pending'
        if obj.province_state == 'pending':
            file_state = 'province_state_pending'

        elif obj.price_confirmation and not obj.input_price_confirmation_code:
            file_state = 'confirmation_code_pending'

        else:
            file_state = 'allocated_pending'
        hatching = PoultryHatching.objects.filter(Q(trash=False) | Q(trash=True), key=obj.hatching.key).first()
        inspections = VetFarmInspection.objects.filter(poultry_hatching=hatching, trash=False)
        losses = 0
        if inspections:
            losses = inspections.aggregate(total_quantity=Sum('Losses')).get('total_quantity', 0)
        inspection_losses = (losses * 100) / obj.hatching.quantity if losses > 0 else 0

        if ProvinceKillRequest.objects.filter(
                province_request__city_request_Poultry__poultry_request=obj,
                state='accepted').exists():
            if obj.remain_quantity == 0:
                file_state = 'allocated_completed'
            age2 = (obj.send_date - hatching.date).days + 1
        else:
            age2 = (datetime.now() - hatching.date).days + 1

        return {
            "age": age2,
            "left_over": hatching.left_over,
            "file_state": file_state,
            "hatching_date": hatching.date,
            "allow_hatching": hatching.allow_hatching,
            "inspection_losses": losses,
            "inspection_losses_percent": inspection_losses,
            "total_losses_percent": (hatching.losses * 100) / hatching.quantity,
            "poultry_losses_percent": (int(obj.losses) * 100) / hatching.quantity,
            "total_weight": obj.Index_weight * obj.quantity
        }

    def get_vet_farm(self, obj):

        vet_farm = VetFarm.objects.filter(poultry=obj.poultry, trash=False).first()
        vet_farm_fullname = vet_farm.vet.user.fullname if vet_farm else None
        vet_farm_mobile = vet_farm.vet.user.mobile if vet_farm else None

        return {
            "vet_farm_fullname": vet_farm_fullname,
            "vet_farm_mobile": vet_farm_mobile,
        }

    def get_city_check_request(self, obj):
        try:
            city_check = CityOperatorCheckRequest.objects.get(trash=False, poultry_request=obj)
            return city_check.key
        except:
            return None


class PoultryRequestForBarMangementSerializer(serializers.ModelSerializer):
    poultry = PoultryForBarManagementSerializer(read_only=True)
    age = serializers.SerializerMethodField('get_age')

    class Meta:
        model = PoultryRequest
        fields = ['key', 'poultry', 'send_date', 'age', 'amount', 'financial_operation', 'chicken_breed', 'order_code',
                  'freezing', 'export', 'direct_buying', 'free_sale_in_province']

    def get_age(self, obj):
        age = (obj.send_date.date() - obj.hatching.date.date()).days + 1
        return age


class PoultryRequestForGeneralCasestatusSerializer(serializers.ModelSerializer):
    poultry = PoultryForBarManagementSerializer(read_only=True)
    other_informations = serializers.SerializerMethodField('get_other_informations')

    class Meta:
        model = PoultryRequest
        fields = ['key', 'id', 'poultry', 'send_date', 'amount', 'financial_operation', 'quantity', 'Index_weight',
                  'order_code', 'province_state',
                  'state_process',
                  'other_informations', 'final_state', 'out', 'free_sale_in_province']

    def get_other_informations(self, obj):
        vet_farm_name = None
        vet_farm_mobile = None
        vet_farm = VetFarm.objects.filter(poultry=obj.poultry, trash=False).select_related(
            'vet__user').only('vet__user__mobile', 'vet__user__fullname').last()
        if vet_farm:
            vet_farm_name = vet_farm.vet.user.fullname
            vet_farm_mobile = vet_farm.vet.user.mobile

        return {
            "vet_farm_name": vet_farm_name,
            "vet_farm_mobile": vet_farm_mobile,
            "province_kill_request_state": ProvinceKillRequest.objects.filter(trash=False,
                                                                              province_request__poultry_request=obj).exists(),
            "kill_house_state": KillHouseCheckRequest.objects.filter(trash=False,
                                                                     province_kill_request__province_request__poultry_request=obj).exists(),
            "kill_house_request_state": KillHouseRequest.objects.filter(trash=False,
                                                                        province_request__poultry_request=obj).exists(),
            "receive_bar_state": VetCheckRequest.objects.filter(trash=False,
                                                                kill_house_request__province_request__poultry_request=obj).exists(),
            "bar_state": KillHouseAssignmentInformation.objects.filter(trash=False,
                                                                       kill_house_request__province_request__poultry_request=obj).exists(),
            "province_factor_state": ProvinceFactorToKillHouse.objects.filter(
                province_check_info__kill_house_assignment__kill_house_request__province_request__poultry_request=obj,
                trash=False).exists(),
            "kill_house_factor_state": KillHouseFactorToProvince.objects.filter(
                province_factor__province_check_info__kill_house_assignment__kill_house_request__province_request__poultry_request=obj,
                trash=False, state='accepted').exists(),
            "inspector_state": PovinceInspector.objects.filter(poultry_request=obj,
                                                               trash=False).exists(),
        }


# سریالایزر مربوط به درخواست  مرغدار
class PoultryRequestSerializer(serializers.ModelSerializer):
    # user = SystemUserProfileSerializer(read_only=True)
    poultry = PoultrySerializer(read_only=True)
    hatching = PoultryHatchingSerializer(read_only=True)
    process = serializers.SerializerMethodField('get_process')

    class Meta:
        model = PoultryRequest
        fields = '__all__'
        # fields = ['id', 'poultry', 'hatching']

    # تایع برای نمایش ریز جزییات مزبوط به پرونده مرغدار برای پنل های استان
    def get_process(self, instance):
        process = {}

        if ProvinceKillRequest.objects.filter(
                province_request__city_request_Poultry__poultry_request=instance,
                state='accepted').exists():
            age2 = (instance.send_date - instance.hatching.date).days + 1
        else:
            age2 = (datetime.now() - instance.hatching.date).days + 1

        file_state = 'pending'
        if instance.province_state == 'pending':
            file_state = 'province_state_pending'

        if ProvinceKillRequest.objects.filter(province_request__poultry_request__id=instance.id).exists():
            if instance.remain_quantity == 0:
                file_state = 'allocated_completed'


        else:
            file_state = 'allocated_pending'

        process.update({"file_state": file_state})

        process.update({"poultry": {
            "poultry_unit_name": instance.poultry.unit_name,
            "breeding_unique_id": instance.poultry.breeding_unique_id,
            "halls": instance.poultry.number_of_halls,
            "tenant": instance.poultry.tenant,
            "has_tenant": instance.poultry.has_tenant,
            "poultry_request_id": instance.id,
            "base_order": instance.poultry.user.base_order,

            "awaiting_payment": instance.awaiting_payment,
            "poultry_request_key": instance.key,
            "general_order_code": instance.general_order_code,
            "kill_house_list": instance.kill_house_list,
            "poultry_request_final_state": instance.final_state,
            "poultry_order_code": instance.order_code,
            "poultry_send_date": instance.send_date,
            "poultry_name": instance.poultry.user.fullname,
            "poultry_mobile": instance.poultry.user.mobile,
            "poultry_city": instance.poultry.address.city.name,
            "poultry_province": instance.poultry.address.province.name,
            "poultry_address": instance.poultry.address.address,
            "national_id": instance.poultry.user.national_id,
            "poultry_gis_code": instance.poultry.gis_code,
            'age': age2,
            'chicken_date': None,
            "poultry_quantity": instance.quantity,
            "poultry_remain_quantity": instance.remain_quantity,
            "poultry_previous_quantity": instance.previous_quantity,
            "poultry_first_quantity": instance.first_quantity,
            "poultry_chicken_breed": instance.chicken_breed,
            "poultry_request_losses": instance.losses,
            "poultry_Index_weight": "{} کیلوگرم".format(instance.Index_weight),
            "Index_weight": instance.Index_weight,
            "total_weight": instance.Index_weight * instance.quantity,
            "poultry_register_date": instance.create_date,
            "poultry_auction": instance.auction,
            "sell_type": instance.cell_type,
            "buyer": instance.buyer,
            "quarantine_code": instance.quarantine_code,

        }
        })
        poultry_hatching = PoultryHatching.objects.filter(key=instance.hatching.key, trash=False)
        if poultry_hatching.count() > 0:
            poultry_hatching = poultry_hatching.last()
            inspections = VetFarmInspection.objects.filter(poultry_hatching=poultry_hatching)
            losses = 0
            if inspections.count() > 0:
                for ins in inspections:
                    if ins.Losses > 0:
                        losses += ins.Losses
                    else:
                        pass

                if losses > 0:
                    process.update({"inspection_losses": losses
                                    })
                    process.update({
                        "inspection_losses_percent": (losses * 100) / instance.hatching.quantity
                    })
            else:
                process.update({"inspection_losses": losses
                                })
                process.update({
                    "inspection_losses_percent": losses
                })

            process.update({"poultry_hatching": {
                "poultry_key": instance.poultry.key,
                "poultry_hatching_key": instance.hatching.key,
                "poultry_name": instance.poultry.unit_name,
                "quantity": instance.hatching.quantity,
                "losses": instance.hatching.losses,
                "total_losses_percent": (instance.hatching.losses * 100) / instance.hatching.quantity,
                "poultry_losses_percent": (int(instance.losses) * 100) / instance.hatching.quantity,
                "left_over": instance.hatching.left_over,
                "hall": instance.hatching.hall,
                "date": instance.hatching.date,
                "allow_hatching": instance.hatching.allow_hatching,
                "period": instance.hatching.period,
                "state": instance.hatching.state,
            }
            })
        else:
            process.update({"poultry_hatching": None
                            })

        vetfarm_inspection = VetFarmInspection.objects.filter(vet_farm__poultry=instance.poultry, trash=False)
        if vetfarm_inspection.count() > 0:
            vetfarm_inspection = vetfarm_inspection.last()
            process.update({"vetfarm_inspection": {
                "vet_name": vetfarm_inspection.vet_farm.vet.user.fullname,
                "hall": vetfarm_inspection.hall,
                "topic": vetfarm_inspection.topic,
                "description": vetfarm_inspection.description,
                "image": vetfarm_inspection.image,
                "losses": vetfarm_inspection.Losses,
                "longitude": vetfarm_inspection.longitude,
                "latitude": vetfarm_inspection.latitude,
            }
            })
        else:
            process.update({"vetfarm_inspection": None
                            })

        auctions = PoultryRequestAuction.objects.filter(poultry_request=instance, state='active', trash=False).order_by(
            'auction_date')
        if auctions.count() > 0:
            auctions_list = []
            for auction in auctions:
                if auction.state == 'active':
                    index = list(auctions).index(auction) + 1
                    pricing = Pricing.objects.get(id=auction.pricing.id, trash=False)
                    internal_dict_auction = {
                        "ceiling_price": pricing.ceiling_price,
                        "floor_price": pricing.floor_price,
                        "fee": auction.fee,
                        "hour": auction.hour,
                        "date": auction.auction_date,
                        "index": index,
                        "total_index": auctions.count()
                    }
                    auctions_list.append(internal_dict_auction)
                    process.update({"auctions_list": auctions_list})
                # else:
                #     break
            # process['poultry'].update({"auctions_list":auctions_list})
            process.update({"auctions_list": auctions_list})
        else:
            process.update({"auctions_list": None})
        kill_house_auctions = KillHouseRequestAction.objects.filter(poultry_request=instance, state='pending',
                                                                    trash=False)
        if kill_house_auctions.count() > 0:
            kill_house_auctions_list = []
            for kill_house_auction in kill_house_auctions:
                internal_dict_kill_house_auction = {
                    "kill_house_name": kill_house_auction.kill_house.name,
                    "fullname": kill_house_auction.kill_house.kill_house_operator.user.fullname,
                    "mobile": kill_house_auction.kill_house.kill_house_operator.user.mobile,
                    "city": kill_house_auction.kill_house.system_address.city.name,
                    "province": kill_house_auction.kill_house.system_address.province.name,
                    "fee": kill_house_auction.fee,
                }
                kill_house_auctions_list.append(internal_dict_kill_house_auction)
                process.update({"kill_house_auctions_list": kill_house_auctions_list})
        else:
            process.update({"kill_house_auctions_list": None})
        kill_house_auction_winner = KillHouseRequestActionWinner.objects.filter(
            kill_house_request_auction__poultry_request=instance, trash=False)
        if kill_house_auction_winner.count() > 0:
            kill_house_auction_winner = kill_house_auction_winner.last()
            process.update({"kill_house_winner": {
                "kill_house_winner_key": kill_house_auction_winner.key,
                "kill_house_name": kill_house_auction_winner.kill_house_request_auction.kill_house.name,
                "kill_house_user_name": kill_house_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.fullname,
                "kill_house_user_mobile": kill_house_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.mobile,
                "kill_house_city": kill_house_auction_winner.kill_house_request_auction.kill_house.system_address.city.name,
                "kill_house_province": kill_house_auction_winner.kill_house_request_auction.kill_house.system_address.province.name,
                "fee": kill_house_auction_winner.fee,
                "quantity": kill_house_auction_winner.quantity
            }
            })
        else:
            process.update({"kill_house_winner": None
                            })

        province_request_auctions = ProvinceRequestAction.objects.filter(poultry_request=instance, state='active',
                                                                         trash=False)
        if province_request_auctions.count() > 0:
            province_request_auction_list = []
            for province_request_auction in province_request_auctions:
                internal_dict_province_request_auction_list = {
                    "fullname": province_request_auction.province_operator_system.user.fullname,
                    "mobile": province_request_auction.province_operator_system.user.mobile,
                    "city": province_request_auction.province_operator_system.user.city.name,
                    "province": province_request_auction.province_operator_system.user.province.name,
                }
                province_request_auction_list.append(internal_dict_province_request_auction_list)
                process.update({"province_request_auction_list": province_request_auction_list})
        else:
            process.update({"province_request_auction_list": None})

        poultry_assignment = PoultryAssignmentInformation.objects.filter(poultry_request=instance, trash=False)

        if poultry_assignment.count() > 0:
            poultry_bar_list = []
            for bar in poultry_assignment:
                internal_poultry_bar = {
                    "poultry_bar_info_key": bar.key,
                    "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,
                }
                poultry_bar_list.append(internal_poultry_bar)

            process.update({"poultry_bar_info": poultry_bar_list})
        if not poultry_assignment:
            process.update({"poultry_bar_info": None})

        city = CityOperatorCheckRequest.objects.filter(poultry_request=instance, trash=False)
        if city:
            process.update({"city": {
                "city_operator_name": city[0].city_operator_system.user.fullname,
                "city_operator_mobile": city[0].city_operator_system.user.mobile,
                "city_operator_province": city[0].city_operator_system.address.province.name,
                "city_operator_city": city[0].city_operator_system.address.city.name,
                "city_operator_address": city[0].city_operator_system.address.address,
                "city_operator_national_id": city[0].city_operator_system.user.national_id,
                "city_state": city[0].state,
                "province_accept": city[0].province_accept,
                "accepted_rejected_date": city[0].create_date,
                "city_operator_message": city[0].message,
                "unit_name": city[0].city_operator_system.unit_name,

            }})
        if not city:
            process.update({"city": None})
        # cit = CityUnit.objects.filter(name=instance.poultry.address.city.name, trash=False)
        # if cit.count() > 0:
        #     city_operator = CityOperator.objects.get(address__city=cit[0].city, trash=False)
        city_operator = CityOperator.objects.get(key=instance.city_operator.key, trash=False)

        process.update({"city_operator": {
            "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,
            "city_operator_address": city_operator.address.address,
            "city_operator_national_id": city_operator.user.national_id,
            "unit_name": city_operator.unit_name,

        }})

        province = ProvinceCheckOperatorRequest.objects.filter(poultry_request=instance,
                                                               trash=False)
        if province:
            process.update({"province": {
                "province_check_request_key": province[0].key,
                "province_operator_name": province[0].province_operator_system.user.fullname,
                "province_operator_mobile": province[0].province_operator_system.user.mobile,
                "province_operator_provinc": province[0].province_operator_system.address.province.name,
                "province_operator_city": province[0].province_operator_system.address.city.name,
                "province_operator_address": province[0].province_operator_system.address.address,
                "province_operator_national_id": province[0].province_operator_system.user.national_id,
                "province_state": province[0].state,
                "chicken_price": province[0].fee,
                "province_message": province[0].message,
                "accepted_rejected_date": province[0].create_date,
            }})
        if not province:
            process.update({"province": None})
        role = Group.objects.get(name='ProvinceOperator')
        province_operator = ProvinceOperator.objects.get(address__province__name=instance.poultry.address.province.name,
                                                         user__role=role, trash=False)
        process.update({"province_operator": {
            "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,
            "province_operator_address": province_operator.address.address,
            "province_operator_national_id": province_operator.user.national_id,
        }})

        if ProvinceFactorToKillHouseForPoultry.objects.filter(province_check_req=province.last()).exists():
            poultry_factor = ProvinceFactorToKillHouseForPoultry.objects.filter(
                province_check_req=province.last()).last()
            if poultry_factor.bank != None:
                name_of_bank_user_poultry = poultry_factor.bank.name_of_bank_user
                bank_name_poultry = poultry_factor.bank.bank_name
                card_poultry = poultry_factor.bank.card
                shaba_poultry = poultry_factor.bank.shaba
                account_poultry = poultry_factor.bank.account
            else:
                name_of_bank_user_poultry = None
                bank_name_poultry = None
                card_poultry = None
                shaba_poultry = None
                account_poultry = None
            process.update({"poultry_factor": {
                "poultry_factor_key": poultry_factor.key,
                "province_factor_fee": poultry_factor.factor_fee,
                "province_operator": poultry_factor.province_check_req.province_operator_system.user.fullname,
                "province_mobile": poultry_factor.province_check_req.province_operator_system.user.mobile,
                "weight": poultry_factor.total_weight,
                "cost": poultry_factor.total_price,
                "poultry_share_with_profit": poultry_factor.shares,
                "total_amount_char": words(poultry_factor.total_price) + " " + "ریال",
                "name_of_bank_user": name_of_bank_user_poultry,
                "bank_name": bank_name_poultry,
                "card": card_poultry,
                "shaba": shaba_poultry,
                "account": account_poultry,
            }})
        else:
            process.update({"poultry_factor": None})

        if ProvinceFactorToKillHouse.objects.filter(province_check_req=province.last()).exists():
            province_factor = ProvinceFactorToKillHouse.objects.filter(province_check_req=province.last()).last()
            if province_factor.bank != None:
                name_of_bank_user_province_factor = province_factor.bank.name_of_bank_user
                bank_name_province_factor = province_factor.bank.bank_name
                card_province_factor = province_factor.bank.card
                shaba_province_factor = province_factor.bank.shaba
                account_province_factor = province_factor.bank.account
            else:
                name_of_bank_user_province_factor = None
                bank_name_province_factor = None
                card_province_factor = None
                shaba_province_factor = None
                account_province_factor = None

            process.update({"province_factor": {
                "province_factor_key": province_factor.key,
                "province_factor_fee": province_factor.factor_fee,
                "province_operator": province_factor.province_check_req.province_operator_system.user.fullname,
                "province_mobile": province_factor.province_check_req.province_operator_system.user.mobile,
                "weight": province_factor.total_weight,
                "cost": province_factor.total_price,
                "union_share_with_profit": province_factor.shares,
                "total_amount_char": words(province_factor.total_price) + " " + "ریال",
                "name_of_bank_user": name_of_bank_user_province_factor,
                "bank_name": bank_name_province_factor,
                "card": card_province_factor,
                "shaba": shaba_province_factor,
                "account": account_province_factor,
            }})
        else:
            process.update({"province_factor": None})

        if ProvinceImportKillHouseOutFactors.objects.filter(province_check=province.last()).exists():
            payment_out_factors = ProvinceImportKillHouseOutFactors.objects.filter(province_check=province.last())
            interal_factor_list = []
            for payment_out_factor in payment_out_factors:
                internal_dict = {
                    "key": payment_out_factor.key,
                    "amount": payment_out_factor.amount,
                    "image": payment_out_factor.image,
                }
                interal_factor_list.append(internal_dict)
            process.update({"out_factors": interal_factor_list})
        else:
            process.update({"out_factors": None})

        province_kill_reqs = ProvinceKillRequest.objects.filter(
            province_request__city_request_Poultry__poultry_request=instance, trash=False)

        if province_kill_reqs.count() > 0:
            state_list = []
            for province_kill_req in province_kill_reqs:
                state_list.append(province_kill_req.payment_type)
            l1 = set(state_list)
            if len(l1) > 1:
                process.update({"file_payment_type": "cash_credit"})
            else:
                process.update({"file_payment_type": state_list[0]})

            province_kill_reqs_list = []
            for province_kill_req in province_kill_reqs:
                internal_province_kill_dict_infos = {
                    "province_kill_req_key": province_kill_req.key,
                    "payment_type": province_kill_req.payment_type,
                    "payment_dead_line": province_kill_req.payment_dead_line,
                    "kill_req_key": province_kill_req.kill_request.key,
                    "province_kill_req_state": province_kill_req.state,
                    "kill_house_name": province_kill_req.kill_request.kill_house.name,
                    "kill_house_user_name": province_kill_req.kill_request.kill_house.kill_house_operator.user.fullname,
                    "kill_house_user_city": province_kill_req.kill_request.kill_house.kill_house_operator.user.city.name,
                    "kill_house_mobile": province_kill_req.kill_request.kill_house.kill_house_operator.user.mobile,
                    "kill_house_user_province": province_kill_req.kill_request.kill_house.kill_house_operator.user.province.name,
                    "kill_house_user_national_id": province_kill_req.kill_request.kill_house.kill_house_operator.user.national_id,
                    "quantity": province_kill_req.quantity,
                    "time": province_kill_req.kill_request.recive_time,
                    "date": province_kill_req.kill_request.recive_date,
                    "automatic_state": province_kill_req.automatic,
                    "fee": province_kill_req.fee,
                    "province_kill_req_message": province_kill_req.message
                }

                kill_house_requests = KillHouseRequest.objects.filter(
                    province_request__city_request_Poultry__poultry_request=instance,
                    province_kill_request=province_kill_req, trash=False)
                if kill_house_requests.count() > 0:
                    reqs = []
                    for kill_house_request in kill_house_requests:
                        province_req = kill_house_request.province_request
                        internal_dict_infos = {
                            "kill_house_req_key": kill_house_request.key,
                            "payment_type": province_kill_req.payment_type,
                            "payment_dead_line": province_kill_req.payment_dead_line,
                            "province_fee": province_kill_req.fee,
                            "kill_house_vet_state": kill_house_request.vet_state,
                            "kill_req_key": kill_house_request.kill_request.key,
                            "barcod": kill_house_request.bar_code,
                            "kill_house_state": kill_house_request.state,
                            "kill_house_name": kill_house_request.kill_request.kill_house.name,
                            "kill_house_user_name": kill_house_request.kill_request.kill_house.kill_house_operator.user.fullname,
                            "kill_house_user_province": kill_house_request.kill_request.kill_house.kill_house_operator.user.province.name,
                            "kill_house_user_city": kill_house_request.kill_request.kill_house.kill_house_operator.user.city.name,
                            "kill_house_user_address": kill_house_request.kill_request.kill_house.system_address.address,
                            "kill_house_mobile": kill_house_request.kill_request.kill_house.kill_house_operator.user.mobile,
                            "kill_house_national_id": kill_house_request.kill_request.kill_house.kill_house_operator.user.national_id,
                            "quantity": kill_house_request.quantity,
                            "fee": kill_house_request.province_kill_request.fee,
                            "time": kill_house_request.kill_request.recive_time,
                            "date": kill_house_request.kill_request.recive_date,
                            "cars": kill_house_request.car,
                            "driver_name": kill_house_request.add_car.driver.driver_name,
                            "capocity": kill_house_request.add_car.driver.capocity,
                            "type_car": kill_house_request.add_car.driver.type_car,
                            "pelak": kill_house_request.add_car.driver.pelak,
                            "clearance_code": kill_house_request.clearance_code,
                            "traffic_code": kill_house_request.traffic_code,
                            "show_kill_house": kill_house_request.show_kill_house,
                            "kill_house_message": kill_house_request.kill_house_message
                        }

                        vet_check = VetCheckRequest.objects.filter(kill_house_request=kill_house_request, trash=False)
                        if vet_check:
                            internal_dict_infos.update({
                                "vet_check_info": {
                                    "vet_user": vet_check[0].kill_house_vet.vet.user.fullname,
                                    "vet_user_mobile": vet_check[0].kill_house_vet.vet.user.mobile,
                                    "vet_check_state": vet_check[0].state,
                                    "vet_check_accept_date": vet_check[0].create_date,
                                }
                            })
                        if not vet_check:
                            internal_dict_infos.update({
                                "vet_check_info": None
                            })
                        kill_house_assignment = KillHouseAssignmentInformation.objects.filter(
                            kill_house_check__province_kill_request__province_request=province_req,
                            kill_house_request=kill_house_request, trash=False)
                        if kill_house_assignment:
                            internal_dict_infos.update({
                                "bar_info": {
                                    "kill_house_assignment_key": kill_house_assignment[0].key,
                                    "real_quantity": kill_house_assignment[0].real_quantity,
                                    "kill_house_weight_without_load": kill_house_assignment[0].car_weight_without_load,
                                    "kill_house_weight_with_load": kill_house_assignment[0].car_weight_with_load,
                                    "kill_house_image_without_load": kill_house_assignment[
                                        0].car_weight_without_load_image,
                                    "kill_house_image_with_load": kill_house_assignment[0].car_weight_with_load_image,
                                    "kill_house_net_weight": kill_house_assignment[0].net_weight,
                                    "expire_time": kill_house_assignment[0].protest_time,
                                    "kill_house_assignment_state": kill_house_assignment[0].state,
                                    "kill_house_assignment_message": kill_house_assignment[0].message,
                                    "accept_reject_date": kill_house_assignment[0].modify_date,
                                    "unusual_casualties": kill_house_assignment[0].unusual_casualties,

                                }
                            })
                            complaint = KillHouseComplaint.objects.filter(bar=kill_house_assignment[0], trash=False)
                            percentage_losses = PercentageOfLosses.objects.all()
                            if percentage_losses.count() > 0:
                                percentage_losses = percentage_losses.last().percent
                            else:
                                percentage_losses = None

                            if complaint.count() > 0:
                                complaint = complaint.last()
                                check_complaint = CheckUnusualCasualties.objects.filter(complaint=complaint)
                                if check_complaint.count() > 0:
                                    reviewer = check_complaint.last().role
                                else:
                                    reviewer = None
                                internal_dict_infos.update({
                                    "complaint": {
                                        "complaint_key": complaint.key,
                                        "create_date": complaint.create_date,
                                        "title": complaint.title,
                                        "description": complaint.description,
                                        "percent": complaint.percent,
                                        "image": complaint.image,
                                        "state": complaint.state,
                                        "message": complaint.message,
                                        "registrar": complaint.registrar,
                                        "reviewer": reviewer,
                                        "real_weight": kill_house_assignment[0].net_weight,
                                        "losses_weight": kill_house_assignment[0].weight_withs_losses,
                                        "percentage_losses": percentage_losses,
                                    }
                                })
                            else:
                                internal_dict_infos.update({
                                    "complaint": None
                                })
                        if not kill_house_assignment:
                            internal_dict_infos.update({
                                "bar_info": None
                            })
                            internal_dict_infos.update({
                                "complaint": None
                            })

                        poultry_factor = ProvinceFactorToKillHouseForPoultry.objects.filter(
                            province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                            trash=False)
                        if poultry_factor.count() > 0:
                            poultry_factor = poultry_factor.last()
                            if poultry_factor.bank != None:
                                name_of_bank_user = poultry_factor.bank.name_of_bank_user
                                bank_name = poultry_factor.bank.bank_name
                                card = poultry_factor.bank.card,
                                shaba = poultry_factor.bank.shaba,
                                account = poultry_factor.bank.account,
                            else:
                                name_of_bank_user = None
                                bank_name = None
                                card = None
                                shaba = None
                                account = None
                            share_allocation = ShareOfAllocation.objects.all()
                            if share_allocation.count() > 0:
                                share_allocation = share_allocation.last()
                                total = share_allocation.total
                            else:
                                total = 0
                            internal_dict_infos.update({
                                "province_factor_to_kill_house_for_poultry": {
                                    "province_factor_key": poultry_factor.key,
                                    "province_factor_fee": poultry_factor.factor_fee,
                                    "province_operator": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.fullname,
                                    "province_mobile": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.mobile,
                                    "weight": poultry_factor.total_weight,
                                    "bar_code": poultry_factor.factor_bar_code,
                                    "kill_house_name": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
                                    "kill_house_mobile": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
                                    "cost": poultry_factor.total_price,
                                    "poultry_share_with_profit": poultry_factor.shares[
                                        'poultryShareWithProfit'],
                                    "total_amount_char": words(poultry_factor.total_price) + " " + "ریال",
                                    "total_share_allocation": poultry_factor.total_weight * total,
                                    "total_share_allocation_char": words(
                                        poultry_factor.total_weight * total) + " " + "ریال",
                                    "name_of_bank_user": name_of_bank_user,
                                    "bank_name": bank_name,
                                    "card": card,
                                    "shaba": shaba,
                                    "account": account,
                                }
                            })
                        if not poultry_factor:
                            internal_dict_infos.update({
                                "province_factor_to_kill_house_for_poultry": None
                            })
                        province_factor = ProvinceFactorToKillHouse.objects.filter(
                            province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                            trash=False)
                        if province_factor:
                            if province_factor[0].bank != None:
                                name_of_bank_user = province_factor[0].bank.name_of_bank_user
                                bank_name = province_factor[0].bank.bank_name
                                card = province_factor[0].bank.card,
                                shaba = province_factor[0].bank.shaba,
                                account = province_factor[0].bank.account,
                            else:
                                name_of_bank_user = None
                                bank_name = None
                                card = None
                                shaba = None
                                account = None
                            share_allocation = ShareOfAllocation.objects.all()
                            if share_allocation.count() > 0:
                                share_allocation = share_allocation.last()
                                total = share_allocation.total
                            else:
                                total = 0
                            if province_factor[0].poultry_factor == None:
                                poultry_share_with_profit = province_factor[0].shares['poultryShareWithProfit']
                            else:
                                poultry_share_with_profit = province_factor[0].poultry_factor.total_price

                            internal_dict_infos.update({
                                "province_factor_to_kill_house": {
                                    "province_factor_key": province_factor[0].key,
                                    "province_factor_fee": province_factor[0].factor_fee,
                                    "province_operator": province_factor[
                                        0].province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.fullname,
                                    "province_mobile": province_factor[
                                        0].province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.mobile,
                                    "weight": province_factor[0].total_weight,
                                    "bar_code": province_factor[0].factor_bar_code,
                                    "kill_house_name": province_factor[
                                        0].province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
                                    "kill_house_mobile": province_factor[
                                        0].province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
                                    "cost": province_factor[0].total_price,
                                    "poultry_share_with_profit": poultry_share_with_profit,
                                    "union_share_with_profit": province_factor[0].shares['unionShareWithProfit'],
                                    "total_amount_char": words(province_factor[0].total_price) + " " + "ریال",
                                    "total_share_allocation": province_factor[0].total_weight * total,
                                    "total_share_allocation_char": words(
                                        province_factor[0].total_weight * total) + " " + "ریال",
                                    "name_of_bank_user": name_of_bank_user,
                                    "bank_name": bank_name,
                                    "card": card,
                                    "shaba": shaba,
                                    "account": account,
                                }
                            })
                        if not province_factor:
                            internal_dict_infos.update({
                                "province_factor_to_kill_house": None
                            })
                        kill_house_factor_poultry = KillHouseFactorToPoultry.objects.filter(
                            province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                            trash=False)
                        if kill_house_factor_poultry.count():
                            kill_house_factor_poultry = kill_house_factor_poultry.last()
                            internal_dict_infos.update({
                                "kill_house_factor_to_poultry": {
                                    "kill_house_name": kill_house_request.killhouse_user.name,
                                    "kill_house_user_city": kill_house_request.killhouse_user.system_address.city.name,
                                    "kill_house_user_province": kill_house_request.killhouse_user.system_address.province.name,
                                    "time": kill_house_factor_poultry.create_date,
                                    "payment_code": kill_house_factor_poultry.payment_code,
                                    "factor_image": kill_house_factor_poultry.factor_image,
                                    "factor_key": kill_house_factor_poultry.key,
                                    "factor_state": kill_house_factor_poultry.state,
                                    "total_money": kill_house_factor_poultry.province_factor.total_price,
                                    "factor_message": kill_house_factor_poultry.message
                                }
                            })
                        if not kill_house_factor_poultry:
                            internal_dict_infos.update({
                                "kill_house_factor_to_poultry": 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:
                            internal_dict_infos.update({
                                "kill_house_factor_to_province": {
                                    "kill_house_name": kill_house_request.killhouse_user.name,
                                    "kill_house_user_city": kill_house_request.killhouse_user.system_address.city.name,
                                    "kill_house_user_province": kill_house_request.killhouse_user.system_address.province.name,
                                    "time": kill_house_factor[0].create_date,
                                    "payment_code": kill_house_factor[0].payment_code,
                                    "factor_image": kill_house_factor[0].factor_image,
                                    "factor_key": kill_house_factor[0].key,
                                    "factor_state": kill_house_factor[0].state,
                                    "total_money": kill_house_factor[0].province_factor.total_price,
                                    "factor_message": kill_house_factor[0].message
                                }
                            })
                        if not kill_house_factor:
                            internal_dict_infos.update({
                                "kill_house_factor_to_province": None
                            })

                        reqs.append(internal_dict_infos)
                    internal_province_kill_dict_infos.update({"kill_house_requests": reqs

                                                              })
                if not kill_house_requests:
                    internal_province_kill_dict_infos.update({"kill_house_requests": None

                                                              })

                province_kill_reqs_list.append(internal_province_kill_dict_infos)
            process.update({"province_kill_requests": province_kill_reqs_list})

        if not province_kill_reqs:
            process.update({"province_kill_requests": None

                            })

        kill_house_reqs = KillHouseRequest.objects.filter(
            kill_house_request_auction_winner__kill_house_request_auction__poultry_request=instance, trash=False)
        if kill_house_reqs.count() > 0:

            reqs = []
            for kill_house_request in kill_house_reqs:
                province_req = kill_house_request.province_request
                internal_dict_infos = {
                    "kill_house_req_key": kill_house_request.key,
                    "kill_house_vet_state": kill_house_request.vet_state,
                    "order_code": instance.order_code,
                    "barcod": kill_house_request.bar_code,
                    "kill_house_state": kill_house_request.state,
                    "kill_house_name": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.name,
                    "kill_house_user_name": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.fullname,
                    "kill_house_user_province": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.province.name,
                    "kill_house_user_city": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.city.name,
                    "kill_house_user_address": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.system_address.address,
                    "kill_house_mobile": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.mobile,
                    "kill_house_national_id": kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.national_id,
                    "quantity": kill_house_request.quantity,
                    # "time": kill_house_request.kill_request.recive_time,
                    # "date": kill_house_request.kill_request.recive_date,
                    "cars": kill_house_request.car,
                    "driver_name": kill_house_request.add_car.driver.driver_name,
                    "type_car": kill_house_request.add_car.driver.type_car,
                    "pelak": kill_house_request.add_car.driver.pelak,
                    "clearance_code": kill_house_request.clearance_code,
                    "traffic_code": kill_house_request.traffic_code,
                    "show_kill_house": kill_house_request.show_kill_house,
                    "kill_house_message": kill_house_request.kill_house_message
                }

                vet_check = VetCheckRequest.objects.filter(kill_house_request=kill_house_request, trash=False)
                if vet_check:
                    internal_dict_infos.update({
                        "vet_check_info": {
                            "vet_user": vet_check[0].kill_house_vet.vet.user.fullname,
                            "vet_user_mobile": vet_check[0].kill_house_vet.vet.user.mobile,
                            "vet_check_state": vet_check[0].state,
                            "vet_check_accept_date": vet_check[0].create_date,
                        }
                    })
                if not vet_check:
                    internal_dict_infos.update({
                        "vet_check_info": None
                    })
                kill_house_assignment = KillHouseAssignmentInformation.objects.filter(
                    kill_house_request=kill_house_request, trash=False)
                if kill_house_assignment:
                    internal_dict_infos.update({
                        "bar_info": {
                            "kill_house_assignment_key": kill_house_assignment[0].key,
                            "real_quantity": kill_house_assignment[0].real_quantity,
                            "kill_house_weight_without_load": kill_house_assignment[0].car_weight_without_load,
                            "kill_house_weight_with_load": kill_house_assignment[0].car_weight_with_load,
                            "kill_house_image_without_load": kill_house_assignment[
                                0].car_weight_without_load_image,
                            "kill_house_image_with_load": kill_house_assignment[0].car_weight_with_load_image,
                            "kill_house_net_weight": kill_house_assignment[0].net_weight,
                            "expire_time": kill_house_assignment[0].protest_time,
                            "kill_house_assignment_state": kill_house_assignment[0].state,
                            "kill_house_assignment_message": kill_house_assignment[0].message,
                            "accept_reject_date": kill_house_assignment[0].modify_date

                        }
                    })
                    complaint = KillHouseComplaint.objects.filter(bar=kill_house_assignment[0], trash=False)
                    if complaint.count() > 0:
                        complaint = complaint.last()
                        internal_dict_infos.update({
                            "complaint": {
                                "complaint_key": complaint.key,
                                "title": complaint.title,
                                "description": complaint.description,
                                "percent": complaint.percent,
                                "image": complaint.image,
                                "state": complaint.state,
                                "message": complaint.message,
                            }
                        })
                    else:
                        internal_dict_infos.update({
                            "complaint": None
                        })
                if not kill_house_assignment:
                    internal_dict_infos.update({
                        "bar_info": None
                    })
                    internal_dict_infos.update({
                        "complaint": None
                    })
                poultry_factor = ProvinceFactorToKillHouseForPoultry.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=instance,
                    province_check_info__kill_house_assignment__kill_house_request=kill_house_request, trash=False)
                if poultry_factor.count() > 0:
                    poultry_factor = poultry_factor.last()
                    if poultry_factor.bank != None:
                        name_of_bank_user = poultry_factor.bank.name_of_bank_user
                        bank_name = poultry_factor.bank.bank_name
                        card = poultry_factor.bank.card,
                        shaba = poultry_factor.bank.shaba,
                        account = poultry_factor.bank.account,
                    else:
                        name_of_bank_user = None
                        bank_name = None
                        card = None
                        shaba = None
                        account = None
                    share_allocation = ShareOfAllocation.objects.all()
                    if share_allocation.count() > 0:
                        share_allocation = share_allocation.last()
                        total = share_allocation.total
                    else:
                        total = 0
                    internal_dict_infos.update({
                        "province_factor_to_kill_house_for_poultry": {
                            "province_factor_key": poultry_factor.key,
                            "province_factor_fee": poultry_factor.factor_fee,
                            "province_operator": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.fullname,
                            "province_mobile": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator_system.user.mobile,
                            "weight": poultry_factor.total_weight,
                            "bar_code": poultry_factor.factor_bar_code,
                            "kill_house_name": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
                            "kill_house_mobile": poultry_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
                            "cost": poultry_factor.total_price,
                            "poultry_share_with_profit": poultry_factor.shares[
                                'poultryShareWithProfit'],
                            "total_amount_char": words(poultry_factor.total_price) + " " + "ریال",
                            "total_share_allocation": poultry_factor.total_weight * total,
                            "total_share_allocation_char": words(
                                poultry_factor.total_weight * total) + " " + "ریال",
                            "name_of_bank_user": name_of_bank_user,
                            "bank_name": bank_name,
                            "card": card,
                            "shaba": shaba,
                            "account": account,
                        }
                    })
                if not poultry_factor:
                    internal_dict_infos.update({
                        "province_factor_to_kill_house_for_poultry": None
                    })
                province_factor = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=instance,
                    province_check_info__kill_house_assignment__kill_house_request=kill_house_request, trash=False)
                if province_factor:
                    if province_factor[0].bank != None:
                        name_of_bank_user = province_factor[0].bank.name_of_bank_user
                        bank_name = province_factor[0].bank.bank_name
                        card = province_factor[0].bank.card,
                        shaba = province_factor[0].bank.shaba,
                        account = province_factor[0].bank.account,
                    else:
                        name_of_bank_user = None
                        bank_name = None
                        card = None
                        shaba = None
                        account = None
                    share_allocation = ShareOfAllocation.objects.all()
                    if share_allocation.count() > 0:
                        share_allocation = share_allocation.last()
                        total = share_allocation.total
                    else:
                        total = 0
                    # if poultry_factor == None:
                    if province_factor[0].poultry_factor == None:
                        poultry_share_with_profit = province_factor[0].shares['poultryShareWithProfit']
                    else:
                        poultry_share_with_profit = province_factor[0].poultry_factor.total_price
                    province_operator = province_factor[0].province_check_info.province_operator
                    internal_dict_infos.update({
                        "province_factor_to_kill_house": {
                            "province_factor_key": province_factor[0].key,
                            "province_factor_fee": province_factor[0].factor_fee,
                            "province_operator": province_operator.user.fullname,
                            "province_mobile": province_operator.user.mobile,
                            "weight": province_factor[0].total_weight,
                            "bar_code": province_factor[0].factor_bar_code,
                            "kill_house_name": province_factor[
                                0].province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.name,
                            "kill_house_mobile": province_factor[
                                0].province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.kill_house.kill_house_operator.user.mobile,
                            "cost": province_factor[0].total_price,
                            "poultry_share_with_profit": poultry_share_with_profit,
                            "union_share_with_profit": province_factor[0].shares['unionShareWithProfit'],
                            "total_amount_char": words(province_factor[0].total_price) + " " + "ریال",
                            "total_share_allocation": province_factor[0].total_weight * total,
                            "total_share_allocation_char": words(
                                province_factor[0].total_weight * total) + " " + "ریال",
                            "name_of_bank_user": name_of_bank_user,
                            "bank_name": bank_name,
                            "card": card,
                            "shaba": shaba,
                            "account": account,
                        }
                    })
                if not province_factor:
                    internal_dict_infos.update({
                        "province_factor_to_kill_house": None
                    })

                kill_house_factor_poultry = KillHouseFactorToPoultry.objects.filter(
                    province_factor__province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=instance,
                    province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                    trash=False)
                if kill_house_factor_poultry.count():
                    kill_house_factor_poultry = kill_house_factor_poultry.last()
                    internal_dict_infos.update({
                        "kill_house_factor_to_poultry": {
                            "kill_house_name": kill_house_request.killhouse_user.name,
                            "kill_house_user_city": kill_house_request.killhouse_user.system_address.city.name,
                            "kill_house_user_province": kill_house_request.killhouse_user.system_address.province.name,
                            "time": kill_house_factor_poultry.create_date,
                            "payment_code": kill_house_factor_poultry.payment_code,
                            "factor_image": kill_house_factor_poultry.factor_image,
                            "factor_key": kill_house_factor_poultry.key,
                            "factor_state": kill_house_factor_poultry.state,
                            "total_money": kill_house_factor_poultry.province_factor.total_price,
                            "factor_message": kill_house_factor_poultry.message
                        }
                    })
                if not kill_house_factor_poultry:
                    internal_dict_infos.update({
                        "kill_house_factor_to_poultry": None
                    })
                kill_house_factor = KillHouseFactorToProvince.objects.filter(
                    province_factor__province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=instance,
                    province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
                    trash=False)
                if kill_house_factor:
                    internal_dict_infos.update({
                        "kill_house_factor_to_province": {
                            "kill_house_name": kill_house_request.killhouse_user.name,
                            "kill_house_user_city": kill_house_request.killhouse_user.system_address.city.name,
                            "kill_house_user_province": kill_house_request.killhouse_user.system_address.province.name,
                            "time": kill_house_factor[0].create_date,
                            "payment_code": kill_house_factor[0].payment_code,
                            "factor_image": kill_house_factor[0].factor_image,
                            "factor_key": kill_house_factor[0].key,
                            "factor_state": kill_house_factor[0].state,
                            "total_money": kill_house_factor[0].province_factor.total_price,
                            "factor_message": kill_house_factor[0].message
                        }
                    })
                if not kill_house_factor:
                    internal_dict_infos.update({
                        "kill_house_factor_to_province": None
                    })

                reqs.append(internal_dict_infos)
            process.update({"auction": reqs})

        if not kill_house_reqs:
            process.update({"auction": None})

        allocation = DepositAllocation.objects.filter(poultry=instance, trash=False)
        if instance.poultry.user_bank_info != None:
            poultry_bank_info = instance.poultry.user_bank_info.name_of_bank_user
            poultry_bank_name = instance.poultry.user_bank_info.bank_name
            poultry_card_number = instance.poultry.user_bank_info.card
            poultry_shaba = instance.poultry.user_bank_info.shaba
        else:
            poultry_bank_info = None
            poultry_bank_name = None
            poultry_card_number = None
            poultry_shaba = None

        if city_operator.user_bank_info != None:
            city_bank_info = city_operator.user_bank_info.name_of_bank_user
            city_bank_name = city_operator.user_bank_info.bank_name
            city_card_number = city_operator.user_bank_info.card
            city_shaba = city_operator.user_bank_info.shaba
        else:
            city_bank_info = None
            city_bank_name = None
            city_card_number = None
            city_shaba = None
        financial_operator = SystemUserProfile.objects.filter(role__name='ProvinceFinancial',
                                                              province__name=instance.poultry.address.province.name)
        if financial_operator.count() > 0:
            operator = ProvinceOperator.objects.get(user=financial_operator.last())
            if operator.user_bank_info != None:
                province_bank_info = operator.user_bank_info.name_of_bank_user
                province_bank_name = operator.user_bank_info.bank_name
                province_card_number = operator.user_bank_info.card
                province_shaba = operator.user_bank_info.shaba
            else:
                province_bank_info = None
                province_bank_name = None
                province_card_number = None
                province_shaba = None

        if allocation.count() > 0:
            fee = 0
            process.update({"allocation": {"allocation_key": allocation[0].key,
                                           "fee": fee,
                                           "total_money": allocation[0].poultry_share + allocation[
                                               0].city_share + allocation[0].province_share + allocation[
                                                              0].company_share + allocation[
                                                              0].central_union_share + allocation[
                                                              0].fanava_share,
                                           "total_money_char": words(
                                               allocation[0].poultry_share + allocation[
                                                   0].city_share + allocation[0].province_share +
                                               allocation[
                                                   0].company_share + allocation[
                                                   0].central_union_share + allocation[
                                                   0].fanava_share) + " " + 'ریال',
                                           "poultry_share_digit": allocation[0].poultry_share,
                                           "poultry_share_char": words(
                                               allocation[0].poultry_share) + " " + 'ریال',
                                           "poultry_share_payment": allocation[0].poultry_share_payment,
                                           "poultry_remaining": (allocation[0].poultry_share - allocation[
                                               0].poultry_share_payment),
                                           "poultry_payment_documents": allocation[0].poultry_share_payment_info,
                                           "poultry_bank_info": poultry_bank_info,
                                           "poultry_bank_name": poultry_bank_name,
                                           "poultry_card_number": poultry_card_number,
                                           "poultry_shaba": poultry_shaba,
                                           "poultry_image": allocation[0].poultry_image,
                                           "city_share_digit": allocation[0].city_share,
                                           "city_share_char": words(
                                               allocation[0].city_share) + " " + 'ریال',
                                           "city_image": allocation[0].city_image,
                                           "city_bank_info": city_bank_info,
                                           "city_bank_name": city_bank_name,
                                           "city_card_number": city_card_number,
                                           "city_shaba": city_shaba,
                                           "city_share_payment": allocation[0].city_share_payment,
                                           "city_share_remaining": (
                                                   allocation[0].city_share - allocation[0].city_share_payment),
                                           "city_payment_documents": allocation[0].city_share_payment_info,
                                           "province_share_digit": allocation[0].province_share,
                                           "province_share_char": words(
                                               allocation[0].province_share) + " " + 'ریال',
                                           "province_share_payment": allocation[0].province_share_payment,
                                           "province_share_remaining": (allocation[0].province_share - allocation[
                                               0].province_share_payment),
                                           "province_payment_documents": allocation[0].province_share_payment_info,
                                           "province_bank_info": province_bank_info,
                                           "province_bank_name": province_bank_name,
                                           "province_card_number": province_card_number,
                                           "province_shaba": province_shaba,
                                           "company_share_digit": allocation[0].company_share,
                                           "company_share_char": words(
                                               allocation[0].company_share) + " " + 'ریال',
                                           "company_share_payment": allocation[0].company_share_payment,
                                           "company_share_remaining": (allocation[0].company_share - allocation[
                                               0].company_share_payment),
                                           "company_payment_documents": allocation[0].company_share_payment_info,
                                           "company_bank_info": '************',
                                           "company_bank_name": '************',
                                           "company_card_number": '**************',
                                           "company_shaba": '************',
                                           "central_union_share_digit": allocation[0].central_union_share,
                                           "central_union_share_char": words(
                                               allocation[0].central_union_share) + " " + 'ریال',
                                           "central_union_share_payment": allocation[0].central_union_share_payment,
                                           "central_union_share_remaining": (
                                                   allocation[0].central_union_share - allocation[
                                               0].central_union_share_payment),
                                           "central_union_payment_documents": allocation[
                                               0].central_union_share_payment_info,
                                           "central_union_bank_info": '************',
                                           "central_union_bank_name": '************',
                                           "central_union_card_number": '**************',
                                           "central_union_shaba": '************',
                                           "fanava_share_digit": allocation[0].fanava_share,
                                           "fanava_share_share_char": words(
                                               allocation[0].fanava_share) + " " + 'ریال',
                                           "fanava_share_payment": allocation[0].fanava_share_payment,
                                           "fanava_share_remaining": (
                                                   allocation[0].fanava_share - allocation[0].fanava_share_payment),
                                           "fanava_payment_documents": allocation[0].fanava_share_payment_info,
                                           "fanava_bank_info": '************',
                                           "fanava_bank_name": '************',
                                           "fanava_card_number": '**************',
                                           "fanava_shaba": '************',

                                           }})

        if not allocation:
            process.update({"allocation": None})

        province_incpector = PovinceInspector.objects.filter(poultry_request=instance, trash=False)
        if province_incpector:
            process.update(
                {"province_incpector": {"inspector_name": province_incpector[0].inspector_operator.user.fullname,
                                        "state": province_incpector[0].state,
                                        "message": province_incpector[0].message,
                                        "accept-reject-date": province_incpector[0].create_date, }})
        if not province_incpector:
            province_name = instance.poultry.address.province.name
            inspector = InspectorOperator.objects.get(address__province__name=province_name, trash=False)
            process.update({"province_incpector": {"province_incpector": None,
                                                   "state": 'pending',
                                                   "inspector_name": inspector.user.fullname,
                                                   "inspector_mobile": inspector.user.mobile,
                                                   "inspector_address": inspector.address.province.name}})

        return process


# سریالایزر مربوط به درخواست مزایده مرغدار
class PoultryRequestAuctionSerializer(serializers.ModelSerializer):
    poultry_request = PoultryRequestSerializer(read_only=True)

    class Meta:
        model = PoultryRequestAuction
        fields = '__all__'


# سریالایزر مربوط به ورود اطلاعات بار برای بارهای اختصاص یافته به درخواست مرغدار

class PoultryAssignmentInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = PoultryAssignmentInformation
        fields = '__all__'


class LastUpdateSerializer(serializers.ModelSerializer):
    class Meta:
        model = LastUpdate
        fields = '__all__'


class PoultryHatchingForLocSerializer(serializers.ModelSerializer):
    class Meta:
        model = PoultryHatching
        fields = ('left_over', 'chicken_age', 'date',
                  'licence_number','killed_quantity','total_losses','quantity')


class PoultryLocationSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryLocSerializer(read_only=True)
    address = SystemAddressForLocSerializer(required=False)
    hatching = serializers.SerializerMethodField()

    class Meta:
        model = Poultry
        fields = [
            'id', 'unit_name', 'Lat', 'Long', 'user', 'hatching', 'address', 'breeding_unique_id'
        ]

    def get_hatching(self, instance):
        serilizer = PoultryHatchingForLocSerializer(instance.poultry_hatching_user, many=True).data
        return serilizer


class SystemUserProfileForAutoAllocationSerializerForGetAllPoultry(serializers.ModelSerializer):
    class Meta:
        model = SystemUserProfile
        fields = ['fullname', 'mobile']


class SystemAddressSerializerForGetAllPoultry(serializers.ModelSerializer):
    city = CityForLocSerializer(required=False)

    class Meta:
        model = SystemAddress
        fields = ['city']


class GetAllPoultrySerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializerForGetAllPoultry(read_only=True)
    address = SystemAddressSerializerForGetAllPoultry(required=False)
    last_hatching_remain_quantity = serializers.SerializerMethodField()
    province_allow_sell_free = serializers.SerializerMethodField()
    chain_company = serializers.SerializerMethodField()

    class Meta:
        model = Poultry
        fields = ['user', 'key', 'unit_name', 'address', 'last_hatching_remain_quantity', 'province_allow_sell_free',
                  'chain_company']

    def get_last_hatching_remain_quantity(self, obj):
        poultry_data = self.context.get('poultry_remain_dict', {}).get(obj.id, {})
        return poultry_data.get('last_hatching_remain_quantity', 0)

    def get_province_allow_sell_free(self, obj):
        poultry_data = self.context.get('poultry_remain_dict', {}).get(obj.id, {})
        return poultry_data.get('allow_sell_free')

    def get_chain_company(self, obj):
        poultry_data = self.context.get('poultry_remain_dict', {}).get(obj.id, {})
        return poultry_data.get('chain_company')


class PoultryPredictionSerializer(serializers.ModelSerializer):
    poultry = PoultryForPredictionSerializer(required=False)

    class Meta:
        model = PoultryPrediction
        fields = ['key', 'poultry', 'date', 'killing_ave_age', 'active_left_over', 'killing_ave_count',
                  'killing_ave_weight',
                  'killing_loss_weight_percent']


class HatchingIncreaseRequestSerializer(serializers.ModelSerializer):
    hatching = PoultryHatchingForChainAllocationSerializer(read_only=True)

    class Meta:
        model = HatchingIncreaseRequest
        fields = "__all__"


class EvacuationHatchingDetailSerializer(serializers.ModelSerializer):
    hatching = PoultryHatchingSerializer(read_only=True)

    class Meta:
        model = EvacuationHatchingDetail
        fields = '__all__'


class ChickenCommissionPricesSerializer(serializers.ModelSerializer):
    price_info = serializers.SerializerMethodField()

    class Meta:
        model = ChickenCommissionPrices
        fields = "__all__"

    def get_price_info(self, obj):
        kill_house_price = round(
            ((obj.chicken_average_price + obj.kill_house_price) / 750) * 1000) if obj.chicken_average_price else 0
        return {
            "killHousePrice": kill_house_price,
            "wholesalePrice": kill_house_price + obj.wholesaler_price if obj.chicken_average_price else 0,
            "retailPrice": kill_house_price + obj.retailer_price if obj.chicken_average_price else 0,
        }


class ChickenCommissionPricesForDashboardSerializer(serializers.ModelSerializer):
    price_info = serializers.SerializerMethodField()

    class Meta:
        model = ChickenCommissionPrices
        fields = ['chicken_average_price', 'price_info', 'date']

    def get_price_info(self, obj):
        kill_house_price = round(
            ((obj.chicken_average_price + obj.kill_house_price) / 750) * 1000) if obj.chicken_average_price else 0
        return {
            "killHousePrice": kill_house_price,
            "wholesalePrice": kill_house_price + obj.wholesaler_price if obj.chicken_average_price else 0,
            "retailPrice": kill_house_price + obj.retailer_price if obj.chicken_average_price else 0,
        }


class PoultryRequestQuarantineCodeSerializer(serializers.ModelSerializer):
    class Meta:
        model = PoultryRequestQuarantineCode
        fields = ['key', 'quarantine_code', 'traffic_code', 'quarantine_quantity', 'registrar', 'register_date',
                  'system_quarantine_quantity']


class PoultryForDetailsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryLocSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Poultry
        fields = [
            'unit_name', 'user', 'address', 'breeding_unique_id'
        ]


class PoultryHatchingForDetailsSerializer(serializers.ModelSerializer):
    killing_info = serializers.SerializerMethodField()
    active_kill = serializers.SerializerMethodField()
    vet_farm = serializers.SerializerMethodField()
    killing_ave_age = serializers.SerializerMethodField()
    poultry = PoultryForDetailsSerializer(read_only=True)

    class Meta:
        model = PoultryHatching
        fields = ('violation', 'licence_number', 'breeding_unique_id', 'CertId', 'poultry', 'InteractTypeName',
                  'UnionTypeName', 'hall', 'period', 'create_date', 'date', 'predicate_date', 'chicken_breed',
                  'chicken_age',
                  'quantity', 'PersonTypeName', 'increase_quantity', 'losses', 'direct_losses', 'total_losses',
                  'total_commitment_quantity', 'total_free_commitment_quantity', 'governmental_quantity',
                  'free_quantity', 'free_killed_quantity', 'out_province_killed_quantity', 'out_province_killed_weight',
                  'killing_info', 'killed_quantity', 'left_over', 'samasat_discharge_percentage', 'total_commitment',
                  'total_average_killed_weight', 'total_killed_weight', 'active_kill', 'export_killed_quantity',
                  'export_killed_weight', 'vet_farm', 'latest_hatching_change', 'violation', 'killing_ave_age',
                  'poultry','bar_difference_request_quantity','bar_difference_request_weight')

    def get_vet_farm(self, instance):
        vet = {
            "vet_farm_full_name": 'ندارد',
            "vet_farm_mobile": '',
        }
        vet_farm = VetFarm.objects.filter(poultry=instance.poultry)
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()
            vet = {
                "vet_farm_full_name": vet_farm.vet.user.fullname,
                "vet_farm_mobile": vet_farm.vet.user.mobile,
            }

        return vet

    def get_killing_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0,
                                                                    province_request__poultry_request__hatching=obj)
        return_province_kill_requests = ProvinceKillRequest.objects.filter(trash=True, return_trash=True,return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0,
                                                                    province_request__poultry_request__hatching=obj)
        province_kill_requests_quantity = \
            province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        province_kill_requests_weight = \
            province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0


        return_province_kill_requests_quantity = \
            return_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        return_province_kill_requests_weight = \
            return_province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0


        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=obj)
        first_quantity = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity') or 0
        first_weight = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        ware_house_bars = kill_house_requests.filter(ware_house_confirmation=True)
        ware_house_bars_quantity = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_quantity'))[
                                       'total'] or 0
        ware_house_bars_weight = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_weight'))[
                                     'total'] or 0

        ware_house_bars_weight_lose = ware_house_bars.aggregate(total=Sum('weight_loss'))[
                                          'total'] or 0
        bar_complete_with_kill_house = kill_house_requests.filter(
            assignment_state_archive='True')
        return_kill_house_requests = KillHouseRequest.objects.filter(trash=True, return_trash=True,province_request__poultry_request__hatching=obj)

        return_kill_house_weight = return_kill_house_requests.aggregate(
            total_quantity=Sum('accepted_real_weight')).get('total_quantity') or 0

        return_kill_house_quantity = return_kill_house_requests.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get('total_quantity') or 0

        accepted_real_wight_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        accepted_real_quantity_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity', 0) or 0

        return {
            "violation_message": 'متخلف' + ' ' + '(مانده در سالن بیش از حد مجاز)' if obj.violation else 'عادی',
            "province_kill_requests": len(province_kill_requests),
            "province_kill_requests_quantity": province_kill_requests_quantity,
            "province_kill_requests_weight": province_kill_requests_weight,
            "kill_house_requests": len(kill_house_requests),
            "kill_house_requests_first_quantity": first_quantity,
            "kill_house_requests_first_weight": first_weight,
            "bar_complete_with_kill_house": len(bar_complete_with_kill_house),
            "accepted_real_quantity_final": accepted_real_quantity_final,
            "accepted_real_wight_final": accepted_real_wight_final,
            "ware_house_bars": len(ware_house_bars),
            "ware_house_bars_quantity": ware_house_bars_quantity,
            "ware_house_bars_weight": ware_house_bars_weight,
            'ware_house_bars_weight_lose': ware_house_bars_weight_lose / len(
                ware_house_bars) if ware_house_bars else 0,
            'return_province_kill_requests_count': return_province_kill_requests.count(),
            'return_kill_house_requests_count': return_kill_house_requests.count(),
            'return_kill_house_weight': return_kill_house_weight,
            'return_kill_house_quantity': return_kill_house_quantity,
            'return_province_kill_requests_weight': return_province_kill_requests_weight,
            'return_province_kill_requests_quantity': return_province_kill_requests_quantity,
            'total_return_weight': return_province_kill_requests_weight + return_kill_house_weight,
            'total_return_quantity': return_province_kill_requests_quantity + return_kill_house_quantity,
            'total_sale_in_province_weight': int(province_kill_requests_weight + first_weight),
            'total_sale_in_province_quantity': province_kill_requests_quantity + first_quantity,
        }

    def get_killing_ave_age(self, obj):
        return obj.poultry.killing_ave_age

    def get_active_kill(self, instance):

        active_kill = False
        count_of_request = 0

        province_kill_request = ProvinceKillRequest.objects.filter(trash=False,
                                                                   province_request__poultry_request__hatching=instance,
                                                                   state='accepted')
        if province_kill_request.count() > 0:
            count_of_request = province_kill_request.count()

        if ProvinceKillRequest.objects.filter(trash=False, province_request__poultry_request__hatching=instance,
                                              state='pending').exists():
            active_kill = True
        info = {
            "active_kill": active_kill,
            "count_of_request": count_of_request,
        }

        return info


class PoultryRequestForHatchingDetailSerializer(serializers.ModelSerializer):
    weight = serializers.SerializerMethodField()

    class Meta:
        model = PoultryRequest
        fields = ['order_code', 'send_date', 'buyer_fullname', 'buyer_mobile', 'buyer_province', 'buyer_city',
                  'quarantine_code', 'quarantine_quantity', 'quantity', 'weight','killing_age']

    def get_weight(self, obj):
        return int(obj.quantity * obj.Index_weight)


class ChainAllocationForHatchingDetailSerializer(serializers.ModelSerializer):
    chain_company = ChainCompanySerializer(read_only=True)
    kill_house = KillHouseForChainAllocationSerializer(read_only=True)

    class Meta:
        model = ChainAllocation
        fields = '__all__'


class PoultryHatchingForBazrasiSerializer(serializers.ModelSerializer):
    # poultry = PoultrySerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    age = serializers.SerializerMethodField('get_age')
    inspection_losses = serializers.SerializerMethodField('get_inspection')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    active_kill = serializers.SerializerMethodField('get_active_kill')
    killing_info = serializers.SerializerMethodField('get_killing_info')
    free_governmental_info = serializers.SerializerMethodField('get_free_governmental_info')

    class Meta:
        model = PoultryHatching
        fields = '__all__'

    # تابع برای بدست آوردن سن مرع
    def get_age(self, instance):
        return instance.chicken_age

    def get_inspection(self, instance):
        inspection = VetFarmInspection.objects.filter(poultry_hatching=instance)
        if inspection.count() > 0:
            inspections = 0
            for ins in inspection:
                if ins.Losses == 0:
                    pass
                else:
                    inspections += int(ins.Losses)
            return inspections

    def get_vet_farm(self, instance):
        vet = {
            "vet_farm_full_name": 'ندارد',
            "vet_farm_mobile": '',
        }
        vet_farm = VetFarm.objects.filter(poultry=instance.poultry).select_related('vet').only(
            'vet__user__fullname', 'vet__user__mobile'
        )
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()
            vet = {
                "vet_farm_full_name": vet_farm.vet.user.fullname,
                "vet_farm_mobile": vet_farm.vet.user.mobile,
            }

        return vet

    def get_active_kill(self, instance):
        active_kill = False

        count_of_request = ProvinceKillRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=instance,
                                                              state='accepted').count()

        if ProvinceKillRequest.objects.filter(trash=False, province_request__poultry_request__hatching=instance,
                                              state='pending').exists():
            active_kill = True
        info = {
            "active_kill": active_kill,
            "count_of_request": count_of_request,
        }

        return info

    def get_killing_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0,
                                                                    province_request__poultry_request__hatching=obj).only(
            'total_killed_quantity',
            'total_killed_weight'
        )
        province_kill_requests_quantity = \
            province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        province_kill_requests_weight = \
            province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0
        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=obj)
        first_quantity = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity') or 0
        first_weight = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        ware_house_bars = kill_house_requests.filter(ware_house_confirmation=True)
        ware_house_bars_quantity = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_quantity'))[
                                       'total'] or 0
        ware_house_bars_weight = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_weight'))[
                                     'total'] or 0

        ware_house_bars_weight_lose = ware_house_bars.aggregate(total=Sum('weight_loss'))[
                                          'total'] or 0
        bar_complete_with_kill_house = kill_house_requests.filter(
            assignment_state_archive='True')

        accepted_real_wight_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        accepted_real_quantity_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity', 0) or 0

        return {
            "violation_message": 'متخلف' + ' ' + '(مانده در سالن بیش از حد مجاز)' if obj.violation else 'عادی',
            "province_kill_requests": len(province_kill_requests),
            "province_kill_requests_quantity": province_kill_requests_quantity,
            "province_kill_requests_weight": province_kill_requests_weight,
            "kill_house_requests": len(kill_house_requests),
            "kill_house_requests_first_quantity": first_quantity,
            "kill_house_requests_first_weight": first_weight,
            "bar_complete_with_kill_house": len(bar_complete_with_kill_house),
            "accepted_real_quantity_final": accepted_real_quantity_final,
            "accepted_real_wight_final": accepted_real_wight_final,
            "ware_house_bars": len(ware_house_bars),
            "ware_house_bars_quantity": ware_house_bars_quantity,
            "ware_house_bars_weight": ware_house_bars_weight,
            'ware_house_bars_weight_lose': ware_house_bars_weight_lose / len(
                ware_house_bars) if ware_house_bars else 0,
        }

    def get_free_governmental_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    province_request__poultry_request__hatching=obj)

        governmental_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=False)
        governmental_province_kill_requests_quantity = \
            governmental_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        free_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=True)

        free_province_kill_requests_quantity = \
            free_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        out_poultry_requests = PoultryRequest.objects.filter(trash=False, out=True, state_process='accepted',
                                                             province_state='accepted',
                                                             out_province_request_cancel=False, final_state='archive',
                                                             hatching=obj)
        out_poultry_requests_quantity = out_poultry_requests.aggregate(total=Sum('quantity'))[
                                            'total'] or 0
        free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
        if free_sale_province.allow == False:
            left_total_free_commitment_quantity = obj.left_over

        elif obj.total_free_commitment_quantity == 0:
            left_total_free_commitment_quantity = 0
        else:
            if obj.total_commitment_quantity == 0:
                left_total_free_commitment_quantity = obj.left_over
            else:
                left_total_free_commitment_quantity = obj.total_free_commitment_quantity - (
                        free_province_kill_requests_quantity + out_poultry_requests_quantity) if (
                                                                                                         obj.total_free_commitment_quantity - (
                                                                                                         free_province_kill_requests_quantity + out_poultry_requests_quantity)) > 0 else 0

        return {
            "governmental_allocated_quantity": governmental_province_kill_requests_quantity,
            "total_commitment_quantity": obj.total_commitment_quantity,
            "free_allocated_quantity": free_province_kill_requests_quantity + out_poultry_requests_quantity,
            "total_free_commitment_quantity": obj.total_free_commitment_quantity,
            "left_total_free_commitment_quantity": left_total_free_commitment_quantity,

        }




class PoultryRequestForDirectBuyingSerializer(serializers.ModelSerializer):
    poultry = PoultryForDirectBuyingSerializer(read_only=True)
    age = serializers.SerializerMethodField()
    total_allocated = serializers.SerializerMethodField()

    class Meta:
        model = PoultryRequest
        fields = [
            'key',
            'poultry',
            'age',
            'total_allocated',
            'Index_weight',
            'quantity',
            'chicken_breed',
            'send_date',
            'remain_quantity',
            'amount'
        ]

    def get_age(self, obj):
        age = (obj.send_date.date() - obj.hatching.date.date()).days + 1
        hatching_key =  obj.hatching.key
        return {
            'age':age,
            'hatching_key':hatching_key
        }

    def get_total_allocated(self, obj):
        return obj.quantity - obj.remain_quantity


class ManagementHatchingAgeRangeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ManagementHatchingAgeRange
        fields = '__all__'


class GetAllPoultryForPoultryScienceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializerForGetAllPoultry(read_only=True)
    address = SystemAddressSerializerForGetAllPoultry(required=False)

    class Meta:
        model = Poultry
        fields = ['id', 'user', 'key', 'unit_name', 'address']


class PoultryDetailForPoultryScienceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryScienceWithoutRoleSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    hatching = serializers.SerializerMethodField('get_hatching')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    hatching_info = serializers.SerializerMethodField('get_hatching_info')


    class Meta:
        model = Poultry
        exclude = (
            'create_date',
            'modify_date',
            'password',
            'created_by',
            'modified_by',
        )

    def get_vet_farm(self, instance):
        internal_dictionary = {}
        vet_farm = VetFarm.objects.filter(poultry=instance, trash=False)
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()

            internal_dictionary = {
                "full_name": vet_farm.vet.user.fullname,
                "mobile": vet_farm.vet.user.mobile,
                "city": vet_farm.vet.user.city.name,
                "province": vet_farm.vet.user.province.name,

            }

        return internal_dictionary

    def get_hatching(self, instance):
        hatching_list = []
        for hatching in PoultryHatching.objects.filter(poultry=instance, state='pending',
                                                 allow_hatching='pending', archive=False,
                                                 trash=False):
            age = (datetime.now().date() - hatching.date.date()).days + 1
            internal_dictionary = {
                "poultry_key": hatching.poultry.key,
                "poultry_hatching_key": hatching.key,
                "poultry": hatching.poultry.unit_name,
                "quantity": hatching.quantity,
                "losses": hatching.losses,
                "left_over": hatching.left_over,
                "out_province_killed_quantity": hatching.out_province_killed_quantity,
                "export_killed_quantity": hatching.export_killed_quantity,
                "hall": hatching.hall,
                "date": hatching.date,
                "period": hatching.period,
                "state": hatching.state,
                "age": age,
                "licence_number": hatching.licence_number,

            }
            hatching_list.append(internal_dictionary)

        return hatching_list

    def get_hatching_info(self, obj):
        hatching = PoultryHatching.objects.filter(poultry__exact=obj, state='pending', archive=False,
                                                  trash=False).last()
        period = 0
        active_hatching = False
        if hatching:
            period = hatching.period
            if hatching.state == 'pending':
                active_hatching = True
        return {"period": period, "active_hatching": active_hatching}


class PoultryDetailForPoultryAndHatchingForPoultryScienceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryScienceWithoutRoleSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)


    class Meta:
        model = Poultry
        exclude = (
            'create_date',
            'modify_date',
            'password',
            'created_by',
            'modified_by',
        )


class PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer(serializers.ModelSerializer):
    poultry = PoultryDetailForPoultryAndHatchingForPoultryScienceSerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    age = serializers.SerializerMethodField('get_age')
    inspection_losses = serializers.SerializerMethodField('get_inspection')
    vet_farm = serializers.SerializerMethodField('get_vet_farm')
    active_kill = serializers.SerializerMethodField('get_active_kill')
    killing_info = serializers.SerializerMethodField('get_killing_info')
    free_governmental_info = serializers.SerializerMethodField('get_free_governmental_info')
    report_info = serializers.SerializerMethodField('get_report_info')

    class Meta:
        model = PoultryHatching
        fields = '__all__'

    def get_report_info(self, instance):
        poultry_science = PoultryScienceReport.objects.filter(trash=False, hatching=instance).only('image').first()
        image= False
        has_poultry_science = False
        if poultry_science:
            has_poultry_science = True
            if poultry_science.image:
                image = True
        result={
            'poultry_science': has_poultry_science,
            'image':image,
        }
        return result
    # تابع برای بدست آوردن سن مرع
    def get_age(self, instance):
        return instance.chicken_age

    def get_inspection(self, instance):
        inspection = VetFarmInspection.objects.filter(poultry_hatching=instance)
        if inspection.count() > 0:
            inspections = 0
            for ins in inspection:
                if ins.Losses == 0:
                    pass
                else:
                    inspections += int(ins.Losses)
            return inspections

    def get_vet_farm(self, instance):
        vet = {
            "vet_farm_full_name": 'ندارد',
            "vet_farm_mobile": '',
        }
        vet_farm = VetFarm.objects.filter(poultry=instance.poultry).select_related('vet').only(
            'vet__user__fullname', 'vet__user__mobile'
        )
        if vet_farm.count() > 0:
            vet_farm = vet_farm.last()
            vet = {
                "vet_farm_full_name": vet_farm.vet.user.fullname,
                "vet_farm_mobile": vet_farm.vet.user.mobile,
            }

        return vet

    def get_active_kill(self, instance):
        active_kill = False

        count_of_request = ProvinceKillRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=instance,
                                                              state='accepted').count()

        if ProvinceKillRequest.objects.filter(trash=False, province_request__poultry_request__hatching=instance,
                                              state='pending').exists():
            active_kill = True
        info = {
            "active_kill": active_kill,
            "count_of_request": count_of_request,
        }

        return info

    def get_killing_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0,
                                                                    province_request__poultry_request__hatching=obj).only(
            'total_killed_quantity',
            'total_killed_weight'
        )
        province_kill_requests_quantity = \
            province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        province_kill_requests_weight = \
            province_kill_requests.aggregate(total=Sum('total_killed_weight'))['total'] or 0
        kill_house_requests = KillHouseRequest.objects.filter(trash=False,
                                                              province_request__poultry_request__hatching=obj)
        first_quantity = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity') or 0
        first_weight = kill_house_requests.aggregate(total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        ware_house_bars = kill_house_requests.filter(ware_house_confirmation=True)
        ware_house_bars_quantity = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_quantity'))[
                                       'total'] or 0
        ware_house_bars_weight = ware_house_bars.aggregate(total=Sum('ware_house_accepted_real_weight'))[
                                     'total'] or 0

        ware_house_bars_weight_lose = ware_house_bars.aggregate(total=Sum('weight_loss'))[
                                          'total'] or 0
        bar_complete_with_kill_house = kill_house_requests.filter(
            assignment_state_archive='True')

        accepted_real_wight_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_weight')).get(
            'total_quantity') or 0

        accepted_real_quantity_final = bar_complete_with_kill_house.aggregate(
            total_quantity=Sum('accepted_real_quantity')).get(
            'total_quantity', 0) or 0

        return {
            "violation_message": 'متخلف' + ' ' + '(مانده در سالن بیش از حد مجاز)' if obj.violation else 'عادی',
            "province_kill_requests": len(province_kill_requests),
            "province_kill_requests_quantity": province_kill_requests_quantity,
            "province_kill_requests_weight": province_kill_requests_weight,
            "kill_house_requests": len(kill_house_requests),
            "kill_house_requests_first_quantity": first_quantity,
            "kill_house_requests_first_weight": first_weight,
            "bar_complete_with_kill_house": len(bar_complete_with_kill_house),
            "accepted_real_quantity_final": accepted_real_quantity_final,
            "accepted_real_wight_final": accepted_real_wight_final,
            "ware_house_bars": len(ware_house_bars),
            "ware_house_bars_quantity": ware_house_bars_quantity,
            "ware_house_bars_weight": ware_house_bars_weight,
            'ware_house_bars_weight_lose': ware_house_bars_weight_lose / len(
                ware_house_bars) if ware_house_bars else 0,
        }

    def get_free_governmental_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    province_request__poultry_request__hatching=obj)

        governmental_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=False)
        governmental_province_kill_requests_quantity = \
            governmental_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        free_province_kill_requests = province_kill_requests.filter(
            Q(province_request__poultry_request__direct_buying=False) | Q(
                province_request__poultry_request__direct_buying=True),
            province_request__poultry_request__free_sale_in_province=True)

        free_province_kill_requests_quantity = \
            free_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                'total'] or 0
        out_poultry_requests = PoultryRequest.objects.filter(trash=False, out=True, state_process='accepted',
                                                             province_state='accepted',
                                                             out_province_request_cancel=False, final_state='archive',
                                                             hatching=obj)
        out_poultry_requests_quantity = out_poultry_requests.aggregate(total=Sum('quantity'))[
                                            'total'] or 0
        free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
        if free_sale_province.allow == False:
            left_total_free_commitment_quantity = obj.left_over

        elif obj.total_free_commitment_quantity == 0:
            left_total_free_commitment_quantity = 0
        else:
            if obj.total_commitment_quantity == 0:
                left_total_free_commitment_quantity = obj.left_over
            else:
                left_total_free_commitment_quantity = obj.total_free_commitment_quantity - (
                        free_province_kill_requests_quantity + out_poultry_requests_quantity) if (
                                                                                                         obj.total_free_commitment_quantity - (
                                                                                                         free_province_kill_requests_quantity + out_poultry_requests_quantity)) > 0 else 0

        return {
            "governmental_allocated_quantity": governmental_province_kill_requests_quantity,
            "total_commitment_quantity": obj.total_commitment_quantity,
            "free_allocated_quantity": free_province_kill_requests_quantity + out_poultry_requests_quantity,
            "total_free_commitment_quantity": obj.total_free_commitment_quantity,
            "left_total_free_commitment_quantity": left_total_free_commitment_quantity,

        }
