from datetime import datetime
import json

from django.db.models import Q, Sum, F, Case, When, FloatField, Count
from jdatetime import timedelta
from rest_framework import serializers
import django_filters
from rest_framework_recursive.fields import RecursiveField

from LiveStock.Cooperative.serializers import CooperativeForSharesSerializer
from LiveStock.models import LiveStockRolseProduct, Cooperative, CooperativeProductsShare
from authentication.models import SystemUserProfile, ExternalTransaction
from authentication.serializer.serializer import SystemUserProfileSerializer, BankCardSerializer, \
    SystemUserProfileForAutoAllocationSerializer, SystemUserProfileForGuildSerializer, \
    SystemUserProfileForInspectionSerializer, SystemUserProfileForFactorSerializer, \
    SystemUserProfileForPoultryLocSerializer, SystemUserProfileForPoultryScienceSerializer, \
    SystemUserProfileForPoultryScienceWithoutRoleSerializer
from authentication.serializers import UserProfileSerializer, SystemAddressSerializer
from deposit_id import wage_counting_type, out_selling_ignore, new_out_selling_count_wage, \
    new_out_selling_count_wage_date, before_out_buying_count_wage_amount
from deposit_percent import wage_percent, carcases_sell
from general_urls import base_url_for_sms_report
from panel.CityOperator.serializers import CityOperatorForSubSectorTransactionsSerializer
from panel.KillHouse.helpers import get_finance_info, get_difference_carcasses_weight, get_new_wage_for_free_buying, \
    get_total_wage_info
from panel.KillHouse.serializers import VetSerializer, ProvinceKillRequestSerializer, \
    KillHouseAssignmentInformationSerializer, KillHouseSerializer, KillHouseDailyQuotaSerializer, \
    ProvinceKillRequestForAutoAllocationSerializer, KillHouseWareHouseSerializer, KillHouseForProvinceSerializer, \
    KillHouseRequestForColdHouseAllocationsSerializer, KillHouseFreeBarInformationSerializer, \
    KillHouseForKillHouseVetKillHouseSerializer, KillHouseForKillingInformationDiscrepancyReportSerializer, \
    KillHouseForAutoAllocationSerializer, KillHouseForKillHouseGuildRelationSerializer, \
    KillHouseForKillHouseStewardRelationSerializer, KillHouseOperatorForAutoAllocationsSerializer, \
    PosKillHouseForKillingInformationDiscrepancyReportSerializer, KillHouseForCommonlyUsedSerializer, \
    KillHouseForReturnBuyingSerializer
from panel.ProvinceOperator.services.pos_transfer_service import POSTransferService
from panel.models import (
    Pricing,
    ProvinceCheckOperatorRequest,
    ProvinceCheckInformation,
    ProvinceFactorToKillHouse,
    KillHouseFactorToProvince,
    ProvinceCheckKillHouseFactor,
    DepositAllocation,
    PovinceInspector,
    PriceAnalysis,
    WareHouseFactor,
    ProvinceOperator, ProvinceRequestAction, ProvincePercentLeftOver, InspectorOperator, ShareOfAllocation,
    PaymentDeadLine, MonthlyProfitPercentage, ProvinceFactorToKillHouseForPoultry, KillHouseFactorToPoultry,
    Wallet, Itransaction, Debt, Deposit, Penalty, FinancialDocument, FinancialTransaction, Admin,
    ProvinceImportKillHouseOutFactors, VetSupervisor, Jahad, ProvincialGovernment, VetCheckAllocations, HourLimit,
    SmsLicense, PoultryRequest, PoultryAllowCityProvince, ProvinceAllowKillHouseRegisterCar,
    ProvinceAllowPoultryChooseKillHouse, ProvinceAllowPoultryChooseKillHouseTotal, ProvinceAllowPoultrySellFree,
    ProvinceAllowPoultrySellFreeTotal, ProvinceCheckOperatorOutRequest,
    ProvinceAutoAllocation, KillHouseAssignmentInformation, AutoAcceptProvinceKillRequest,
    AutoMakeKillHouseRequest, CityJahad, Guilds, Steward, KillHousePercentageOfLosses, StewardAllocation,
    ProvinceAllowKillHouseChooseStewardGuilds, StewardWareHouse, GuildsWareHouse, Commerce, CityCommerce,
    HatchingLossesPermission, KillHouse, WagePayment, ProvinceAllowKillHouseDirectBuyingTotal,
    ProvinceAllowKillHouseDirectBuying, ProvinceAllowKillHouseRegisterGuilds, ProvinceAllowKillHouseRegisterGuildsTotal,
    CityVet, KillHouseHourLimit, AutomaticStewardAllocation, FreeSaleWithinprovince, Observatory, ProvinceSupervisor,
    Car, Product, PosVersion, PosItem, GuildRoom, PosCompany, POSId, POSMachine, AdditionalProducts, POSTransactions,
    StewardFreeBarInformation, TypeActivity, AreaActivity, EvacuationPermit, SellForFreezing, LiveStockSupport,
    ColdHouse, ColdHouseAllocations, OperationLimitation, ApprovedPrice, Announcements, ChickenAgeRange, TimeRange,
    CitySupervisor, JahadInspector, SystemWallet, SuperAdmin, PaymentGatewayPercentage, WageType, PercentageOfWageType,
    ShareType, TotalWageInformation, ProvinceKillRequest, SlaughterHouseTransaction, ChainCompanyTransaction,
    ChainAllocation, KillHouseFreeBarInformation, KillHouseRequest, ChainCompany, InternalTransaction,
    TotalPaymentGatewayPercentage, StewardFreeSaleBarInformation, CityLivestock, ImprovingLivestock, Reports,
    ReportsUsers, UserReports, ReportSubmissionTime, MovingText, MovingTextDashboardStatus, MovingTextRole,
    MovingTextWithRole, NewProduct, AdminX, Supporter, ZarinPalAccounts, PoultryExport, PoultryOutProvinceRequest,
    Dispenser, VetFarmAggregatePermission, KillHouseBarLimitation, CityPoultry, KillHouseStewardGuildRelation,
    OutOfProvinceSellingCarcassesPermission, OutProvinceCarcassesBuyer, KillHouseFreeSaleBarInformation,
    ProductPricingType, KillHousePricePermission, BaseOutProvinceCarcassesBuyer, RolesProducts,
    AutomaticDirectBuyingPermission, PosMachineTransactions, BroadcastPrice, OutProvinceSaleLimitation,
    PosAllocationTransactions, ParentCompany, POSDeviceSession, PosDeviceVersion, SubSectorTransactions,
    SubSectorPercentageOfWageType, PosSegmentation, Vet, CityGuild, DistributionUserLevel, BarDifferenceRequest,
    OtherProducts, ProductsTransactions, PriceConfirmation, CompanyBeneficiaryAccount, ProteinGuild, CommonlyUsed,
    PercentageDropLimitation, UploadImageLimitation, ApkInfo, DirectBuyingVerification, FinePermission,
    ShowMarketRequest, IndexWeightCategory, PoultryScience, PoultryScienceReport, AllowRegisterCodeForGuilds,
    GuildsGeneralConfigs, StewardAppLogin, StewardRequest, RestrictionCarcassDistribution,
    AllowRegisterCodeForKillHouseFreeSaleBarInformation, AllowRegisterCodeForStewardFreeSaleBarInformation,
    LimitationForDirectPurchaseAndBarInformation, WarehouseArchive, SmsRecipient, MarketDailyLimitation,
    HatchingArchivePercent, Representative, POSAccessLevel, DispenserInformation, KillHousePercentage
)
from panel.poultry.helpers import market_daily_limitation_info
from panel.poultry.serializers import PoultryRequestSerializer, PoultrySerializer, \
    PoultryRequestForAutoAllocationSerializer, ChainAllocationSerializer, ChainCompanySerializer, \
    PoultryForPoultryRequestLetterSerializer, OutProvincePoultryRequestBuyerSerializer, \
    PoultryRequestForOutRequestTransactionsSerializer, PoultryDetailForPoultryScienceSerializer, \
    PoultryHatchingForPredictionSerializer, PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer


# سریالایزر مربوط به اپراتور شهرستان
class ProvinceOperatorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

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


class ProvinceOperatorForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = ProvinceOperator
        fields = ['address', 'user_bank_info', 'identity_documents', 'phone']


class AdminForAllUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = Admin
        fields = ['address', 'identity_documents', 'active']


# سریالایزر مربوط به اپراتور شهرستان
class AdminSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)

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


class ProvinceCheckOperatorOutRequestSerializer(serializers.ModelSerializer):
    poultry_request = PoultryRequestSerializer(read_only=True)

    class Meta:
        model = ProvinceCheckOperatorOutRequest
        fields = '__all__'


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

    class Meta:
        model = ProvinceCheckOperatorRequest
        fields = '__all__'


class AdditionalProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = AdditionalProducts
        exclude = (
            'create_date',
            'modify_date',
            'created_by',
            'modified_by',
        )


class ProductSerializer(serializers.ModelSerializer):
    product_price = serializers.SerializerMethodField('get_product_price')
    product_weight = serializers.SerializerMethodField('get_product_weight')
    product_sale_weight = serializers.SerializerMethodField('get_product_sale_weight')
    product_remain_weight = serializers.SerializerMethodField('get_product_remain_weight')
    product_extra_sale_weight = serializers.SerializerMethodField('get_product_extra_sale_weight')
    parent_key = serializers.SerializerMethodField('get_parent_product')

    class Meta:
        model = Product
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'trash',
            'guild',
            'steward',
            'kill_house',
            'created_by',
            'modified_by',
        )
        # fields = '__all__'

    def get_product_price(self, obj):
        try:
            price_type = ProductPricingType.objects.filter(trash=False).first()
            if price_type and price_type.province == False and obj.name == 'مرغ گرم':
                if obj.kill_house is not None:
                    price = obj.kill_house.kill_house_operator.user.city.product_price / 1000 if obj.kill_house.kill_house_operator.user.city.product_price > 0 else 0
                elif obj.guild is not None:
                    price = obj.guild.user.city.product_price / 1000 if obj.guild.user.city.product_price > 0 else 0

                else:
                    price = obj.steward.guild.user.city.product_price / 1000 if obj.steward.guild.user.city.product_price > 0 else 0


            else:
                price = obj.price / 1000 if obj.price > 0 else 0
        except:

            price = obj.price / 1000 if obj.price > 0 else 0
        return price

    def get_product_weight(self, obj):
        weight = obj.weight * 1000 if obj.weight > 0 else 0
        return weight

    def get_product_sale_weight(self, obj):
        sale_weight = obj.sale_weight * 1000 if obj.sale_weight > 0 else 0
        return sale_weight

    def get_product_remain_weight(self, obj):
        remain_weight = obj.remain_weight * 1000 if obj.remain_weight > 0 else 0
        return remain_weight

    def get_product_extra_sale_weight(self, obj):
        extra_sale_weight = obj.extra_sale_weight * 1000 if obj.extra_sale_weight > 0 else 0
        return extra_sale_weight

    def get_parent_product(self, obj):
        parent = AdditionalProducts.objects.filter(name=obj.name, trash=False)
        parent_key = parent.first().key if parent else None
        return parent_key


class ProvinceRequestActionSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceRequestAction
        fields = '__all__'


class SmsLicenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = SmsLicense
        fields = '__all__'


# سریالایزر مربوط به تایید یا رد اطلاعات بار وارد شده کشتارگاه
class ProvinceCheckInformationSerializer(serializers.ModelSerializer):
    kill_house_assignment = KillHouseAssignmentInformationSerializer(read_only=True)

    class Meta:
        model = ProvinceCheckInformation
        fields = '__all__'


# سریالایزر مربوط به قیمت گذاری
class ProvincePercentLeftOverSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvincePercentLeftOver
        fields = '__all__'


# سریالایزر مربوط به قیمت گذاری
class PricingSerializer(serializers.ModelSerializer):
    operator = SystemUserProfileSerializer(read_only=True)

    class Meta:
        model = Pricing
        fields = '__all__'


class ProvinceFactorToKillHouseForPoultrySerializer(serializers.ModelSerializer):
    province_check_info = ProvinceCheckInformationSerializer(read_only=True)
    bank = BankCardSerializer(read_only=True)

    class Meta:
        model = ProvinceFactorToKillHouseForPoultry
        fields = '__all__'


class ProvinceFactorToKillHousePdfSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceFactorToKillHouse
        fields = '__all__'


# سریالایزر مربوط به فاکتور استان برای کشتارگاه
class ProvinceFactorToKillHouseSerializer(serializers.ModelSerializer):
    province_check_info = ProvinceCheckInformationSerializer(read_only=True)
    # province_check_req = ProvinceCheckOperatorRequestSerializer(read_only=True)
    bank = BankCardSerializer(read_only=True)
    kill_house_factor_to_province = serializers.SerializerMethodField('get_kill_house_factor')
    province_factor_to_kill_house = serializers.SerializerMethodField('get_province_factor')
    poultry_request = serializers.SerializerMethodField('get_poultry_request')

    class Meta:
        model = ProvinceFactorToKillHouse
        fields = '__all__'

    def get_poultry_request(self, instance):
        poultry_request_dict = None
        poultry_request = PoultryRequest.objects.filter(
            key=instance.province_check_info.kill_house_assignment.kill_house_request.province_kill_request.province_request.poultry_request.key)
        if poultry_request.count() > 0:
            poultry_request = poultry_request.last()

            poultry_request_dict = {
                "poultry_request_id": poultry_request.id,
                "poultry_name": poultry_request.poultry.unit_name,
                "send_date": poultry_request.send_date,
                "chicken_breed": poultry_request.chicken_breed,
                "poultry_user_name": poultry_request.poultry.user.fullname,
                "poultry_user_mobile": poultry_request.poultry.user.mobile,

            }
        return poultry_request_dict

    def get_kill_house_factor(self, instance):

        factors = KillHouseFactorToProvince.objects.filter(province_factor=instance)

        factor_dict = None
        if factors.count() > 0:
            factors = factors.last()
            factor_dict = {
                "factor_key": factors.key,
                "payment_code": factors.payment_code,
                "factor_state": factors.state,

            }
        return factor_dict

    def get_province_factor(self, instance):
        factor_dict = None

        user = SystemUserProfile.objects.filter(role__name='ProvinceFinancial',
                                                province=instance.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.system_address.province)
        if user.count() > 0:
            user = user.last()
            province_operator = ProvinceOperator.objects.filter(user=user)
            if province_operator.count() > 0:
                province_operator = province_operator.last()
                if province_operator.user_bank_info != None:
                    factor_dict = {
                        "card": province_operator.user_bank_info.card,
                        "shaba": province_operator.user_bank_info.shaba,
                        "name_of_bank_user": province_operator.user_bank_info.name_of_bank_user,
                        "bank_name": province_operator.user_bank_info.bank_name,

                    }
                    assingment = KillHouseAssignmentInformation.objects.get(
                        key=instance.province_check_info.kill_house_assignment.key)
                    if assingment.kill_house_request.kill_request.slaughter_house != None:

                        kill_place = assingment.kill_house_request.kill_request.slaughter_house.name
                    else:
                        kill_place = assingment.kill_house_request.kill_request.kill_house.name
                    factor_dict.update(({
                        "factor_create_date": instance.create_date,
                        "total_factor_amount": instance.total_price,
                        "real_amount_factor": instance.total_weight * instance.factor_fee,
                        "poultry_share": instance.shares['poultry_share'],
                        "province_share": instance.shares['province_share'],
                        "kill_place": kill_place,
                        "real_quantity": assingment.real_quantity,
                        "bar_quantity": assingment.kill_house_request.quantity,
                        "net_weight": assingment.net_weight,
                    }))

        return factor_dict


class ProvinceImportKillHouseOutFactorsSerializer(serializers.ModelSerializer):
    kill_house_factor = ProvinceFactorToKillHouseSerializer(read_only=True)
    kill_house_factor_poultry = ProvinceFactorToKillHouseForPoultrySerializer(read_only=True)
    province_check = ProvinceCheckOperatorRequestSerializer(read_only=True)

    class Meta:
        model = ProvinceImportKillHouseOutFactors
        fields = '__all__'


class KillHouseFactorToPoultrySerializer(serializers.ModelSerializer):
    province_factor = ProvinceFactorToKillHouseForPoultrySerializer(read_only=True)

    class Meta:
        model = KillHouseFactorToPoultry
        fields = '__all__'


# سریالایزر مربوط به فاکتور کشتارگاه برای استان
class KillHouseFactorToProvinceSerializer(serializers.ModelSerializer):
    province_factor = ProvinceFactorToKillHouseSerializer(read_only=True)

    class Meta:
        model = KillHouseFactorToProvince
        fields = '__all__'


# سریالایزر مربوط به بررسی فاکتور کشتارگاه توسط استان
class ProvinceCheckKillHouseFactorSerializer(serializers.ModelSerializer):
    kill_house_factor = KillHouseFactorToProvinceSerializer(read_only=True)

    class Meta:
        model = ProvinceCheckKillHouseFactor
        fields = '__all__'


# سریالایزر مربوط به تخصیصات مالی
class DepositAllocationSerializer(serializers.ModelSerializer):
    poultry = PoultryRequestSerializer(read_only=True)

    class Meta:
        model = DepositAllocation
        fields = '__all__'


# سریالایزر مربوط به بازرس استان
class InspectorOperatorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = InspectorOperator
        fields = '__all__'


class InspectorOperatorForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = InspectorOperator
        fields = ['address', 'identity_documents', 'active']


# سریالایزر مربوط به بازرس استان
class PovinceInspectorSerializer(serializers.ModelSerializer):
    class Meta:
        model = PovinceInspector
        fields = '__all__'


class VetSupervisorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    vet = VetSerializer(read_only=True)

    class Meta:
        model = VetSupervisor
        fields = '__all__'


class CityVetSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = CityVet
        fields = '__all__'


class CommerceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Commerce
        fields = '__all__'


class CityCommerceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = CityCommerce
        fields = '__all__'


class ProvinceSupervisorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = ProvinceSupervisor
        fields = '__all__'


class CitySupervisorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = CitySupervisor
        fields = '__all__'


class SuperAdminSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = SuperAdmin
        fields = '__all__'


class JahadInspectorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = JahadInspector
        fields = '__all__'


class VetSupervisorForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    vet = VetSerializer(read_only=True)

    class Meta:
        model = VetSupervisor
        fields = ['address', 'vet']


class VetCheckAllocationsSerializer(serializers.ModelSerializer):
    vet = VetSerializer(read_only=True)
    province_kill_request = ProvinceKillRequestSerializer(read_only=True)

    class Meta:
        model = VetCheckAllocations
        fields = '__all__'


# سریالایزر مربوط به آنالیز قیمت
class PriceAnalysisorSerializer(serializers.ModelSerializer):
    class Meta:
        model = PriceAnalysis
        fields = '__all__'


class ShareOfAllocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = ShareOfAllocation
        fields = '__all__'


class PaymentDeadLineSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentDeadLine
        fields = '__all__'


class MonthlyProfitPercentageSerializer(serializers.ModelSerializer):
    class Meta:
        model = MonthlyProfitPercentage
        fields = '__all__'


# سریالایزر مربوط به ثبت در خواست مرغ منجمد
class WareHouseFactorSerializer(serializers.ModelSerializer):
    first_operator = UserProfileSerializer(read_only=True)
    second_operator = UserProfileSerializer(read_only=True)

    class Meta:
        model = WareHouseFactor
        fields = '__all__'
        # extra_kwargs = ['customer', 'national_code', 'date', 'mobile', 'product_type', 'weight', 'fee', 'wage','considerations','' ]
        extra_kwargs = {"considerations": {"required": False, "allow_null": True},
                        "Complications": {"required": False, "allow_null": True},
                        "tax": {"required": False, "allow_null": True},
                        "discount": {"required": False, "allow_null": True},
                        "name_of_bank_user": {"required": False, "allow_null": True},
                        "card": {"required": False, "allow_null": True},
                        "shaba": {"required": False, "allow_null": True},
                        "account": {"required": False, "allow_null": True}
                        }


class walletSerializer(serializers.ModelSerializer):
    class Meta:
        model = Wallet
        fields = '__all__'


class ItransactionSerializer(serializers.ModelSerializer):
    wallet = walletSerializer(read_only=True)

    class Meta:
        model = Itransaction
        fields = '__all__'


class DebtSerializer(serializers.ModelSerializer):
    class Meta:
        model = Debt
        fields = '__all__'


class PenaltySerializer(serializers.ModelSerializer):
    class Meta:
        model = Penalty
        fields = '__all__'


class DepositSerializer(serializers.ModelSerializer):
    class Meta:
        model = Deposit
        fields = '__all__'


# class IwalletSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Iwallet
#         fields = '__all__'


class FinancialDocumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = FinancialDocument
        fields = '__all__'


# class ItransactionFilter(django_filters.FilterSet):
#     class Meta:
#         model = Itransaction
#         fields = ['wallet',]

class FinancialTransactionSerializer(serializers.ModelSerializer):
    itransaction = ItransactionSerializer(read_only=True)

    class Meta:
        model = FinancialTransaction
        fields = '__all__'


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

    class Meta:
        model = Car
        fields = '__all__'


class JahadForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = Jahad
        fields = ['address', 'user_bank_info', 'identity_documents', 'active']


class CityJahadForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = CityJahad
        fields = ['address', 'user_bank_info', 'identity_documents', 'active']


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

    class Meta:
        model = CityPoultry
        fields = '__all__'


# سریالازر مربوط به جهاد
class JahadSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = Jahad
        fields = '__all__'


class PosCompanySerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)

    class Meta:
        model = PosCompany
        fields = '__all__'


# سریالازر مربوط به استانداری
class ProvincialGovernmentSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = ProvincialGovernment
        fields = '__all__'


class ProvincialGovernmentForAllUserSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = ProvincialGovernment
        fields = ['address', 'user_bank_info', 'identity_documents', 'active']


class HourLimitSerializer(serializers.ModelSerializer):
    class Meta:
        model = HourLimit
        fields = '__all__'


class KillHouseHourLimitSerializer(serializers.ModelSerializer):
    class Meta:
        model = KillHouseHourLimit
        fields = '__all__'


class PoultryAllowCityProvinceSerializer(serializers.ModelSerializer):
    poultry = PoultrySerializer(read_only=True)

    class Meta:
        model = PoultryAllowCityProvince
        fields = '__all__'


class ProvinceAllowKillHouseRegisterCarSerializer(serializers.ModelSerializer):
    kill_house = KillHouseSerializer(read_only=True)

    class Meta:
        model = ProvinceAllowKillHouseRegisterCar
        fields = '__all__'


class ProvinceAllowPoultryChooseKillHouseSerializer(serializers.ModelSerializer):
    Poultry = PoultrySerializer(read_only=True)

    class Meta:
        model = ProvinceAllowPoultryChooseKillHouse
        fields = '__all__'


class ProvinceAllowPoultryChooseKillHouseTotalSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceAllowPoultryChooseKillHouseTotal
        fields = '__all__'


class ProvinceAllowPoultrySellFreeSerializer(serializers.ModelSerializer):
    Poultry = PoultrySerializer(read_only=True)

    class Meta:
        model = ProvinceAllowPoultrySellFree
        fields = '__all__'


class ProvinceAllowPoultrySellFreeTotalSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceAllowPoultrySellFreeTotal
        fields = '__all__'


class FreeSaleWithinprovinceSerializer(serializers.ModelSerializer):
    class Meta:
        model = FreeSaleWithinprovince
        fields = ['key', 'allow', 'weight', 'percent', 'type']


class ProvinceAutoAllocationSerializer(serializers.ModelSerializer):
    poultry_request = PoultryRequestSerializer(read_only=True)
    daily_quota = KillHouseDailyQuotaSerializer(read_only=True)
    province_kill_request = ProvinceKillRequestSerializer(read_only=True)

    class Meta:
        model = ProvinceAutoAllocation
        fields = '__all__'


class StewardForGuildsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Steward
        fields = ['key']


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

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user']


class GeneralGuildsForInspectionsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user', 'type_activity', 'area_activity']


class GuildsForKillHousePercentageSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['user', 'guilds_name', 'allocation_limit', 'address']


class GuildsForStewardAutoAllocationSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['user', 'guilds_name', 'steward', 'allocation_limit', 'address', 'license_number',
                  'type_activity', 'area_activity', 'guilds_id', 'create_date']


class TotalGuildsForPosSerializer(serializers.ModelSerializer):
    class Meta:
        model = Guilds
        fields = ['key']


class GuildInfoForPosSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    products = serializers.SerializerMethodField('get_products')

    class Meta:
        model = Guilds
        fields = ['user', 'phone', 'key', 'guilds_id', 'license_number', 'guilds_name', 'type_activity',
                  'area_activity',
                  'products', 'address', 'condition', 'description_condition']

    def get_products(self, obj):
        # pos = Product.objects.filter(guild=obj,trash=False)
        products = Product.objects.filter(
            Q(general=False, guild=obj) | Q(general=True, guild__isnull=True),
            trash=False)
        serializer = ProductSerializer(products, many=True)
        return serializer.data


class POSDeviceSessionForCompaniesSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSDeviceSession
        fields = ['key', 'name', 'serial', 'password', 'session_create_date', 'session_last_seen_date']


class POSMachineForGuildsSerializer(serializers.ModelSerializer):
    pos_company = serializers.SerializerMethodField('get_pos_company')
    pos_sessions = serializers.SerializerMethodField('get_pos_sessions')
    pos_status = serializers.SerializerMethodField('get_pos_status_method')

    class Meta:
        model = POSMachine
        fields = ['pos_id', 'key', 'receiver_number', 'receiver_number', 'terminal_number', 'pos_company', 'Lat',
                  'active', 'Long', 'pos_sessions', 'pos_status', 'serial', 'password']

    def get_pos_company(self, obj):
        pos_company = PosCompany.objects.get(key=obj.pos_company.key, trash=False)
        return pos_company.name

    def get_pos_sessions(self, obj):
        pos_sessions = POSDeviceSession.objects.filter(pos=obj, trash=False)
        serializer = POSDeviceSessionForCompaniesSerializer(pos_sessions, many=True)
        return serializer.data

    def get_pos_status_method(self, obj):
        if not self.get_pos_sessions(obj):
            return False
        now = datetime.now().date() - timedelta(days=4)
        pos_sessions = POSDeviceSession.objects.filter(pos=obj, trash=False)
        active_sessions = pos_sessions.filter(session_last_seen_date__gt=now)
        active_count = active_sessions.count()
        return active_count > 0


class GuildsForInspectionSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    guild_pos = serializers.SerializerMethodField('get_guild_pos')
    number_of_pos = serializers.SerializerMethodField('get_number_of_pos')
    ware_house_info = serializers.SerializerMethodField('get_ware_house_quantity')

    class Meta:
        model = Guilds
        fields = ['user', 'key', 'guilds_id', 'license_number', 'guilds_name', 'type_activity', 'area_activity',
                  'guild_pos', 'number_of_pos', 'ware_house_info']

    def get_guild_pos(self, obj):
        pos = POSMachine.objects.filter(guild=obj, trash=False)
        serializer = POSMachineForGuildsSerializer(pos, many=True)
        return serializer.data

    def get_number_of_pos(self, obj):
        pos = POSMachine.objects.filter(guild=obj, trash=False)
        return len(pos)

    def get_ware_house_quantity(self, obj):
        try:
            ware_house = GuildsWareHouse.objects.get(guilds=obj, trash=False)
            return {
                "quantity": ware_house.remain_total_number_of_carcasses,
                "weight": ware_house.remain_total_weight_of_carcasses
            }
        except:
            return {
                "quantity": 0,
                "weight": 0
            }


class GuildsForCompaniesSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    guild_pos = serializers.SerializerMethodField('get_guild_pos')
    number_of_pos = serializers.SerializerMethodField('get_number_of_pos')

    class Meta:
        model = Guilds
        fields = ['user', 'key', 'guilds_id', 'license_number', 'guilds_name', 'type_activity', 'area_activity',
                  'guild_pos', 'number_of_pos', 'condition', 'description_condition', 'province_accept_state']

    def get_guild_pos(self, obj):
        pos = POSMachine.objects.filter(guild=obj, pos_company__name=self.context.get('company'), trash=False)
        serializer = POSMachineForGuildsSerializer(pos, many=True)
        return serializer.data

    def get_number_of_pos(self, obj):
        pos = POSMachine.objects.filter(guild=obj, trash=False)
        return len(pos)


class TypeActivitySerializer(serializers.ModelSerializer):
    class Meta:
        model = TypeActivity
        fields = ['key', 'title']


class AreaActivitySerializer(serializers.ModelSerializer):
    class Meta:
        model = AreaActivity
        fields = ['key', 'title']


class GuildsForDispenserAllocationsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)
    allocation_limit = serializers.SerializerMethodField('get_allocation_limit')

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user', 'license_number', 'type_activity', 'area_activity', 'guilds_id',
                  'allocation_limit']

    def get_allocation_limit(self, obj):
        guild = self.context.get('guild')
        if guild:
            relation = KillHouseStewardGuildRelation.objects.filter(guild=guild, steward=guild).first()
            if relation:
                return {
                    "allocation_limit": relation.allocation_limit,
                    "allocation_type": relation.allocation_type
                }
        return None


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

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward']


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

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'type_activity', 'area_activity', 'guilds_id', 'steward']


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

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user']


class GuildsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    guild_area_activity = AreaActivitySerializer(read_only=True)
    guild_type_activity = TypeActivitySerializer(read_only=True)
    kill_house = serializers.SerializerMethodField('get_kill_house')
    # kill_house = KillHouseForAutoAllocationSerializer(many=True,read_only=True)
    steward_kill_house = serializers.SerializerMethodField('get_steward_kill_house')
    # steward_kill_house = KillHouseForAutoAllocationSerializer(many=True,read_only=True)
    stewards = GuildsForDispenserAllocationsSerializer(many=True, read_only=True)

    get_pos_status = serializers.SerializerMethodField('get_pos_status_method')
    product_info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = Guilds
        fields = '__all__'

    def get_kill_house(self, obj):
        kill_houses = KillHouse.objects.filter(
            pk__in=KillHouseStewardGuildRelation.objects.filter(guild=obj).values_list('kill_house', flat=True))
        serializer = KillHouseForKillHouseGuildRelationSerializer(kill_houses, many=True, context={'guild': obj})
        return serializer.data

    def get_steward_kill_house(self, obj):
        kill_houses = KillHouse.objects.filter(
            pk__in=KillHouseStewardGuildRelation.objects.filter(guild=obj).values_list('kill_house', flat=True))
        serializer = KillHouseForKillHouseStewardRelationSerializer(kill_houses, many=True, context={'guild': obj})
        return serializer.data

    def get_pos_status_method(self, obj):
        has_pos = POSMachine.objects.filter(guild=obj).exists()
        if not has_pos:
            return {
                "len_active_sessions": 0,
                "has_pons": False,
                "has_active_pons": False,
            }
        pos_device_ids = POSMachine.objects.filter(guild=obj).values_list('id', flat=True)
        now = datetime.now().date() - timedelta(days=4)
        sessions = POSDeviceSession.objects.filter(trash=False, pos__id__in=pos_device_ids)
        active_sessions = sessions.filter(session_last_seen_date__gt=now)
        active_count = active_sessions.count()
        return {
            "len_active_sessions": active_count,
            "has_pons": has_pos,
            "has_active_pons": active_count > 0,
        }

    def get_info(self, obj):
        products = RolesProducts.objects.filter(guild=obj, trash=False).first()
        return RolesProductsSerializer(products).data


class DistributionUserLevelSerializer(serializers.ModelSerializer):
    class Meta:
        model = DistributionUserLevel
        fields = ['key', 'fa_title', 'en_title']


class RealGuildsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'user', 'guilds_name', 'type_activity', 'area_activity',
                  ]


class RealGuildsForDashboardSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)
    ware_house_info = serializers.SerializerMethodField('get_ware_house_info')
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'user', 'guilds_name', 'steward', 'ware_house_info', 'address']

    def get_ware_house_info(self, obj):

        date1 = self.context.get('request').GET.get('date1')
        date2 = self.context.get('request').GET.get('date2')
        product = RolesProducts.objects.filter(guild=obj, trash=False, name='مرغ گرم').first()

        if date1:
            date1 = datetime.strptime(str(date1), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(date2), '%Y-%m-%d').date()

            allocations = StewardAllocation.objects.filter(
                Q(steward=obj) | Q(to_steward=obj),
                trash=False, calculate_status=True, to_cold_house__isnull=True,
                date__date__gte=date1, date__date__lte=date2, warehouse=True, steward_warehouse=True)

            free_bars = StewardFreeBarInformation.objects.filter(trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2, steward=obj, warehouse=True)
            free_sale_bars = StewardFreeSaleBarInformation.objects.filter(trash=False, date__date__gte=date1,
                                                                          date__date__lte=date2, steward=obj,
                                                                          warehouse=True)
            segmentations = PosSegmentation.objects.filter(guild=obj, trash=False, warehouse=True,
                                                           date__date__gte=date1, date__date__lte=date2)
            transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
                                                               transaction__date__date__gte=date1,
                                                               transaction__date__date__lte=date2, trash=False,
                                                               warehouse=True)
            archives = WarehouseArchive.objects.filter(Q(steward=obj) | Q(guild=obj), trash=False,
                                                       date__date__gte=date1, date__lte=date2,
                                                       warehouse=True)


        else:
            allocations = StewardAllocation.objects.filter(
                Q(steward=obj) | Q(to_steward=obj),
                trash=False, calculate_status=True, to_cold_house__isnull=True, warehouse=True, steward_warehouse=True)

            free_bars = StewardFreeBarInformation.objects.filter(trash=False, steward=obj, warehouse=True)
            free_sale_bars = StewardFreeSaleBarInformation.objects.filter(trash=False, steward=obj, warehouse=True)
            segmentations = PosSegmentation.objects.filter(guild=obj, trash=False, warehouse=True)
            transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True, trash=False,
                                                               warehouse=True)
            archives = WarehouseArchive.objects.filter(Q(steward=obj) | Q(guild=obj), trash=False, warehouse=True)

        allocations_aggregates = allocations.aggregate(
            total_input_bars_count=Count('id', filter=Q(to_steward=obj)),
            total_output_bars_count=Count('id', filter=Q(steward=obj)),
            total_input_bars_weight=Sum('real_weight_of_carcasses', filter=Q(to_steward=obj)),
            total_input_governmental_bars_weight=Sum('real_weight_of_carcasses',
                                                     filter=Q(to_steward=obj, quota='governmental')),
            total_input_free_bars_weight=Sum('real_weight_of_carcasses', filter=Q(to_steward=obj, quota='free')),
            total_output_bars_weight=Sum('real_weight_of_carcasses',
                                         filter=Q(steward=obj, receiver_state__in=('pending', 'accepted'))),
            total_output_governmental_bars_weight=Sum('real_weight_of_carcasses',
                                                      filter=Q(steward=obj, receiver_state__in=('pending', 'accepted'),
                                                               quota='governmental')),
            total_output_free_bars_weight=Sum('real_weight_of_carcasses',
                                              filter=Q(steward=obj, receiver_state__in=('pending', 'accepted'),
                                                       quota='free')),
            total_input_entered_bars_weight=Sum('real_weight_of_carcasses',
                                                filter=Q(to_steward=obj, receiver_state='accepted')),

            total_input_entered_governmental_bars_weight=Sum('real_weight_of_carcasses',
                                                             filter=Q(to_steward=obj, receiver_state='accepted',
                                                                      quota='governmental')),
            total_input_entered_free_bars_weight=Sum('real_weight_of_carcasses',
                                                     filter=Q(to_steward=obj, receiver_state='accepted', quota='free')),
            total_input_entered_bars_count=Count('id', filter=Q(to_steward=obj, receiver_state='accepted'))

        )

        free_bars_aggregates = free_bars.aggregate(
            total_count=Count('id'),
            total_weight=Sum('weight_of_carcasses')
        )

        free_sale_bars_aggregates = free_sale_bars.aggregate(
            total_count=Count('id'),
            total_weight=Sum('weight_of_carcasses'),
            total_governmental_weight=Sum('weight_of_carcasses', filter=Q(quota='governmental')),
            total_free_weight=Sum('weight_of_carcasses', filter=Q(quota='free')),

        )

        segmentations_weight = \
            segmentations.aggregate(total=Sum('weight'))[
                'total'] or 0
        segmentations_governmental_weight = \
            segmentations.filter(quota='governmental').aggregate(total=Sum('weight'))[
                'total'] or 0
        segmentations_free_weight = \
            segmentations.filter(quota='free').aggregate(total=Sum('weight'))[
                'total'] or 0
        pos_allocated_weight_info = transactions.aggregate(
            pos_allocated_weight=Sum('cur_weight'),
            pos_governmental_allocated_weight=Sum('cur_weight',
                                                  filter=Q(price_approved=True)),
            pos_free_allocated_weight=Sum('cur_weight', filter=Q(price_approved=False)),

        )
        archives_info = archives.aggregate(
            archives_weight=Sum('weight'),
            archives_governmental_weight=Sum('weight',
                                             filter=Q(quota='governmental')),
            archives_free_weight=Sum('weight',
                                     filter=Q(quota='free')),

        )
        pos_allocated_weight = pos_allocated_weight_info['pos_allocated_weight'] or 0
        pos_governmental_allocated_weight = pos_allocated_weight_info['pos_governmental_allocated_weight'] or 0
        pos_free_allocated_weight = pos_allocated_weight_info['pos_free_allocated_weight'] or 0

        input_allocations_count = allocations_aggregates['total_input_bars_count'] or 0
        input_allocations_weight = allocations_aggregates['total_input_bars_weight'] or 0
        input_governmental_allocations_weight = allocations_aggregates['total_input_governmental_bars_weight'] or 0
        input_free_allocations_weight = allocations_aggregates['total_input_free_bars_weight'] or 0
        input_entered_allocations_weight = allocations_aggregates['total_input_entered_bars_weight'] or 0
        input_entered_governmental_allocations_weight = allocations_aggregates[
                                                            'total_input_entered_governmental_bars_weight'] or 0
        input_entered_free_allocations_weight = allocations_aggregates['total_input_entered_free_bars_weight'] or 0
        input_entered_allocations_count = allocations_aggregates['total_input_entered_bars_count'] or 0
        output_allocations_weight = allocations_aggregates['total_output_bars_weight'] or 0
        output_governmental_allocations_weight = allocations_aggregates['total_output_governmental_bars_weight'] or 0
        output_free_allocations_weight = allocations_aggregates['total_output_free_bars_weight'] or 0
        output_allocations_count = allocations_aggregates['total_output_bars_count'] or 0
        free_bars_weight = free_bars_aggregates['total_weight'] or 0
        free_bars_count = free_bars_aggregates['total_count'] or 0
        free_sale_bars_weight = free_sale_bars_aggregates['total_weight'] or 0
        free_sale_governmental_bars_weight = free_sale_bars_aggregates['total_governmental_weight'] or 0
        free_sale_free_bars_weight = free_sale_bars_aggregates['total_free_weight'] or 0
        free_sale_bars_count = free_sale_bars_aggregates['total_count'] or 0
        archives_weight = archives_info['archives_weight'] or 0
        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0
        remain_weight = int(
            (input_entered_allocations_weight + free_bars_weight) - (free_sale_bars_weight + output_allocations_weight))

        total_input_governmental_weight = input_entered_governmental_allocations_weight
        total_input_free_weight = input_entered_free_allocations_weight + free_bars_weight
        total_input_weight = total_input_governmental_weight + total_input_free_weight
        total_output_governmental_weight = output_governmental_allocations_weight + free_sale_governmental_bars_weight + segmentations_governmental_weight + int(
            pos_governmental_allocated_weight / 1000)
        total_output_free_weight = output_free_allocations_weight + free_sale_free_bars_weight + segmentations_free_weight + int(
            pos_free_allocated_weight / 1000)
        total_output_weight = total_output_governmental_weight + total_output_free_weight
        total_remain_weight = total_input_weight - total_output_weight
        total_remain_governmental_weight = (
                                                   total_input_governmental_weight - total_output_governmental_weight) - archives_governmental_weight if (
                                                                                                                                                                 (
                                                                                                                                                                         total_input_governmental_weight - total_output_governmental_weight) - archives_governmental_weight) > 0 else 0
        total_remain_free_weight = (total_input_free_weight - total_output_free_weight) - archives_free_weight if (
                                                                                                                          (
                                                                                                                                  total_input_free_weight - total_output_free_weight) - archives_free_weight) > 0 else 0
        last_total_remain_free_weight = ((
                                                 total_input_free_weight - total_output_free_weight) - archives_free_weight) * -1 if (
                                                                                                                                             (
                                                                                                                                                     total_input_free_weight - total_output_free_weight) - archives_free_weight) < 0 else 0
        last_total_remain_governmental_weight = (
                                                        (
                                                                total_input_governmental_weight - total_output_governmental_weight) - archives_governmental_weight) * -1 if (
                                                                                                                                                                                    (
                                                                                                                                                                                            total_input_governmental_weight - total_output_governmental_weight) - archives_governmental_weight) < 0 else 0
        last_total_remain_weight = last_total_remain_governmental_weight + last_total_remain_free_weight

        result = {
            "total_bars_weight": int(input_allocations_weight + free_bars_weight),
            "total_bars_count": free_bars_count + input_allocations_count,
            "input_bars_weight": int(input_allocations_weight),
            "input_governmental_allocations_weight": int(input_governmental_allocations_weight),
            "input_free_allocations_weight": int(input_free_allocations_weight),
            "input_bars_count": input_allocations_count,
            "total_entered_bars_weight": int(input_entered_allocations_weight + free_bars_weight),
            "input_entered_governmental_allocations_weight": int(input_entered_governmental_allocations_weight),
            "input_entered_free_allocations_weight": int(input_entered_free_allocations_weight),
            "total_entered_bars_count": input_entered_allocations_count + free_bars_count,
            "in_province_bars_count": output_allocations_count,
            "in_province_bars_weight": int(output_allocations_weight),
            "in_province_governmental_bars_weight": int(output_governmental_allocations_weight),
            "in_province_free_bars_weight": int(output_free_allocations_weight),
            "out_province_bars_count": free_sale_bars_count,
            "out_province_bars_weight": int(free_sale_bars_weight),
            "out_province_governmental_bars_weight": int(free_sale_governmental_bars_weight),
            "out_province_free_bars_weight": int(free_sale_free_bars_weight),
            "total_in_out_province_bars_weight": int(free_sale_bars_weight) + int(output_allocations_weight),
            "total_in_out_province_bars_count": output_allocations_count + free_sale_bars_count,
            "free_bars_weight": free_bars_weight,
            "free_bars_count": free_bars_count,
            "remain_weight": remain_weight,
            "segmentations_weight": segmentations_weight,
            "segmentations_governmental_weight": segmentations_governmental_weight,
            "segmentations_free_weight": segmentations_free_weight,
            "total_input_weight": total_input_weight,
            "total_input_governmental_weight": total_input_governmental_weight,
            "total_input_free_weight": total_input_free_weight,
            "total_output_weight": total_output_weight,
            "total_output_governmental_weight": total_output_governmental_weight,
            "total_output_free_weight": total_output_free_weight,
            "total_remain_weight": total_remain_weight,
            "total_remain_governmental_weight": total_remain_governmental_weight,
            "total_remain_free_weight": total_remain_free_weight,
            "last_total_remain_free_weight": last_total_remain_free_weight,
            "last_total_remain_governmental_weight": last_total_remain_governmental_weight,
            "last_total_remain_weight": last_total_remain_weight,
            "pos_allocated_weight": int(pos_allocated_weight / 1000),
            "pos_governmental_allocated_weight": int(pos_governmental_allocated_weight / 1000),
            "pos_free_allocated_weight": int(pos_free_allocated_weight / 1000),
            "archives_weight": archives_weight,
            "archives_governmental_weight": archives_governmental_weight,
            "archives_free_weight": archives_free_weight,
        }

        return result


class PosGuildsSerializer(serializers.ModelSerializer):
    shop_name = serializers.CharField(source='guilds_name', read_only=True)
    fullname = serializers.CharField(source='user.fullname', read_only=True)
    mobile = serializers.CharField(source='user.mobile', read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'shop_name', 'fullname', 'mobile', 'steward']


class ColdHouseForStewardSerializer(serializers.ModelSerializer):
    steward = GuildsForStewardMenueSerializer(read_only=True)

    class Meta:
        model = ColdHouse
        fields = ['key', 'kill_house', 'steward', 'total_input_weight', 'total_allocated_weight',
                  'total_remain_weight', 'name', 'province', 'city', 'address', 'capacity', 'active', 'broadcast',
                  'relocate']


class GuildsForTotalColdHouseSerializer(serializers.ModelSerializer):
    cold_houses_info = serializers.SerializerMethodField('get_cold_houses_info')
    fullname = serializers.CharField(source='user.fullname', read_only=True)
    mobile = serializers.CharField(source='user.mobile', read_only=True)
    province = serializers.CharField(source='user.province.name', read_only=True)
    city = serializers.CharField(source='user.city.name', read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'fullname', 'mobile', 'province', 'city', 'cold_houses_info']

    def get_cold_houses_info(self, obj):
        cold_houses = ColdHouse.objects.filter(steward=obj, trash=False)

        total_input_weight = cold_houses.aggregate(total=Sum('total_input_weight'))[
                                 'total'] or 0
        total_allocated_weight = cold_houses.aggregate(total=Sum('total_allocated_weight'))[
                                     'total'] or 0
        total_remain_weight = cold_houses.aggregate(total=Sum('total_remain_weight'))[
                                  'total'] or 0

        return {
            "total_cold_houses": len(cold_houses),
            "total_input_weight": total_input_weight,
            "total_allocated_weight": total_allocated_weight,
            "total_remain_weight": total_remain_weight,
        }


class StewardColdHousesSerializer(serializers.ModelSerializer):
    cold_houses = serializers.SerializerMethodField('get_cold_houses')

    class Meta:
        model = Guilds
        fields = ['key', 'cold_houses']

    def get_cold_houses(self, obj):
        cold_houses = ColdHouse.objects.filter(steward=obj, trash=False)
        serializer = ColdHouseForStewardSerializer(cold_houses, many=True)
        return serializer.data


class GuildsForColdHouseSerializer(serializers.ModelSerializer):
    fullname = serializers.CharField(source='user.fullname', read_only=True)
    mobile = serializers.CharField(source='user.mobile', read_only=True)
    province = serializers.CharField(source='user.province.name', read_only=True)
    city = serializers.CharField(source='user.city.name', read_only=True)

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


class GuildsForDistributionManagementSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)
    city = serializers.CharField(source='address.city.name', read_only=True)
    general_infos = serializers.SerializerMethodField('get_general_infos')
    kill_house = serializers.SerializerMethodField('get_kill_house')
    steward_kill_house = serializers.SerializerMethodField('get_steward_kill_house')
    stewards = serializers.SerializerMethodField('get_stewards')
    user_level = DistributionUserLevelSerializer(read_only=True, many=True)
    transactions = serializers.SerializerMethodField('get_transactions')

    class Meta:
        model = Guilds
        fields = ['key', 'user', 'city', 'guilds_name', 'type_activity', 'area_activity', 'steward', 'general_infos',
                  'kill_house', 'steward_kill_house', 'stewards', 'user_level', 'transactions']

    def get_kill_house(self, obj):
        kill_houses = KillHouse.objects.filter(
            pk__in=KillHouseStewardGuildRelation.objects.filter(guild=obj).values_list('kill_house', flat=True))
        serializer = KillHouseForKillHouseGuildRelationSerializer(kill_houses, many=True, context={'guild': obj})
        return serializer.data

    def get_steward_kill_house(self, obj):
        kill_houses = KillHouse.objects.filter(
            pk__in=KillHouseStewardGuildRelation.objects.filter(guild=obj).values_list('kill_house', flat=True))
        serializer = KillHouseForKillHouseStewardRelationSerializer(kill_houses, many=True, context={'guild': obj})
        return serializer.data

    def get_stewards(self, obj):
        stewards = Guilds.objects.filter(
            pk__in=KillHouseStewardGuildRelation.objects.filter(guild=obj).values_list('steward', flat=True))
        serializer = GuildsForDispenserAllocationsSerializer(stewards, many=True, context={'guild': obj})
        return serializer.data

    def get_general_infos(self, obj):

        steward_guild_relations = KillHouseStewardGuildRelation.objects.filter(Q(guild=obj) | Q(steward=obj),
                                                                               trash=False)

        if obj.steward == False:
            input_total_allocation_limit = \
                steward_guild_relations.filter(Q(kill_house__isnull=False) | Q(steward__isnull=False),
                                               guild=obj).aggregate(total=Sum('allocation_limit'))['total'] or 0
            output_total_allocation_limit = 0
        else:
            input_total_allocation_limit = \
                steward_guild_relations.filter(kill_house__isnull=False, steward=obj).aggregate(
                    total=Sum('allocation_limit'))['total'] or 0
            output_total_allocation_limit = \
                steward_guild_relations.filter(steward=obj, guild__isnull=False).aggregate(
                    total=Sum('allocation_limit'))['total'] or 0

        type_object = self.context.get('type_object')
        role_object = self.context.get('role_object')
        type = self.context.get('type')
        if type_object == 'KillHouse':
            if type == 'guild':
                relation = steward_guild_relations.filter(guild=obj, kill_house=role_object).first()
            else:
                relation = steward_guild_relations.filter(steward=obj, kill_house=role_object).first()
        else:
            relation = steward_guild_relations.filter(guild=obj, steward=role_object).first()

        return {
            "self_input_total_allocation_limit": relation.allocation_limit if relation else None,
            "self_total_allocation_type": relation.allocation_type if relation else None,
            "input_total_allocation_limit": input_total_allocation_limit,
            "output_total_allocation_limit": output_total_allocation_limit
        }

    def get_transactions(self, obj):
        transactions = PosAllocationTransactions.objects.filter(pos__guild=obj, trash=False)
        return len(transactions)


class TestGuildsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)
    kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(many=True, required=False)

    guilds_steward = serializers.SerializerMethodField('get_steward')
    stewarrd_info = serializers.SerializerMethodField('get_stewarrd_info')
    kill_house_info = serializers.SerializerMethodField('get_kill_house_info')

    class Meta:
        model = Guilds
        fields = '__all__'

    def get_steward(self, obj):
        steward = Steward.objects.filter(guilds=obj, guilds__steward=True).last()
        if steward:
            serializer = StewardForGuildsSerializer(steward)
            return serializer.data
        return None

    def get_stewarrd_info(self, obj):
        if obj.centers_allocation != None and len(obj.centers_allocation) != 0:
            import uuid
            key = obj.centers_allocation[0]['value']
            steward = Steward.objects.filter(key=uuid.UUID(key), guilds__steward=True).last()
            if steward:
                return steward.guilds.guilds_name
        return None

    def get_kill_house_info(self, obj):
        kill_house_list = []
        if obj.kill_house_centers_allocation != None:
            for kill_house in obj.kill_house_centers_allocation:
                kill_house = KillHouse.objects.get(key=kill_house['value'], trash=False)
                kill_house_list.append({
                    "name": kill_house.name,
                    "killer": kill_house.killer,
                    "mobile": kill_house.kill_house_operator.user.mobile
                })

        return kill_house_list


class GuildsWareHouseSerializer(serializers.ModelSerializer):
    guilds = GuildsSerializer(read_only=True)

    class Meta:
        model = GuildsWareHouse
        fields = '__all__'


class StewardForDispenserAllocationsSerializer(serializers.ModelSerializer):
    guilds = GuildsForDispenserAllocationsSerializer(read_only=True)

    class Meta:
        model = Steward
        fields = ['key', 'guilds']


class StewardSerializer(serializers.ModelSerializer):
    guilds = GuildsSerializer(read_only=True)
    product_info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = Steward
        fields = '__all__'

    def get_info(self, obj):
        products = RolesProducts.objects.filter(guild=obj.guilds, trash=False).first()
        return RolesProductsSerializer(products).data


class ProductForStewardFreeBarInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['key', 'name']


class StewardFreeBarInformationSerializer(serializers.ModelSerializer):
    steward = GuildsForStewardAutoAllocationSerializer(read_only=True)
    guild = GuildsForStewardAutoAllocationSerializer(read_only=True)
    product = ProductForStewardFreeBarInformationSerializer(read_only=True)

    class Meta:
        model = StewardFreeBarInformation
        fields = '__all__'


class PosStewardFreeBarInformationSerializer(serializers.ModelSerializer):
    buyer = serializers.SerializerMethodField('get_buyer')

    class Meta:
        model = StewardFreeBarInformation
        fields = ['key', 'buyer', 'kill_house_name', 'kill_house_mobile', 'province', 'city', 'date',
                  'number_of_carcasses', 'weight_of_carcasses', 'bar_image']

    def get_buyer(self, obj):
        buyer = obj.guild if obj.guild else obj.steward
        type = 'guild' if obj.guild else 'steward'
        return {
            "fullname": buyer.user.fullname,
            "mobile": buyer.user.mobile,
            "shop": buyer.guilds_name,
            "type": type,

        }


class OutProvinceCarcassesBuyerForStewardSerializer(serializers.ModelSerializer):
    steward = GeneralGuildsForInspectionsSerializer(read_only=True)

    class Meta:
        model = OutProvinceCarcassesBuyer
        fields = ['key', 'fullname', 'first_name', 'last_name', 'mobile', 'unit_name', 'city', 'province', 'active',
                  'steward']


class StewardFreeSaleBarInformationSerializer(serializers.ModelSerializer):
    buyer = OutProvinceCarcassesBuyerForStewardSerializer(read_only=True)
    guild = RealGuildsSerializer(read_only=True)
    steward = RealGuildsSerializer(read_only=True)

    class Meta:
        model = StewardFreeSaleBarInformation
        fields = '__all__'


class StewardForStewardAutoAllocationSerializer(serializers.ModelSerializer):
    guilds = GuildsForStewardAutoAllocationSerializer(read_only=True)

    class Meta:
        model = Steward
        fields = ['guilds']


class StewardWareHouseSerializer(serializers.ModelSerializer):
    steward = StewardSerializer(read_only=True)

    class Meta:
        model = StewardWareHouse
        fields = '__all__'


class StewardWareHouseForDailyBroadCastOInDetailsSerializer(serializers.ModelSerializer):
    informations = serializers.SerializerMethodField('get_informations')

    class Meta:
        model = Steward
        fields = ['informations', 'key']

    def get_informations(self, obj):
        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()
        steward_ware_houses = StewardWareHouse.objects.filter(
            Q(weight_of_carcasses__gt=0) | Q(weight_of_free_carcasses__gt=0), date__date__gte=date1,
            date__date__lte=date2, steward=obj, trash=False)

        steward_allocations = StewardAllocation.objects.filter(
            Q(type='manual') | Q(type='auto', system_registration_code=True),
            steward_ware_house__in=steward_ware_houses, receiver_state__in=('pending', 'accepted'),
            trash=False).order_by(
            'id')

        guild_allocations = steward_allocations.filter(guilds__isnull=False, trash=False)
        number_of_guild = guild_allocations.values('guilds').distinct().count() if guild_allocations else 0

        total_number_of_free_carcasses = steward_ware_houses.aggregate(total=Sum('number_of_free_carcasses'))[
            'total']
        total_free_weight_of_carcasses = steward_ware_houses.aggregate(total=Sum('weight_of_free_carcasses'))[
            'total']
        total_number_of_carcasses = steward_ware_houses.aggregate(total=Sum('number_of_carcasses'))[
            'total']
        total_weight_of_carcasses = steward_ware_houses.aggregate(total=Sum('weight_of_carcasses'))[
            'total']

        final_total_number_of_carcasses = \
            steward_ware_houses.aggregate(total=Sum('real_number_of_carcasses'))[
                'total']
        final_total_weight_of_carcasses = \
            steward_ware_houses.aggregate(total=Sum('real_weight_of_carcasses'))[
                'total']

        total_remain_quantity = \
            steward_ware_houses.aggregate(total=Sum('remain_total_number_of_carcasses'))[
                'total']

        total_remain_weight = \
            steward_ware_houses.aggregate(total=Sum('remain_total_weight_of_carcasses'))[
                'total']

        total_allocated_quantity = \
            steward_allocations.aggregate(total=Sum('real_number_of_carcasses'))[
                'total']

        total_allocated_weight = \
            steward_allocations.aggregate(total=Sum('real_weight_of_carcasses'))[
                'total']

        total_accepted_allocated_quantity = \
            steward_allocations.aggregate(total=Sum('receiver_real_number_of_carcasses'))[
                'total']

        total_accepted_allocated_weight = \
            steward_allocations.aggregate(total=Sum('receiver_real_weight_of_carcasses'))[
                'total']

        return {
            "buyers": obj.guilds.guilds_name,
            "city": obj.guilds.address.city.name,
            "incoming_quantity_of_cold_house": 0,
            "incoming_weight_of_cold_house": 0,
            "total_pre_cold_quantity": 0,
            "total_pre_cold_weight": 0,
            "total_number_of_free_carcasses": total_number_of_free_carcasses if total_number_of_free_carcasses != None else 0,
            "total_free_weight_of_carcasses": total_free_weight_of_carcasses if total_free_weight_of_carcasses != None else 0,
            "total_number_of_carcasses": total_number_of_carcasses if total_number_of_carcasses != None else 0,
            "total_weight_of_carcasses": total_weight_of_carcasses if total_weight_of_carcasses != None else 0,
            "final_total_number_of_carcasses": final_total_number_of_carcasses if final_total_number_of_carcasses != None else 0,
            "final_total_weight_of_carcasses": final_total_weight_of_carcasses if final_total_weight_of_carcasses != None else 0,
            "total_allocated_quantity": total_allocated_quantity if total_allocated_quantity != None else 0,
            "total_allocated_weight": total_allocated_weight if total_allocated_weight != None else 0,
            "total_accepted_allocated_quantity": total_accepted_allocated_quantity if total_accepted_allocated_quantity != None else 0,
            "total_accepted_allocated_weight": total_accepted_allocated_weight if total_accepted_allocated_weight != None else 0,
            "total_remain_quantity": total_remain_quantity if total_remain_quantity != None else 0,
            "total_remain_weight": total_remain_weight if total_remain_weight != None else 0,
            "number_of_guild": number_of_guild,
        }


class AutomaticStewardAllocationSerializer(serializers.ModelSerializer):
    steward = StewardForStewardAutoAllocationSerializer(read_only=True)

    # guilds = GuildsSerializer(read_only=True)
    class Meta:
        model = StewardAllocation
        fields = ['key', 'steward', 'number_of_carcasses', 'real_number_of_carcasses', 'weight_of_carcasses',
                  'real_weight_of_carcasses', 'final_registration', 'registration_code', 'system_registration_code',
                  'logged_registration_code',
                  'state', 'date']


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

    class Meta:
        model = Dispenser
        exclude = ('created_by', 'modified_by', 'user_bank_info', 'wallet', 'address', 'create_date',
                   'modify_date')


class DispenserSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    guild = GuildsForStewardAutoAllocationSerializer(read_only=True)
    kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    allocations_info = serializers.SerializerMethodField('get_allocations_info')

    class Meta:
        model = Dispenser
        exclude = ('created_by', 'modified_by', 'user_bank_info', 'wallet', 'address', 'create_date',
                   'modify_date')

    def get_allocations_info(self, obj):
        today = datetime.now().date()
        allocations = StewardAllocation.objects.filter(dispenser=obj, trash=False)
        today_allocations = allocations.filter(date__date=today)
        total_quantity = allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
        total_weight = allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
        today_quantity = today_allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
        today_weight = today_allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0

        return {
            "number_of_allocations": len(allocations),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
            "number_of_today_allocations": len(today_allocations),
            "total_today_quantity": today_quantity,
            "total_today_weight": today_weight,
        }


class NewDispenserSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)

    class Meta:
        model = Dispenser
        fields = ['key', 'user', 'in_use']


class NewDispenserSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)

    class Meta:
        model = Dispenser
        fields = ['key', 'user', 'in_use']


class DispenserAllocationSerializer(serializers.ModelSerializer):
    steward = StewardForDispenserAllocationsSerializer(read_only=True)
    guilds = GuildsForDispenserAllocationsSerializer(read_only=True)
    dispenser = DispenserForAllocationsSerializer(read_only=True)
    seller = serializers.SerializerMethodField('get_seller_info')
    index_weight = serializers.SerializerMethodField('get_index_weight')

    class Meta:
        model = StewardAllocation
        fields = '__all__'

    def get_seller_info(self, obj):
        seller_name = None
        seller_mobile = None
        seller_role = None
        if obj.steward != None:
            seller_name = obj.steward.guilds.user.fullname
            seller_mobile = obj.steward.guilds.user.mobile
            seller_role = 'Steward'
        else:
            seller_name = obj.guilds.user.fullname
            seller_mobile = obj.guilds.user.mobile
            seller_role = 'Guilds'

        return {
            "seller_name": seller_name,
            "seller_mobile": seller_mobile,
            "seller_role": seller_role
        }

    def get_index_weight(self, obj):

        index_weight = round((obj.real_weight_of_carcasses / obj.real_number_of_carcasses),
                             2) if obj.real_number_of_carcasses > 0 else 0

        return index_weight


class DispenserInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = DispenserInformation
        fields = '__all__'


class ChildNewProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewProduct
        fields = ['key', 'name']


class NewProductSerializer(serializers.ModelSerializer):
    child = ChildNewProductSerializer(many=True, read_only=True)
    parent = ChildNewProductSerializer(read_only=True)

    class Meta:
        model = NewProduct
        fields = ['key', 'name', 'parent', 'child']


class PosNewProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = NewProduct
        fields = ['key', 'name', 'sale_type', 'sale_type_package_weight', 'approved_price_status', 'approved_price',
                  'sale_limitation_status', 'selling_more_than_inventory', 'image']


class RolesProductsSerializer(serializers.ModelSerializer):
    # parent_product = NewProductSerializer(read_only=True)
    # kill_house = KillHouseForAutoAllocationSerializer (read_only=True)
    # guild = GuildsForStewardMenueSerializer (read_only=True)

    class Meta:
        model = RolesProducts
        fields = '__all__'


class RolesProductsForInspectionSerializer(serializers.ModelSerializer):
    class Meta:
        model = RolesProducts
        fields = ['name', 'total_carcasses_weight', 'real_allocated_weight',
                  'total_remain_weight']


class PosRolesProductsSerializer(serializers.ModelSerializer):
    parent_product = PosNewProductSerializer(read_only=True)
    price = serializers.SerializerMethodField('get_price')

    class Meta:
        model = RolesProducts
        fields = ['key', 'parent_product', 'name', 'total_carcasses_weight', 'real_allocated_weight',
                  'total_remain_weight', 'approved_price_status', 'price', 'segmentation_weight',
                  'pos_allocated_weight']

    def get_price(self, obj):
        broad_price = BroadcastPrice.objects.get(trash=False)
        price = obj.approved_price if broad_price.active == True else obj.free_price
        return price


class PosOtherProductsSerializer(serializers.ModelSerializer):
    class Meta:
        model = OtherProducts
        fields = ['key', 'name', 'unit', 'image', 'price', 'active']


class CombinedPosProductSerializer(serializers.ModelSerializer):
    price = serializers.SerializerMethodField('get_price')
    product_type = serializers.CharField()

    def get_price(self, obj):
        if isinstance(obj, RolesProducts):
            broad_price = BroadcastPrice.objects.filter(trash=False).first()
            # if broad_price and broad_price.active:
            #     if obj.kill_house:
            #         if obj.approved_price > 0:
            #             if obj.approved_price > obj.free_price and obj.free_price > 0:
            #                 return obj.free_price
            #             else:
            #                 return obj.approved_price
            #
            #         else:
            #             return obj.free_price
            #
            #     else:
            #
            #         if obj.guild.steward:
            #             if broad_price.steward_price > 0:
            #                 if broad_price.steward_price > obj.free_price and obj.free_price > 0:
            #                     return obj.free_price
            #                 else:
            #                     return broad_price.steward_price
            #             else:
            #                 return obj.free_price
            #         else:
            #             if broad_price.guild_price > 0:
            #                 if broad_price.guild_price > obj.free_price and obj.free_price > 0:
            #                     return obj.free_price
            #                 else:
            #                     return broad_price.guild_price
            #             else:
            #                 return obj.free_price
            if broad_price and broad_price.active:
                if obj.kill_house:
                    if broad_price.guild_price > 0:
                        if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                            return obj.free_price
                        else:
                            return broad_price.guild_price

                    else:
                        return obj.free_price

                else:

                    if obj.guild.steward:
                        if broad_price.guild_price > 0:
                            if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                                return obj.free_price
                            else:
                                return broad_price.guild_price
                        else:
                            return obj.free_price
                    else:
                        if broad_price.guild_price > 0:
                            if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                                return obj.free_price
                            else:
                                return broad_price.guild_price
                        else:
                            return obj.free_price

            return obj.free_price
        elif isinstance(obj, OtherProducts):
            return obj.price
        elif isinstance(obj, LiveStockRolseProduct):
            pos_id = self.context.get('validation_device')

            main_product = obj.parent_product
            pos = POSMachine.objects.get(pos_id=pos_id)
            share = CooperativeProductsShare.objects.get(product=main_product, cooperative=pos.cooperative, trash=False)

            return share.price + share.shipping_price + share.cooperative_price + share.company_price + share.cooperative.first_sub_cooperative_price + share.cooperative.second_sub_cooperative_price
        return None

    def to_representation(self, instance):
        if isinstance(instance, RolesProducts):

            data = {
                "key": instance.key,
                "parent_product": instance.parent_product.key,
                "product_type": "roles_product",
                "name": instance.name,
                "image": instance.parent_product.image,
                "price": self.get_price(instance),
                "price_approved": instance.approved_price_status,
                "selling_more": instance.parent_product.selling_more_than_inventory,
                "unit": 'kg',
                "total_carcasses_weight": instance.total_carcasses_weight,
                "real_allocated_weight": instance.real_allocated_weight,
                "total_remain_weight": instance.total_remain_weight,
                "segmentation_weight": instance.segmentation_weight,
                "pos_allocated_weight": instance.pos_allocated_weight,
                "active": True,
                "targetunit": "g",

            }
            return data

        elif isinstance(instance, OtherProducts):
            data = {
                "key": instance.key,
                "parent_product": None,
                "product_type": "other_product",
                "name": instance.name,
                "image": instance.image,
                "price": instance.price,
                "price_approved": False,
                "selling_more": True,
                "unit": instance.unit,
                "total_carcasses_weight": 0,
                "real_allocated_weight": 0,
                "total_remain_weight": 0,
                "segmentation_weight": 0,
                "pos_allocated_weight": 0,
                "active": instance.active,
                "targetunit": "g",

            }
            return data
        elif isinstance(instance, LiveStockRolseProduct):
            data = {
                "key": instance.key,
                "parent_product": instance.parent_product.key,
                "product_type": "stock_product",
                "name": instance.parent_product.name,
                "image": instance.parent_product.image,
                "price": self.get_price(instance),
                "price_approved": True,
                "selling_more": False,
                "unit": 'kg',
                "total_carcasses_weight": instance.total_weight,
                "real_allocated_weight": instance.total_allocated_weight,
                "total_remain_weight": instance.total_remain_weight,
                "segmentation_weight": 0,
                "pos_allocated_weight": 0,
                "active": True,
                "targetunit": "kg",

            }
            return data
        return super().to_representation(instance)
class NewCombinedPosProductSerializer(serializers.ModelSerializer):
    price = serializers.SerializerMethodField('get_price')
    product_type = serializers.CharField()

    def get_price(self, obj):
        if isinstance(obj, RolesProducts):
            broad_price = BroadcastPrice.objects.filter(trash=False).first()
            if broad_price and broad_price.active:
                if obj.kill_house:
                    if broad_price.guild_price > 0:
                        if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                            return obj.free_price
                        else:
                            return broad_price.guild_price

                    else:
                        return obj.free_price

                else:

                    if obj.guild.steward:
                        if broad_price.guild_price > 0:
                            if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                                return obj.free_price
                            else:
                                return broad_price.guild_price
                        else:
                            return obj.free_price
                    else:
                        if broad_price.guild_price > 0:
                            if broad_price.guild_price > obj.free_price and obj.free_price > 0:
                                return obj.free_price
                            else:
                                return broad_price.guild_price
                        else:
                            return obj.free_price

            return obj.free_price
        elif isinstance(obj, OtherProducts):
            return obj.price
        elif isinstance(obj, LiveStockRolseProduct):
            pos_id = self.context.get('validation_device')

            main_product = obj.parent_product
            pos = POSMachine.objects.get(pos_id=pos_id)
            share = CooperativeProductsShare.objects.get(product=main_product, cooperative=pos.cooperative, trash=False)

            return share.price + share.shipping_price + share.cooperative_price + share.company_price + share.cooperative.first_sub_cooperative_price + share.cooperative.second_sub_cooperative_price
        return None

    def to_representation(self, instance):
        if isinstance(instance, RolesProducts):

            data = {
                "key": instance.key,
                "parent_product": instance.parent_product.key,
                "product_type": "roles_product",
                "name": instance.name,
                "image": instance.parent_product.image,
                "price": self.get_price(instance),
                "price_approved": instance.approved_price_status,
                "selling_more": instance.parent_product.selling_more_than_inventory,
                "unit": 'kg',
                "total_carcasses_weight": instance.total_carcasses_weight,
                "real_allocated_weight": instance.real_allocated_weight,
                "total_remain_weight": instance.total_remain_weight,
                "segmentation_weight": instance.segmentation_weight,
                "pos_allocated_weight": instance.pos_allocated_weight,
                "active": True,
                "targetunit": "g",

            }
            return data

        elif isinstance(instance, OtherProducts):
            data = {
                "key": instance.key,
                "parent_product": None,
                "product_type": "other_product",
                "name": instance.name,
                "image": instance.image,
                "price": instance.price,
                "price_approved": False,
                "selling_more": True,
                "unit": instance.unit,
                "total_carcasses_weight": 0,
                "real_allocated_weight": 0,
                "total_remain_weight": 0,
                "segmentation_weight": 0,
                "pos_allocated_weight": 0,
                "active": instance.active,
                "targetunit": "g",

            }
            return data
        elif isinstance(instance, LiveStockRolseProduct):
            data = {
                "key": instance.key,
                "parent_product": instance.parent_product.key,
                "product_type": "stock_product",
                "name": instance.parent_product.name,
                "image": instance.parent_product.image,
                "price": self.get_price(instance),
                "price_approved": True,
                "selling_more": False,
                "unit": 'kg',
                "total_carcasses_weight": instance.total_weight,
                "real_allocated_weight": instance.total_allocated_weight,
                "total_remain_weight": instance.total_remain_weight,
                "segmentation_weight": 0,
                "pos_allocated_weight": 0,
                "active": True,
                "targetunit": "kg",

            }
            return data
        return super().to_representation(instance)


class RolesProductsForStewardAllocationsSerializer(serializers.ModelSerializer):
    # parent_product = NewProductSerializer(read_only=True)
    # kill_house = KillHouseForAutoAllocationSerializer (read_only=True)
    # guild = GuildsForStewardMenueSerializer (read_only=True)

    class Meta:
        model = RolesProducts
        fields = ['name', 'weight_average']


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

    class Meta:
        model = LiveStockSupport
        fields = ['key', 'user']


class ColdHouseSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForProvinceSerializer(read_only=True)
    steward = GuildsForStewardMenueSerializer(read_only=True)

    class Meta:
        model = ColdHouse
        fields = ['key', 'kill_house', 'steward', 'total_input_weight', 'total_allocated_weight',
                  'total_remain_weight', 'name', 'province', 'city', 'address', 'active', 'broadcast', 'relocate',
                  'capacity']


class StewardAllocationSerializer(serializers.ModelSerializer):
    # steward = StewardSerializer(read_only=True)
    product = RolesProductsForStewardAllocationsSerializer(read_only=True)
    kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    to_kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    steward = GuildsSerializer(read_only=True)
    to_steward = GuildsSerializer(read_only=True)
    # ware_house = KillHouseWareHouseSerializer(read_only=True)
    guilds = GuildsSerializer(read_only=True)
    to_guilds = GuildsSerializer(read_only=True)
    to_cold_house = ColdHouseSerializer(read_only=True)
    other_cold_house = ColdHouseSerializer(read_only=True)
    # seller = serializers.SerializerMethodField('get_seller_info')
    index_weight = serializers.SerializerMethodField('get_index_weight')
    date_timestamp = serializers.SerializerMethodField('get_date_timestamp')
    new_state = serializers.SerializerMethodField('get_new_state')
    new_receiver_state = serializers.SerializerMethodField('get_new_receiver_state')
    new_allocation_state = serializers.SerializerMethodField('get_new_allocation_state')

    class Meta:
        model = StewardAllocation
        fields = '__all__'

    # def get_seller_info(self, obj):
    #     seller_name = None
    #     seller_mobile = None
    #     seller_role = None
    #     if obj.ware_house != None:
    #         seller_name = obj.ware_house.kill_house.kill_house_operator.user.fullname
    #         seller_mobile = obj.ware_house.kill_house.kill_house_operator.user.mobile
    #         seller_role = 'KillHouse'
    #     else:
    #         seller_name = obj.steward_ware_house.steward.guilds.user.fullname
    #         seller_mobile = obj.steward_ware_house.steward.guilds.user.mobile
    #         seller_role = 'Steward'
    #
    #     return {
    #         "seller_name": seller_name,
    #         "seller_mobile": seller_mobile,
    #         "seller_role": seller_role
    #     }

    def get_index_weight(self, obj):

        index_weight = round((obj.real_weight_of_carcasses / obj.real_number_of_carcasses),
                             2) if obj.real_number_of_carcasses > 0 else 0

        return index_weight

    def get_date_timestamp(self, obj):
        ts = datetime.timestamp(obj.date)
        return int(ts)

    def get_new_state(self, obj):
        state = None
        if obj.state == 'pending':
            state = 0
        elif obj.state == 'accepted':
            state = 1
        else:
            state = -1
        return state

    def get_new_receiver_state(self, obj):
        state = None
        if obj.receiver_state == 'pending':
            state = 0
        elif obj.receiver_state == 'accepted':
            state = 1
        else:
            state = -1
        return state

    def get_new_allocation_state(self, obj):
        state = None
        if obj.allocation_state == 'pending':
            state = 0
        elif obj.allocation_state == 'accepted':
            state = 1
        else:
            state = -1
        return state


class InProvinceAllocationSerializer(serializers.ModelSerializer):
    product = RolesProductsForStewardAllocationsSerializer(read_only=True)
    kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    to_kill_house = KillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    steward = RealGuildsSerializer(read_only=True)
    to_steward = RealGuildsSerializer(read_only=True)
    guilds = RealGuildsSerializer(read_only=True)
    to_guilds = RealGuildsSerializer(read_only=True)
    steward_pos_status = serializers.SerializerMethodField()
    guild_pos_status = serializers.SerializerMethodField()

    class Meta:
        model = StewardAllocation
        exclude = ('created_by', 'modified_by', 'dispenser', 'car', 'to_cold_house', 'steward_ware_house', 'ware_house',
                   'create_date',
                   'modify_date', 'temporary_deleted', 'temporary_trash', 'calculate_status',
                   'steward_temp_key', 'role')

    def get_steward_pos_status(self, obj):
        steward = getattr(obj, 'steward', None)
        if not steward:
            return 'ندارد'
        has_paid_pos = POSTransactions.objects.filter(
            paid=True,
            pos_machine__guild=steward
        ).exists()
        return 'دارد' if has_paid_pos else 'ندارد'

    def get_guild_pos_status(self, obj):
        steward = getattr(obj, 'steward', None)
        to_guilds = getattr(obj, 'to_guilds', None)
        if not steward or not to_guilds:
            return 'ندارد'
        has_paid_pos = POSTransactions.objects.filter(
            paid=True,
            pos_machine__guild=to_guilds
        ).exists()
        return 'دارد' if has_paid_pos else 'ندارد'


class PosStewardAllocationSerializer(serializers.ModelSerializer):
    # kill_house = PosKillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    # to_kill_house = PosKillHouseForKillingInformationDiscrepancyReportSerializer(required=False)
    # steward = PosGuildsForBroadcastManagementSerializer(read_only=True)
    # to_steward = PosGuildsForBroadcastManagementSerializer(read_only=True)
    # guilds = PosGuildsForBroadcastManagementSerializer(read_only=True)
    # to_guilds = PosGuildsForBroadcastManagementSerializer(read_only=
    allocation_from = serializers.SerializerMethodField('get_allocation_from')
    allocation_to = serializers.SerializerMethodField('get_allocation_to')

    class Meta:
        model = StewardAllocation
        fields = ['key', 'allocation_from', 'allocation_to', 'real_number_of_carcasses', 'real_weight_of_carcasses',
                  'receiver_real_number_of_carcasses', 'receiver_real_weight_of_carcasses', 'sell_type',
                  'allocation_type', 'system_registration_code', 'logged_registration_code', 'receiver_state', 'date',
                  'amount', 'total_amount', 'total_amount_paid', 'total_amount_remain', 'active_expire_date_time',
                  'production_date', 'quota', 'approved_price_status']

    def get_allocation_from(self, obj):
        if obj.kill_house:

            return {
                "key": obj.kill_house.key,
                "name": obj.kill_house.name,
                "type_activity": "KillHouse",
            }
        elif obj.steward:
            return {
                "key": obj.steward.key,
                "name": obj.steward.guilds_name,
                "type_activity": "Steward",
            }

        else:
            return {
                "key": obj.guilds.key,
                "name": obj.guilds.guilds_name,
                "type_activity": "Guild",
            }

    def get_allocation_to(self, obj):
        if obj.to_kill_house:

            return {
                "key": obj.to_kill_house.key,
                "name": obj.to_kill_house.name,
                "type_activity": "KillHouse",
            }
        elif obj.to_steward:
            return {
                "key": obj.to_steward.key,
                "name": obj.to_steward.guilds_name,
                "type_activity": "Steward",
            }

        else:
            return {
                "key": obj.to_guilds.key,
                "name": obj.to_guilds.guilds_name,
                "type_activity": "Guild",
            }


class AutoAcceptProvinceKillRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = AutoAcceptProvinceKillRequest
        fields = ['allow']


class AutoMakeKillHouseRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = AutoMakeKillHouseRequest
        fields = ['allow']


class NewProvinceAutoAllocationSerializer(serializers.ModelSerializer):
    poultry_request = PoultryRequestForAutoAllocationSerializer(read_only=True)
    province_kill_request = ProvinceKillRequestForAutoAllocationSerializer(read_only=True)

    class Meta:
        model = ProvinceAutoAllocation
        fields = ['key', 'create_date', 'poultry_request', 'province_kill_request']


class KillHousePercentageOfLossesSerializer(serializers.ModelSerializer):
    class Meta:
        model = KillHousePercentageOfLosses
        fields = '__all__'


class ProvinceAllowKillHouseChooseStewardGuildsSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForProvinceSerializer(read_only=True)

    class Meta:
        model = ProvinceAllowKillHouseChooseStewardGuilds
        fields = ['key', 'kill_house', 'steward', 'guilds']


class HatchingLossesPermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = HatchingLossesPermission
        fields = ['key', 'percent', 'allow']


class WagePaymentSerializer(serializers.ModelSerializer):
    class Meta:
        model = WagePayment
        fields = '__all__'


class ProvinceAllowKillHouseDirectBuyingTotalSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceAllowKillHouseDirectBuyingTotal
        fields = ['key', 'allow']


class ProvinceAllowKillHouseDirectBuyingSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForProvinceSerializer(read_only=True)

    class Meta:
        model = ProvinceAllowKillHouseDirectBuying
        fields = ['key', 'allow', 'kill_house', 'export_status']


class ProvinceAllowKillHouseRegisterGuildsTotalSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProvinceAllowKillHouseRegisterGuildsTotal
        fields = ['key', 'allow']


class ProvinceAllowKillHouseRegisterGuildsSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForProvinceSerializer(read_only=True)

    class Meta:
        model = ProvinceAllowKillHouseRegisterGuilds
        fields = ['key', 'allow', 'kill_house']


class ObservatorySerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Observatory
        fields = '__all__'


class PosVersiontSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosVersion
        fields = '__all__'


class PosItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosItem
        fields = '__all__'


class POSIdSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSId
        fields = '__all__'


class GuildRoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = GuildRoom
        fields = '__all__'


class POSMachineForInspectionSerializer(serializers.ModelSerializer):
    guild_info = serializers.SerializerMethodField('get_guild_info')
    ware_house_info = serializers.SerializerMethodField('get_ware_house_info')

    class Meta:
        model = POSMachine
        exclude = ('created_by', 'modified_by', 'user', 'pos_company', 'kill_house', 'guild', 'steward', 'create_date',
                   'modify_date', 'trash')

    def get_guild_info(self, obj):

        return {
            "fullname": obj.user.fullname,
            "mobile": obj.user.mobile,
            "city": obj.user.city.name,
            "province": obj.user.province.name,
            "guild_name": obj.guild.guilds_name,
        }

    def get_ware_house_info(self, obj):
        try:
            ware_house = GuildsWareHouse.objects.get(guilds=obj.guild, trash=False)
            return {
                "quantity": ware_house.remain_total_number_of_carcasses,
                "weight": ware_house.remain_total_weight_of_carcasses
            }
        except:
            return {
                "quantity": 0,
                "weight": 0
            }


class PosDeviceVersionSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosDeviceVersion
        fields = '__all__'


class POSMachineSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSMachine
        fields = '__all__'


class NewPOSMachineSerializer(serializers.ModelSerializer):
    owner = serializers.SerializerMethodField('get_owner')
    company_name = serializers.CharField(source='pos_company.name', read_only=True)

    class Meta:
        model = POSMachine
        fields = '__all__'

    def get_owner(self, obj):
        result = None
        if obj.kill_house:
            result = {
                "type": "KillHouse",
                "unit_name": obj.kill_house.name,
                "fullname": obj.kill_house.kill_house_operator.user.fullname,
                "mobile": obj.kill_house.kill_house_operator.user.mobile,
                "license_number": '-',
                "steward": '-',
            }


        elif obj.steward:
            result = {
                "type": "Steward",
                "unit_name": obj.guild.guilds_name,
                "fullname": obj.guild.user.fullname,
                "mobile": obj.guild.user.mobile,
                "license_number": obj.guild.license_number,
                "steward": obj.guild.steward,
            }




        elif obj.guild:
            result = {
                "type": "Guilds",
                "unit_name": obj.guild.guilds_name,
                "fullname": obj.guild.user.fullname,
                "mobile": obj.guild.user.mobile,
                "license_number": obj.guild.license_number,
                "steward": obj.guild.steward,
            }

        else:
            pass
        return result


class POSMachineForLiveStockSerializer(serializers.ModelSerializer):
    company_name = serializers.SerializerMethodField('get_company_name')

    class Meta:
        model = POSMachine
        fields = ['company_name', 'pos_id']

    def get_company_name(self, obj):
        return obj.pos_company.name


class POSDeviceSessionSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSDeviceSession
        fields = '__all__'


class POSMachineForInspectionsSerializer(serializers.ModelSerializer):
    guild = GeneralGuildsForInspectionsSerializer(read_only=True)
    products = serializers.SerializerMethodField('get_products')
    transactions = serializers.SerializerMethodField('get_transactions')

    class Meta:
        model = POSMachine
        fields = ['key', 'pos_id', 'guild', 'products', 'transactions', 'create_date']

    def get_products(self, obj):
        products = RolesProducts.objects.filter(guild=obj.guild, trash=False).order_by('id')
        serializer = RolesProductsForInspectionSerializer(products, many=True)
        return serializer.data

    def get_transactions(self, obj):
        transactions = PosMachineTransactions.objects.filter(pos=obj, paid=True, trash=False)
        return len(transactions)


class POSMachineForTransactionInspectionsSerializer(serializers.ModelSerializer):
    guild = GeneralGuildsForInspectionsSerializer(read_only=True)

    class Meta:
        model = POSMachine
        fields = ['key', 'pos_id', 'guild']


class POSMachineForLiveStockTransactionsSerializer(serializers.ModelSerializer):
    cooperative = CooperativeForSharesSerializer(read_only=True)

    class Meta:
        model = POSMachine
        fields = ['key', 'pos_id', 'cooperative']


class POSDeviceSessionForInspectionSerializer(serializers.ModelSerializer):
    lat = serializers.FloatField(source='lot', read_only=True)
    lng = serializers.FloatField(read_only=True)
    guilds_name = serializers.CharField(source='pos.guild.guilds_name', read_only=True)

    class Meta:
        model = POSDeviceSession
        fields = ['lat', 'lng', 'guilds_name']

class POSMachineForServerSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSMachine
        fields = ['pos_id']


class POSTransactionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSTransactions
        fields = '__all__'


class EvacuationPermitSerializer(serializers.ModelSerializer):
    class Meta:
        model = EvacuationPermit
        fields = '__all__'


class SellForFreezingSerializer(serializers.ModelSerializer):
    class Meta:
        model = SellForFreezing
        fields = ['permission']


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

    class Meta:
        model = LiveStockSupport
        fields = '__all__'


class ColdHouseForRplesSerializer(serializers.ModelSerializer):
    sumation_status = serializers.SerializerMethodField('get_sumation_status')

    class Meta:
        model = ColdHouse
        fields = ['sumation_status', 'total_quantity', 'total_weight', 'name', 'key']

    def get_sumation_status(self, obj):
        allocations = ColdHouseAllocations.objects.filter(state='accepted', cold_house=obj, trash=False).order_by('id')
        accepted_quantitys = allocations.aggregate(total=Sum('accepted_quantity'))['total'] or 0
        accepted_weights = allocations.aggregate(total=Sum('accepted_weight'))['total'] or 0
        obj.total_quantity = accepted_quantitys
        obj.total_weight = accepted_weights
        obj.save()
        return "1"


class ColdHouseAllocationsSerializer(serializers.ModelSerializer):
    cold_house = ColdHouseSerializer(read_only=True)
    kill_house_request = KillHouseRequestForColdHouseAllocationsSerializer(read_only=True)

    class Meta:
        model = ColdHouseAllocations
        fields = '__all__'


class OperationLimitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = OperationLimitation
        exclude = ('id', 'key', 'create_date', 'modify_date', 'trash', 'created_by', 'modified_by')


class ApprovedPriceSerializer(serializers.ModelSerializer):
    class Meta:
        model = ApprovedPrice
        exclude = ('id', 'key', 'create_date', 'modify_date', 'trash', 'created_by', 'modified_by')


class AnnouncementsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Announcements
        exclude = ('id', 'create_date', 'modify_date', 'trash', 'created_by', 'modified_by')


class PaymentGatewayPercentageSerializer(serializers.ModelSerializer):
    class Meta:
        model = PaymentGatewayPercentage
        exclude = ('id', 'create_date', 'key', 'modify_date', 'trash', 'created_by', 'modified_by')


class TotalPaymentGatewayPercentageSerializer(serializers.ModelSerializer):
    class Meta:
        model = TotalPaymentGatewayPercentage
        exclude = ('id', 'create_date', 'key', 'modify_date', 'trash', 'created_by', 'modified_by')


class ChickenAgeRangeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ChickenAgeRange
        fields = ['active', 'maximum', 'minimum']


class TimeRangeSerializer(serializers.ModelSerializer):
    class Meta:
        model = TimeRange
        exclude = (
            'id',
            'key',
            'trash',
            'created_by',
            'modified_by',
            'create_date',
            'modify_date',
        )


class SystemWalletSerializer(serializers.ModelSerializer):
    sumation_status = serializers.SerializerMethodField('get_sumation_status')

    class Meta:
        model = SystemWallet
        exclude = (
            'id',
            'key',
            'trash',
            'created_by',
            'modified_by',
            'create_date',
            'modify_date'
        )

    def get_sumation_status(self, obj):
        status = 0
        if obj.kill_house != None:
            transactions = ExternalTransaction.objects.filter(transaction_type='wallet',
                                                              kill_house_user=obj.kill_house.kill_house_operator.user,
                                                              status='completed',
                                                              trash=False).order_by(
                'id')
            deposit_transactions = transactions.filter(type='deposit')
            withdraw_transactions = transactions.filter(type='withdraw')
            deposit = deposit_transactions.aggregate(total=Sum('amount'))['total'] or 0
            withdraw = withdraw_transactions.aggregate(total=Sum('amount'))['total'] or 0
            total = deposit - withdraw if (deposit - withdraw) > 0 else 0

            obj.balance = total
            obj.save()
            status = 1
        return status


class ShareTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ShareType
        exclude = (
            'trash',
            'created_by',
            'modified_by',
            'create_date',
            'modify_date',
        )


class PercentageForWageTypeSerializer(serializers.ModelSerializer):
    name = serializers.SerializerMethodField('get_share_name')

    class Meta:
        model = PercentageOfWageType
        exclude = (
            'id',
            'trash',
            'created_by',
            'modified_by',
            'create_date',
            'modify_date',
            'wage_type'
        )

    def get_share_name(self, obj):
        return obj.share_type.name


class WageTypeForPoultryOutProvinceRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = WageType
        exclude = (
            'id',
            'name',
            'en_name',
            'amount',
            'key',
            'trash',
            'created_by',
            'modified_by',
            'create_date',
            'modify_date'
        )


class WageTypeSerializer(serializers.ModelSerializer):
    percentages = serializers.SerializerMethodField('get_percentages')

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

    def get_percentages(self, obj):
        percentages = PercentageOfWageType.objects.filter(wage_type=obj, trash=False).order_by('id')
        serializer = PercentageForWageTypeSerializer(percentages, many=True)
        return serializer.data


class PercentageOfWageTypeSerializer(serializers.ModelSerializer):
    wage_type = WageTypeSerializer(read_only=True)

    class Meta:
        model = PercentageOfWageType
        fields = '__all__'


class SubSectorPercentageOfWageTypeSerializer(serializers.ModelSerializer):
    percentage_of_wage_type = PercentageOfWageTypeSerializer(read_only=True)

    class Meta:
        model = SubSectorPercentageOfWageType
        fields = '__all__'


class InternalTransactionSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForKillHouseVetKillHouseSerializer(read_only=True)
    parent_kill_house = KillHouseForKillHouseVetKillHouseSerializer(read_only=True)
    chain_company = ChainCompanySerializer(read_only=True)
    poultry_request = PoultryRequestForAutoAllocationSerializer(read_only=True, many=True)
    poultry = PoultryForPoultryRequestLetterSerializer(read_only=True)
    out_province_poultry_request_buyer = OutProvincePoultryRequestBuyerSerializer(read_only=True)
    payer_info = serializers.SerializerMethodField('get_payer_info')
    transaction_amount = serializers.SerializerMethodField('get_total_wage_pay')
    union_info = serializers.SerializerMethodField('get_union_info')

    class Meta:
        model = InternalTransaction
        fields = '__all__'

    def get_payer_info(self, obj):
        fullname = None
        mobile = None
        if obj.kill_house != None:
            fullname = obj.kill_house.kill_house_operator.user.fullname
            mobile = obj.kill_house.kill_house_operator.user.mobile
        elif obj.out_province_poultry_request_buyer != None:
            fullname = obj.out_province_poultry_request_buyer.user.fullname
            mobile = obj.out_province_poultry_request_buyer.user.mobile
        elif obj.chain_company != None:
            fullname = obj.chain_company.user.fullname
            mobile = obj.chain_company.user.mobile

        else:
            fullname = obj.user.fullname
            mobile = obj.user.mobile

        return {
            "fullname": fullname,
            "mobile": mobile
        }

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

        # if role == 'ProvinceOperator':
        #     amout = obj.union_share
        # elif role == 'Company':
        #     amout = obj.company_share
        # elif role == 'Guilds':
        #     amout = obj.guilds_share
        # elif role == 'SuperAdmin':
        #     amout = obj.amount - obj.other_share
        # else:
        #     amout = obj.amount

        return obj.amount

    def get_union_info(self, obj):
        user = SystemUserProfile.objects.filter(role__name='ProvinceOperator', trash=False).first()
        serializer = SystemUserProfileForFactorSerializer(user)
        return serializer.data


class PoultryOutRequestInternalTransactionSerializer(serializers.ModelSerializer):
    poultry_request = PoultryRequestForOutRequestTransactionsSerializer(read_only=True, many=True)
    poultry = PoultryForPoultryRequestLetterSerializer(read_only=True)
    out_province_poultry_request_buyer = OutProvincePoultryRequestBuyerSerializer(read_only=True)
    payer_info = serializers.SerializerMethodField('get_payer_info')

    class Meta:
        model = InternalTransaction
        fields = '__all__'

    def get_payer_info(self, obj):
        fullname = None
        mobile = None
        if obj.kill_house != None:
            fullname = obj.kill_house.kill_house_operator.user.fullname
            mobile = obj.kill_house.kill_house_operator.user.mobile
        elif obj.out_province_poultry_request_buyer != None:
            fullname = obj.out_province_poultry_request_buyer.user.fullname
            mobile = obj.out_province_poultry_request_buyer.user.mobile
        elif obj.chain_company != None:
            fullname = obj.chain_company.user.fullname
            mobile = obj.chain_company.user.mobile

        else:
            fullname = obj.user.fullname
            mobile = obj.user.mobile

        return {
            "fullname": fullname,
            "mobile": mobile
        }



# class TotalWageInformationSerializer(serializers.ModelSerializer):
#     wage_info = serializers.SerializerMethodField('get_wage_info')
#
#     class Meta:
#         model = TotalWageInformation
#         fields = ['key', 'wage_info']
#
#     def get_wage_info(self, obj):
#         before_total_out_live_buying_province_carcasses_weight = 0
#         after_total_out_live_buying_province_carcasses_weight = 0
#         before_new_out_selling = 0
#         after_new_out_selling = 0
#         company_before_total_out_live_buying_province_carcasses_price = 0
#         before_total_out_live_buying_province_carcasses_price = 0
#         company_before_total_out_live_buying_province_carcasses_weight = 0
#         extra_company_amount = 0
#         total_weight = 0
#         total_wage = 0
#         total_paid_wage = 0
#         shares_list = []
#         total_unpaid_wage = 0
#         union_total_weight = 0
#         union_total_wage = 0
#         union_total_paid_wage = 0
#         union_total_unpaid_wage = 0
#         union_province_kill_request_total_wage = 0
#         freezing_union_province_kill_request_total_wage = 0
#         union_kill_house_free_live_bar_total_wage = 0
#         union_kill_house_free_carcases_bar_total_wage = 0
#         union_chain_allocation_total_wage = 0
#         union_province_kill_request_total_weight = 0
#         freezing_union_province_kill_request_total_weight = 0
#         union_kill_house_free_live_bar_total_weight = 0
#         union_kill_house_free_carcases_bar_total_weight = 0
#         union_chain_allocation_total_weight = 0
#
#         company_total_weight = 0
#         company_total_wage = 0
#         company_total_paid_wage = 0
#         company_total_unpaid_wage = 0
#         company_province_kill_request_total_wage = 0
#         freezing_company_province_kill_request_total_wage = 0
#         company_kill_house_free_live_bar_total_wage = 0
#         company_kill_house_free_carcases_bar_total_wage = 0
#         company_chain_allocation_total_wage = 0
#         company_province_kill_request_total_weight = 0
#         freezing_company_province_kill_request_total_weight = 0
#         company_kill_house_free_live_bar_total_weight = 0
#         company_kill_house_free_carcases_bar_total_weight = 0
#         company_chain_allocation_total_weight = 0
#
#         guilds_total_weight = 0
#         guilds_total_wage = 0
#         guilds_total_paid_wage = 0
#         guilds_total_unpaid_wage = 0
#         guilds_province_kill_request_total_wage = 0
#         freezing_guilds_province_kill_request_total_wage = 0
#         guilds_kill_house_free_live_bar_total_wage = 0
#         guilds_kill_house_free_carcases_bar_total_wage = 0
#         guilds_chain_allocation_total_wage = 0
#         guilds_province_kill_request_total_weight = 0
#         freezing_guilds_province_kill_request_total_weight = 0
#         guilds_kill_house_free_live_bar_total_weight = 0
#         guilds_kill_house_free_carcases_bar_total_weight = 0
#         guilds_chain_allocation_total_weight = 0
#
#         other_total_weight = 0
#         other_total_wage = 0
#         other_total_paid_wage = 0
#         other_total_unpaid_wage = 0
#         other_province_kill_request_total_wage = 0
#         freezing_other_province_kill_request_total_wage = 0
#         other_kill_house_free_live_bar_total_wage = 0
#         other_kill_house_free_carcases_bar_total_wage = 0
#         other_chain_allocation_total_wage = 0
#         other_province_kill_request_total_weight = 0
#         freezing_other_province_kill_request_total_weight = 0
#         other_kill_house_free_live_bar_total_weight = 0
#         other_kill_house_free_carcases_bar_total_weight = 0
#         other_chain_allocation_total_weight = 0
#
#         province_kill_request_total_wage = 0
#         province_kill_request_total_weight = 0
#         freezing_province_kill_requests_total_wage = 0
#         freezing_province_kill_requests_total_weight = 0
#         chain_total_wage = 0
#         chain_total_weight = 0
#         free_bars_live_total_wage = 0
#         free_bars_live_total_weight = 0
#         free_bars_carcases_total_wage = 0
#         free_bars_carcases_total_weight = 0
#         real_free_sale_wage = 0
#         union_real_free_sale_wage = 0
#         company_real_free_sale_wage = 0
#         guilds_real_free_sale_wage = 0
#         other_real_free_sale_wage = 0
#         total_check_wage = 0
#         union_wage_percent = 0
#         company_wage_percent = 0
#         guilds_wage_percent = 0
#         other_wage_percent = 0
#         date1 = None
#         date2 = None
#         role = None
#         if self.context:
#             role = self.context.get('request').GET.get('role')
#             if self.context.get('request').GET.get('date1'):
#                 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()
#
#         wage_type = WageType.objects.filter(en_name='province-kill-request').first()
#         total_check_wage = wage_type.amount
#         percentages_wage_type = PercentageOfWageType.objects.filter(wage_type=wage_type, percent__gt=0, trash=False)
#         for percentage_wage_type in percentages_wage_type:
#             if percentage_wage_type.share_type.en_name == 'union':
#                 union_wage_percent = percentage_wage_type.percent / 100
#             elif percentage_wage_type.share_type.en_name == 'company':
#                 company_wage_percent = percentage_wage_type.percent / 100
#
#             elif percentage_wage_type.share_type.en_name == 'guilds':
#                 guilds_wage_percent = percentage_wage_type.percent / 100
#             elif percentage_wage_type.share_type.en_name in ['city', 'wallet']:
#                 pass
#             else:
#                 other_wage_percent = percentage_wage_type.percent / 100
#         total_wage_type = WageType.objects.filter(trash=False)
#         province_live_wage_amount = total_wage_type.filter(en_name='province-kill-request', trash=False).first().amount
#         free_buying_live_weight_amount = total_wage_type.filter(en_name='live-buy', trash=False).first().amount
#         free_buying_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-buy', trash=False).first().amount
#         free_sell_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-sell', trash=False).first().amount
#         out_province_poultry_request_wage_amount = total_wage_type.filter(en_name='poultry-sell-out-province',
#                                                                           trash=False).first().amount
#
#         if role == 'KillHouse':
#             try:
#                 user = SystemUserProfile.objects.get(user=self.context.get('request').user)
#             except:
#                 user = SystemUserProfile.objects.get(key=self.context.get('request').GET['key'])
#             kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
#             # if date1:
#             #     finance_info = get_finance_info(kill_house, date1, date2)
#             #     slaughter_transactions = InternalTransaction.objects.filter(
#             #         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), date__date__gte=date1,
#             #         date__date__lte=date2, status='completed',
#             #         trash=False)
#             #
#             # else:
#             #     finance_info = get_finance_info(kill_house)
#             #     slaughter_transactions = InternalTransaction.objects.filter(
#             #         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), status='completed',
#             #         trash=False)
#             if date1:
#                 finance_info = get_finance_info(kill_house, date1, date2)
#                 if kill_house.killer and kill_house.type == 'public':
#                     slaughter_transactions = InternalTransaction.objects.filter(
#                         kill_house=kill_house,parent_kill_house=kill_house, date__date__gte=date1,
#                         date__date__lte=date2, status='completed',
#                         trash=False)
#                 else:
#                     slaughter_transactions = InternalTransaction.objects.filter(
#                         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), date__date__gte=date1,
#                         date__date__lte=date2, status='completed',
#                         trash=False)
#
#             else:
#                 finance_info = get_finance_info(kill_house)
#                 if kill_house.killer and kill_house.type == 'public':
#
#                     slaughter_transactions = InternalTransaction.objects.filter(
#                         kill_house=kill_house,parent_kill_house=kill_house, status='completed',
#                         trash=False)
#                 else:
#                     slaughter_transactions = InternalTransaction.objects.filter(
#                         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), status='completed',
#                         trash=False)
#
#             total_paid_wage += slaughter_transactions.aggregate(total=Sum('amount'))[
#                                    'total'] or 0
#
#             return {
#                 "wage_counting_type": wage_counting_type,
#                 "total_wage": finance_info['total_price'],
#                 "total_paid_wage": total_paid_wage,
#                 "off": kill_house.off,
#                 "total_unpaid_wage": finance_info['total_price'] - (total_paid_wage + kill_house.off),
#                 "province_kill_requests_total_wage": finance_info['total_pure_province_carcasses_price'],
#                 "province_kill_requests_total_weight": finance_info['total_pure_province_carcasses_weight'],
#                 "free_bars_live_total_wage": finance_info['total_out_live_buying_province_carcasses_price'],
#                 "free_bars_live_total_weight": finance_info['total_out_live_buying_province_carcasses_weight'],
#                 "free_bars_carcases_total_wage": finance_info['total_out_carcasses_buying_province_carcasses_price'],
#                 "free_bars_carcases_total_weight": finance_info['total_out_carcasses_buying_province_carcasses_weight'],
#                 "free_bars_out_province_carcases_total_wage": finance_info[
#                     'total_out_selling_province_carcasses_price'],
#                 "free_bars_out_province_carcases_total_weight": finance_info[
#                     'total_out_selling_province_carcasses_weight'],
#                 "total_province_live_weight": finance_info['total_province_live_weight'],
#                 "total_province_carcasses_weight": finance_info['total_province_carcasses_weight'],
#                 "province_live_wage_amount": province_live_wage_amount,
#                 "free_buying_live_weight_amount": free_buying_live_weight_amount,
#                 "free_buying_carcesses_weight_amount": free_buying_carcesses_weight_amount,
#                 "free_sell_carcesses_weight_amount": free_sell_carcesses_weight_amount,
#                 "finance_info": finance_info,
#                 "return_total_province_live_weight": finance_info['return_total_province_live_weight'],
#                 "total_return_pure_province_carcasses_price": finance_info[
#                     'total_return_pure_province_carcasses_price'],
#             }
#
#         elif role == 'ChainCompany':
#             try:
#                 user = SystemUserProfile.objects.get(user=self.context.get('request').user)
#             except:
#                 user = SystemUserProfile.objects.get(key=self.context.get('request').GET['key'])
#             chain_company = ChainCompany.objects.get(user=user, trash=False)
#             chain_allocations = ChainAllocation.objects.filter(chain_company=chain_company, state='accepted',
#                                                                trash=False)
#             chain_allocations_total_wage = chain_allocations.aggregate(total=Sum('total_wage_amount'))[
#                                                'total'] or 0
#             total_wage += chain_allocations_total_wage
#             chain_allocations_total_weight = chain_allocations.aggregate(total=Sum('weight'))[
#                                                  'total'] or 0
#             total_weight += chain_allocations_total_weight
#
#             chain_company_transactions = InternalTransaction.objects.filter(chain_company=chain_company,
#                                                                             status='completed', trash=False)
#             total_paid_wage += chain_company_transactions.aggregate(total=Sum('amount'))[
#                                    'total'] or 0
#
#             return {
#                 "total_weight": total_weight,
#                 "total_wage": total_wage,
#                 "chain_allocations_total_wage": chain_allocations_total_wage,
#                 "chain_allocations_total_weight": chain_allocations_total_weight,
#                 "total_paid_wage": total_paid_wage,
#                 "total_unpaid_wage": total_wage - total_paid_wage
#             }
#
#
#
#
#         else:
#             kill_houses = KillHouse.objects.filter(out_province=False, trash=False).order_by('id')
#             if date1:
#
#                 province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user__in=kill_houses, trash=False,
#                                                                             archive_wage=False,
#                                                                             return_to_province=False,
#                                                                             state__in=('pending', 'accepted'),
#                                                                             kill_request__recive_date__date__gte=date1,
#                                                                             kill_request__recive_date__date__lte=date2,
#                                                                             first_car_allocated_quantity=0).order_by(
#                     'id')
#                 return_province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user__in=kill_houses,
#                                                                                    trash=True, return_trash=True,
#                                                                                    archive_wage=False,
#                                                                                    return_to_province=False,
#                                                                                    state__in=('pending', 'accepted'),
#                                                                                    kill_request__recive_date__date__gte=date1,
#                                                                                    kill_request__recive_date__date__lte=date2,
#                                                                                    first_car_allocated_quantity=0).order_by(
#                     'id')
#                 kill_house_requests = KillHouseRequest.objects.filter(
#                     Q(Q(killhouse_user__in=kill_houses) & Q(killer__in=kill_houses)) | Q(
#                         Q(killhouse_user__in=kill_houses) & Q(killer__isnull=True)) | Q(
#                         Q(killhouse_user__in=kill_houses) | Q(killer__in=kill_houses)), archive_wage=False,
#                     kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2,
#                     trash=False, calculate_status=True
#                 )
#                 return_kill_house_requests = KillHouseRequest.objects.filter(
#                     Q(Q(killhouse_user__in=kill_houses) & Q(killer__in=kill_houses)) | Q(
#                         Q(killhouse_user__in=kill_houses) & Q(killer__isnull=True)) | Q(
#                         Q(killhouse_user__in=kill_houses) | Q(killer__in=kill_houses)), archive_wage=False,
#                     kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2,
#                     trash=True, return_trash=True, calculate_status=True
#                 )
#                 kill_house_free_bar_info = KillHouseFreeBarInformation.objects.filter(kill_house__in=kill_houses,
#                                                                                       archive_wage=False,
#                                                                                       calculate_status=True,
#                                                                                       create_date__date__gte=date1,
#                                                                                       create_date__date__lte=date2,
#                                                                                       trash=False)
#                 kill_house_free_sale_bar_info = KillHouseFreeSaleBarInformation.objects.filter(
#                     kill_house__in=kill_houses,
#                     archive_wage=False, calculate_status=True, date__date__gte=date1, date__date__lte=date2,
#                     trash=False)
#
#                 slaughter_transactions = InternalTransaction.objects.filter(
#                     kill_house__in=kill_houses, status='completed', date__date__gte=date1, date__date__lte=date2,
#                     trash=False)
#                 poultry_transactions = InternalTransaction.objects.filter(
#                     poultry__isnull=False, status='completed', date__date__gte=date1, date__date__lte=date2,
#                     trash=False)
#
#                 poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
#                                                                  province_state__in=('pending', 'accepted'), out=True,
#                                                                  out_province_request_cancel=False,
#                                                                  temporary_trash=False, send_date__date__gte=date1,
#                                                                  send_date__date__lte=date2,
#                                                                  wage_pay=True, has_wage=True,
#                                                                  temporary_deleted=False)
#                 difference_requests = BarDifferenceRequest.objects.filter(kill_house__in=kill_houses, trash=False,
#                                                                           create_date__date__gte=date1,
#                                                                           create_date__date__lte=date2,
#                                                                           state='accepted')
#             else:
#                 province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user__in=kill_houses, trash=False,
#                                                                             archive_wage=False,
#                                                                             return_to_province=False,
#                                                                             state__in=('pending', 'accepted'),
#                                                                             first_car_allocated_quantity=0).order_by(
#                     'id')
#                 return_province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user__in=kill_houses,
#                                                                                    trash=True, return_trash=True,
#                                                                                    archive_wage=False,
#                                                                                    return_to_province=False,
#                                                                                    state__in=('pending', 'accepted'),
#                                                                                    first_car_allocated_quantity=0).order_by(
#                     'id')
#                 kill_house_requests = KillHouseRequest.objects.filter(
#                     Q(Q(killhouse_user__in=kill_houses) & Q(killer__in=kill_houses)) | Q(
#                         Q(killhouse_user__in=kill_houses) & Q(killer__isnull=True)) | Q(
#                         Q(killhouse_user__in=kill_houses) | Q(killer__in=kill_houses)), archive_wage=False,
#                     trash=False, calculate_status=True
#                 )
#                 return_kill_house_requests = KillHouseRequest.objects.filter(
#                     Q(Q(killhouse_user__in=kill_houses) & Q(killer__in=kill_houses)) | Q(
#                         Q(killhouse_user__in=kill_houses) & Q(killer__isnull=True)) | Q(
#                         Q(killhouse_user__in=kill_houses) | Q(killer__in=kill_houses)), archive_wage=False,
#                     trash=True, return_trash=True, calculate_status=True
#                 )
#                 kill_house_free_bar_info = KillHouseFreeBarInformation.objects.filter(kill_house__in=kill_houses,
#                                                                                       archive_wage=False,
#                                                                                       calculate_status=True,
#                                                                                       trash=False)
#                 kill_house_free_sale_bar_info = KillHouseFreeSaleBarInformation.objects.filter(
#                     kill_house__in=kill_houses,
#                     archive_wage=False, calculate_status=True,
#                     trash=False)
#
#                 slaughter_transactions = InternalTransaction.objects.filter(
#                     kill_house__in=kill_houses, status='completed',
#                     trash=False)
#                 poultry_transactions = InternalTransaction.objects.filter(
#                     poultry__isnull=False, status='completed',
#                     trash=False)
#
#                 poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
#                                                                  province_state__in=('pending', 'accepted'), out=True,
#                                                                  out_province_request_cancel=False,
#                                                                  temporary_trash=False,
#                                                                  wage_pay=True, has_wage=True,
#                                                                  temporary_deleted=False)
#                 difference_requests = BarDifferenceRequest.objects.filter(kill_house__in=kill_houses, trash=False,
#                                                                           state='accepted')
#
#             out_province_poultry_request_weight = \
#                 poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
#                     'total'] or 0
#             out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('total_wage_amount'))[
#                                                     'total'] or 0
#             union_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('union_share'))[
#                                                           'total'] or 0
#             company_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('company_share'))[
#                                                             'total'] or 0
#             guilds_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('guilds_share'))[
#                                                            'total'] or 0
#             other_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('other_share'))[
#                                                           'total'] or 0
#
#             off = kill_houses.aggregate(total=Sum('off'))[
#                       'total'] or 0
#
#             total_paid_wage = slaughter_transactions.aggregate(total=Sum('amount'))[
#                                   'total'] or 0
#             total_paid_wage += poultry_transactions.aggregate(total=Sum('amount'))[
#                                    'total'] or 0
#
#             total_province_live_weight = province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
#                                              'total'] or 0
#             total_province_live_weight += kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0
#             # total_out_selling_province_carcasses_weight = \
#             #     kill_house_free_sale_bar_info.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0
#             # total_out_selling_province_quarantine_carcasses_weight = \
#             #     kill_house_free_sale_bar_info.aggregate(total=Sum('quarantine_weight_of_carcasses'))['total'] or 0
#
#             # sum_quarantine_carcasses_weight = \
#             #     kill_house_free_sale_bar_info.filter(quarantine_weight_of_carcasses__gt=0).aggregate(
#             #         total_weight=Sum(
#             #             Case(
#             #                 When(real_weight_of_carcasses__lt=F('quarantine_weight_of_carcasses'),
#             #                      then=F('real_weight_of_carcasses')),
#             #                 default=F('quarantine_weight_of_carcasses'),
#             #                 output_field=FloatField()
#             #             )
#             #         )
#             #     )
#             # total_out_selling_province_quarantine_carcasses_weight = sum_quarantine_carcasses_weight[
#             #                                                              'total_weight'] or 0
#
#             total_province_live_weight += \
#                 difference_requests.aggregate(total=Sum('weight'))['total'] or 0
#             difference_requests_weight = \
#                 difference_requests.aggregate(total=Sum('weight'))['total'] or 0
#             return_total_province_live_weight = \
#                 return_province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
#                     'total'] or 0
#             return_total_province_live_weight += \
#                 return_kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0
#             final_date = '2025-05-28'
#             total_out_selling_province_carcasses_weight = \
#                 kill_house_free_sale_bar_info.filter(date__date__lte=final_date).aggregate(
#                     total=Sum('real_weight_of_carcasses'))['total'] or 0
#             new_total_out_selling_province_carcasses_weight = \
#                 kill_house_free_sale_bar_info.filter(date__date__gt=final_date,
#                                                      quarantine_weight_of_carcasses__gt=0).aggregate(
#                     total_weight=Sum(
#                         Case(
#                             When(real_weight_of_carcasses__lt=F('quarantine_weight_of_carcasses'),
#                                  then=F('real_weight_of_carcasses')),
#                             default=F('quarantine_weight_of_carcasses'),
#                             output_field=FloatField()
#                         )
#                     )
#                 )
#             new_out_selling = new_total_out_selling_province_carcasses_weight['total_weight'] or 0
#
#             total_out_selling_province_carcasses_weight += new_out_selling
#
#             if wage_counting_type == 'live':
#                 total_province_carcasses_weight = total_province_live_weight
#
#                 total_pure_province_carcasses_weight = total_province_carcasses_weight
#             else:
#                 return_total_province_live_weight = int(return_total_province_live_weight * 0.75)
#                 total_province_carcasses_weight = total_province_live_weight * 0.75
#                 difference_requests_weight = difference_requests_weight * 0.75
#
#                 total_out_carcasses_buying_for_pure_province_carcasses_weight = \
#                     kill_house_free_bar_info.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
#                 if date1:
#                     total_pure_province_carcasses_weight = total_province_carcasses_weight - get_difference_carcasses_weight(
#                         kill_houses, date1, date2)
#                 else:
#                     total_pure_province_carcasses_weight = total_province_carcasses_weight - get_difference_carcasses_weight(
#                         kill_houses)
#             total_out_live_buying_province_carcasses_weight = \
#                 kill_house_free_bar_info.filter(buy_type='live').aggregate(total=Sum('live_weight'))['total'] or 0
#             real_total_out_live_buying_province_carcasses_weight = total_out_live_buying_province_carcasses_weight
#             if new_out_selling_count_wage:
#                 if out_selling_ignore:
#                     before_total_out_live_buying_province_carcasses_weight = \
#                         kill_house_free_bar_info.filter(create_date__date__lt=new_out_selling_count_wage_date,
#                                                         buy_type='live').aggregate(total=Sum('live_weight'))[
#                             'total'] or 0
#                     after_total_out_live_buying_province_carcasses_weight = \
#                         kill_house_free_bar_info.filter(create_date__date__gte=new_out_selling_count_wage_date,
#                                                         buy_type='live').aggregate(total=Sum('live_weight'))[
#                             'total'] or 0
#                     get_new_wage = get_new_wage_for_free_buying(kill_house_free_sale_bar_info)
#
#                     before_new_out_selling = get_new_wage['before_new_out_selling']
#                     after_new_out_selling = get_new_wage['after_new_out_selling']
#                     max_amount = before_total_out_live_buying_province_carcasses_weight * 0.80
#                     if max_amount <= before_new_out_selling:
#                         before_total_out_live_buying_province_carcasses_weight -= max_amount
#                     else:
#                         before_total_out_live_buying_province_carcasses_weight -= before_new_out_selling
#
#                     if after_total_out_live_buying_province_carcasses_weight > after_new_out_selling:
#                         extra_company_amount = int(after_new_out_selling * extra_company_amount)
#                         after_total_out_live_buying_province_carcasses_weight -= after_new_out_selling
#
#                     else:
#                         extra_company_amount = int(
#                             after_total_out_live_buying_province_carcasses_weight * extra_company_amount)
#
#                         after_total_out_live_buying_province_carcasses_weight = 0
#
#                     total_out_live_buying_province_carcasses_weight = before_total_out_live_buying_province_carcasses_weight + after_total_out_live_buying_province_carcasses_weight
#                     company_before_total_out_live_buying_province_carcasses_weight = before_total_out_live_buying_province_carcasses_weight
#
#             else:
#                 if out_selling_ignore:
#                     max_amount = total_out_live_buying_province_carcasses_weight * 0.80
#                     if max_amount <= new_out_selling:
#                         total_out_live_buying_province_carcasses_weight -= max_amount
#                     else:
#                         total_out_live_buying_province_carcasses_weight -= new_out_selling
#
#             total_out_carcasses_buying_province_carcasses_weight = \
#                 kill_house_free_bar_info.filter(buy_type='carcass').aggregate(total=Sum('weight_of_carcasses'))[
#                     'total'] or 0
#             total_pure_province_carcasses_price = total_pure_province_carcasses_weight * province_live_wage_amount
#             difference_requests_price = difference_requests_weight * province_live_wage_amount
#             total_return_pure_province_carcasses_price = return_total_province_live_weight * province_live_wage_amount
#             total_out_selling_province_carcasses_price = total_out_selling_province_carcasses_weight * free_sell_carcesses_weight_amount
#
#             if new_out_selling_count_wage:
#                 total_out_live_buying_province_carcasses_price = int(
#                     (before_total_out_live_buying_province_carcasses_weight * before_out_buying_count_wage_amount) + (
#                             after_total_out_live_buying_province_carcasses_weight * free_buying_live_weight_amount))
#
#                 before_total_out_live_buying_province_carcasses_price = before_total_out_live_buying_province_carcasses_weight * before_out_buying_count_wage_amount
#             else:
#                 total_out_live_buying_province_carcasses_price = total_out_live_buying_province_carcasses_weight * free_buying_live_weight_amount
#
#             # total_out_live_buying_province_carcasses_price = total_out_live_buying_province_carcasses_weight * free_buying_live_weight_amount
#             total_out_carcasses_buying_province_carcasses_price = total_out_carcasses_buying_province_carcasses_weight * free_buying_carcesses_weight_amount
#             total_price = total_pure_province_carcasses_price + total_out_selling_province_carcasses_price + total_out_live_buying_province_carcasses_price + total_out_carcasses_buying_province_carcasses_price + out_province_poultry_request_wage + extra_company_amount + total_return_pure_province_carcasses_price
#
#             percentages_wage_type = PercentageOfWageType.objects.filter(trash=False)
#             union_province_kill_request_percent = percentages_wage_type.filter(
#                 wage_type__en_name='province-kill-request', share_type__en_name='union').first().percent / 100
#             company_province_kill_request_percent = percentages_wage_type.filter(
#                 wage_type__en_name='province-kill-request', share_type__en_name='company').first().percent / 100
#             guilds_province_kill_request_percent = percentages_wage_type.filter(
#                 wage_type__en_name='province-kill-request', share_type__en_name='guilds').first().percent / 100
#             other_province_kill_request_percent = percentages_wage_type.filter(
#                 wage_type__en_name='province-kill-request', share_type__en_name='other').first().percent / 100
#
#             union_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
#                                                                           share_type__en_name='union').first().percent / 100
#             union_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
#                                                                                share_type__en_name='union').first().percent / 100
#             company_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
#                                                                             share_type__en_name='company').first().percent / 100
#             company_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
#                                                                                  share_type__en_name='company').first().percent / 100
#             guilds_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
#                                                                            share_type__en_name='guilds').first().percent / 100
#             guilds_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
#                                                                                 share_type__en_name='guilds').first().percent / 100
#             other_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
#                                                                           share_type__en_name='other').first().percent / 100
#             other_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
#                                                                                share_type__en_name='other').first().percent / 100
#
#             union_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
#                                                                              share_type__en_name='union').first().percent / 100
#             company_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
#                                                                                share_type__en_name='company').first().percent / 100
#             guilds_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
#                                                                               share_type__en_name='guilds').first().percent / 100
#             other_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
#                                                                              share_type__en_name='other').first().percent / 100
#
#             union_province_kill_request_wage = total_pure_province_carcasses_price * union_province_kill_request_percent
#             return_union_province_kill_request_wage = total_return_pure_province_carcasses_price * union_province_kill_request_percent
#             union_free_buying_live_wage = (
#                                                   total_out_live_buying_province_carcasses_price - before_total_out_live_buying_province_carcasses_price) * union_free_buying_live_percent
#             union_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * union_free_buying_carcasses_percent
#             union_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * union_free_sell_carcasses_percent
#             union_total_wage = union_province_kill_request_wage + union_free_buying_live_wage + union_free_buying_carcasses_wage + union_free_sell_carcasses_wage + union_out_province_poultry_request_wage + return_union_province_kill_request_wage
#             union_total_paid_wage = slaughter_transactions.aggregate(total=Sum('union_share'))['total'] or 0
#             union_total_paid_wage += poultry_transactions.aggregate(total=Sum('union_share'))['total'] or 0
#             union_total_unpaid_wage = union_total_wage - union_total_paid_wage
#
#             shares_list.append({
#                 "name": "اتحادیه",
#                 "out_province_poultry_request_wage": union_out_province_poultry_request_wage,
#                 "province_kill_request_wage": union_province_kill_request_wage,
#                 "return_province_kill_request_wage": return_union_province_kill_request_wage,
#                 "free_buying_live_wage": union_free_buying_live_wage,
#                 "free_buying_carcasses_wage": union_free_buying_carcasses_wage,
#                 "free_sell_carcasses_wage": union_free_sell_carcasses_wage,
#                 "total_wage": union_total_wage,
#                 "total_paid_wage": union_total_paid_wage,
#                 "total_unpaid_wage": union_total_unpaid_wage,
#
#             })
#
#             guilds_difference_requests_price = difference_requests_price * guilds_province_kill_request_percent
#             other_difference_requests_price = difference_requests_price * other_province_kill_request_percent
#             guild_return_province_kill_request_wage = total_return_pure_province_carcasses_price * guilds_province_kill_request_percent
#             other_return_province_kill_request_wage = total_return_pure_province_carcasses_price * other_province_kill_request_percent
#
#             company_province_kill_request_wage = (
#                                                          total_pure_province_carcasses_price * company_province_kill_request_percent) + (
#                                                          guilds_difference_requests_price + other_difference_requests_price)
#             return_company_province_kill_request_wage = (
#                                                                 total_return_pure_province_carcasses_price * company_province_kill_request_percent) + (
#                                                                 guild_return_province_kill_request_wage + other_return_province_kill_request_wage)
#             company_free_buying_live_wage = ((
#                                                      total_out_live_buying_province_carcasses_price - before_total_out_live_buying_province_carcasses_price) * company_free_buying_live_percent) + before_total_out_live_buying_province_carcasses_price
#             company_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * company_free_buying_carcasses_percent
#             company_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * company_free_sell_carcasses_percent
#             company_total_wage = company_province_kill_request_wage + company_free_buying_live_wage + company_free_buying_carcasses_wage + company_free_sell_carcasses_wage + company_out_province_poultry_request_wage + return_company_province_kill_request_wage
#             company_total_paid_wage = slaughter_transactions.aggregate(total=Sum('company_share'))['total'] or 0
#             company_total_paid_wage += poultry_transactions.aggregate(total=Sum('company_share'))['total'] or 0
#             # company_total_pure_paid_wage = company_total_paid_wage - (company_total_paid_wage * 0.08))
#             company_total_unpaid_wage = company_total_wage - company_total_paid_wage
#
#             shares_list.append({
#                 "name": "شرکت",
#                 "out_province_poultry_request_wage": company_out_province_poultry_request_wage,
#                 "province_kill_request_wage": company_province_kill_request_wage,
#                 "return_province_kill_request_wage": return_company_province_kill_request_wage,
#                 "free_buying_live_wage": company_free_buying_live_wage,
#                 "free_buying_carcasses_wage": company_free_buying_carcasses_wage,
#                 "free_sell_carcasses_wage": company_free_sell_carcasses_wage,
#                 "total_wage": company_total_wage,
#                 "total_paid_wage": company_total_paid_wage,
#                 "total_unpaid_wage": company_total_unpaid_wage,
#
#             })
#
#             guilds_province_kill_request_wage = (
#                                                         total_pure_province_carcasses_price * guilds_province_kill_request_percent) - guilds_difference_requests_price
#             # return_guilds_province_kill_request_wage = total_return_pure_province_carcasses_price * guilds_province_kill_request_percent
#             guilds_free_buying_live_wage = (
#                                                    total_out_live_buying_province_carcasses_price - before_total_out_live_buying_province_carcasses_price) * guilds_free_buying_live_percent
#             guilds_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * guilds_free_buying_carcasses_percent
#             guilds_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * guilds_free_sell_carcasses_percent
#             guilds_total_wage = guilds_province_kill_request_wage + guilds_free_buying_live_wage + guilds_free_buying_carcasses_wage + guilds_free_sell_carcasses_wage + guilds_out_province_poultry_request_wage
#             guilds_total_paid_wage = slaughter_transactions.aggregate(total=Sum('guilds_share'))['total'] or 0
#             guilds_total_paid_wage += poultry_transactions.aggregate(total=Sum('guilds_share'))['total'] or 0
#             guilds_total_unpaid_wage = guilds_total_wage - guilds_total_paid_wage
#
#             shares_list.append({
#                 "name": "صنف پروتئین",
#                 "out_province_poultry_request_wage": guilds_out_province_poultry_request_wage,
#                 "province_kill_request_wage": guilds_province_kill_request_wage,
#                 "return_province_kill_request_wage": 0,
#                 "free_buying_live_wage": guilds_free_buying_live_wage,
#                 "free_buying_carcasses_wage": guilds_free_buying_carcasses_wage,
#                 "free_sell_carcasses_wage": guilds_free_sell_carcasses_wage,
#                 "total_wage": guilds_total_wage,
#                 "total_paid_wage": guilds_total_paid_wage,
#                 "total_unpaid_wage": guilds_total_unpaid_wage,
#
#             })
#
#             other_province_kill_request_wage = (
#                                                        total_pure_province_carcasses_price * other_province_kill_request_percent) - other_difference_requests_price
#             # return_other_province_kill_request_wage = total_return_pure_province_carcasses_price * other_province_kill_request_percent
#             other_free_buying_live_wage = (
#                                                   total_out_live_buying_province_carcasses_price - before_total_out_live_buying_province_carcasses_price) * other_free_buying_live_percent
#             other_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * other_free_buying_carcasses_percent
#             other_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * other_free_sell_carcasses_percent
#             other_total_wage = other_province_kill_request_wage + other_free_buying_live_wage + other_free_buying_carcasses_wage + other_free_sell_carcasses_wage + other_out_province_poultry_request_wage
#             other_total_paid_wage = slaughter_transactions.aggregate(total=Sum('other_share'))['total'] or 0
#             other_total_paid_wage += poultry_transactions.aggregate(total=Sum('other_share'))['total'] or 0
#             other_total_unpaid_wage = other_total_wage - other_total_paid_wage
#
#             shares_list.append({
#                 "name": "دامپزشک",
#                 "out_province_poultry_request_wage": other_out_province_poultry_request_wage,
#                 "province_kill_request_wage": other_province_kill_request_wage,
#                 "return_province_kill_request_wage": 0,
#                 "free_buying_live_wage": other_free_buying_live_wage,
#                 "free_buying_carcasses_wage": other_free_buying_carcasses_wage,
#                 "free_sell_carcasses_wage": other_free_sell_carcasses_wage,
#                 "total_wage": other_total_wage,
#                 "total_paid_wage": other_total_paid_wage,
#                 "total_unpaid_wage": other_total_unpaid_wage,
#
#             })
#
#             return {
#                 "wage_counting_type": wage_counting_type,
#                 "total_wage": total_price,
#                 "total_paid_wage": total_paid_wage,
#                 "off": off,
#                 "total_unpaid_wage": total_price - (total_paid_wage + off),
#                 "out_province_poultry_request_weight": out_province_poultry_request_weight,
#                 "out_province_poultry_request_wage": out_province_poultry_request_wage,
#                 "province_kill_requests_total_wage": total_pure_province_carcasses_price,
#                 "province_kill_requests_total_weight": total_pure_province_carcasses_weight,
#                 "free_bars_live_total_wage": total_out_live_buying_province_carcasses_price,
#                 "free_bars_live_total_weight": real_total_out_live_buying_province_carcasses_weight,
#                 "free_bars_carcases_total_wage": total_out_carcasses_buying_province_carcasses_price,
#                 "free_bars_carcases_total_weight": total_out_carcasses_buying_province_carcasses_weight,
#                 "free_bars_out_province_carcases_total_wage": total_out_selling_province_carcasses_price,
#                 "free_bars_out_province_carcases_total_weight": total_out_selling_province_carcasses_weight,
#                 "total_province_live_weight": total_province_live_weight,
#                 "total_province_carcasses_weight": total_province_carcasses_weight,
#                 "province_live_wage_amount": province_live_wage_amount,
#                 "free_buying_live_weight_amount": free_buying_live_weight_amount,
#                 "free_buying_carcesses_weight_amount": free_buying_carcesses_weight_amount,
#                 "free_sell_carcesses_weight_amount": free_sell_carcesses_weight_amount,
#                 "out_province_poultry_request_wage_amount": out_province_poultry_request_wage_amount,
#                 "extra_company_amount": extra_company_amount,
#                 "shares": shares_list,
#                 "return_total_province_live_weight": return_total_province_live_weight,
#                 "total_return_pure_province_carcasses_price": total_return_pure_province_carcasses_price,
#             }

class TotalWageInformationSerializer(serializers.ModelSerializer):
    wage_info = serializers.SerializerMethodField('get_wage_info')

    class Meta:
        model = TotalWageInformation
        fields = ['key', 'wage_info']

    def get_wage_info(self, obj):
        before_total_out_live_buying_province_carcasses_weight = 0
        after_total_out_live_buying_province_carcasses_weight = 0
        before_new_out_selling = 0
        after_new_out_selling = 0
        company_before_total_out_live_buying_province_carcasses_price = 0
        before_total_out_live_buying_province_carcasses_price = 0
        company_before_total_out_live_buying_province_carcasses_weight = 0
        extra_company_amount = 0
        total_weight = 0
        total_wage = 0
        total_paid_wage = 0
        shares_list = []
        total_unpaid_wage = 0
        union_total_weight = 0
        union_total_wage = 0
        union_total_paid_wage = 0
        union_total_unpaid_wage = 0
        union_province_kill_request_total_wage = 0
        freezing_union_province_kill_request_total_wage = 0
        union_kill_house_free_live_bar_total_wage = 0
        union_kill_house_free_carcases_bar_total_wage = 0
        union_chain_allocation_total_wage = 0
        union_province_kill_request_total_weight = 0
        freezing_union_province_kill_request_total_weight = 0
        union_kill_house_free_live_bar_total_weight = 0
        union_kill_house_free_carcases_bar_total_weight = 0
        union_chain_allocation_total_weight = 0

        company_total_weight = 0
        company_total_wage = 0
        company_total_paid_wage = 0
        company_total_unpaid_wage = 0
        company_province_kill_request_total_wage = 0
        freezing_company_province_kill_request_total_wage = 0
        company_kill_house_free_live_bar_total_wage = 0
        company_kill_house_free_carcases_bar_total_wage = 0
        company_chain_allocation_total_wage = 0
        company_province_kill_request_total_weight = 0
        freezing_company_province_kill_request_total_weight = 0
        company_kill_house_free_live_bar_total_weight = 0
        company_kill_house_free_carcases_bar_total_weight = 0
        company_chain_allocation_total_weight = 0

        guilds_total_weight = 0
        guilds_total_wage = 0
        guilds_total_paid_wage = 0
        guilds_total_unpaid_wage = 0
        guilds_province_kill_request_total_wage = 0
        freezing_guilds_province_kill_request_total_wage = 0
        guilds_kill_house_free_live_bar_total_wage = 0
        guilds_kill_house_free_carcases_bar_total_wage = 0
        guilds_chain_allocation_total_wage = 0
        guilds_province_kill_request_total_weight = 0
        freezing_guilds_province_kill_request_total_weight = 0
        guilds_kill_house_free_live_bar_total_weight = 0
        guilds_kill_house_free_carcases_bar_total_weight = 0
        guilds_chain_allocation_total_weight = 0

        other_total_weight = 0
        other_total_wage = 0
        other_total_paid_wage = 0
        other_total_unpaid_wage = 0
        other_province_kill_request_total_wage = 0
        freezing_other_province_kill_request_total_wage = 0
        other_kill_house_free_live_bar_total_wage = 0
        other_kill_house_free_carcases_bar_total_wage = 0
        other_chain_allocation_total_wage = 0
        other_province_kill_request_total_weight = 0
        freezing_other_province_kill_request_total_weight = 0
        other_kill_house_free_live_bar_total_weight = 0
        other_kill_house_free_carcases_bar_total_weight = 0
        other_chain_allocation_total_weight = 0

        province_kill_request_total_wage = 0
        province_kill_request_total_weight = 0
        freezing_province_kill_requests_total_wage = 0
        freezing_province_kill_requests_total_weight = 0
        chain_total_wage = 0
        chain_total_weight = 0
        free_bars_live_total_wage = 0
        free_bars_live_total_weight = 0
        free_bars_carcases_total_wage = 0
        free_bars_carcases_total_weight = 0
        real_free_sale_wage = 0
        union_real_free_sale_wage = 0
        company_real_free_sale_wage = 0
        guilds_real_free_sale_wage = 0
        other_real_free_sale_wage = 0
        total_check_wage = 0
        union_wage_percent = 0
        company_wage_percent = 0
        guilds_wage_percent = 0
        other_wage_percent = 0
        date1 = None
        date2 = None
        role = None
        if self.context:
            role = self.context.get('request').GET.get('role')
            if self.context.get('request').GET.get('date1'):
                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()

        wage_type = WageType.objects.filter(en_name='province-kill-request').first()
        total_check_wage = wage_type.amount
        percentages_wage_type = PercentageOfWageType.objects.filter(wage_type=wage_type, percent__gt=0, trash=False)
        for percentage_wage_type in percentages_wage_type:
            if percentage_wage_type.share_type.en_name == 'union':
                union_wage_percent = percentage_wage_type.percent / 100
            elif percentage_wage_type.share_type.en_name == 'company':
                company_wage_percent = percentage_wage_type.percent / 100

            elif percentage_wage_type.share_type.en_name == 'guilds':
                guilds_wage_percent = percentage_wage_type.percent / 100
            elif percentage_wage_type.share_type.en_name in ['city', 'wallet']:
                pass
            else:
                other_wage_percent = percentage_wage_type.percent / 100
        total_wage_type = WageType.objects.filter(trash=False)
        province_live_wage_amount = total_wage_type.filter(en_name='province-kill-request', trash=False).first().amount
        free_buying_live_weight_amount = total_wage_type.filter(en_name='live-buy', trash=False).first().amount
        free_buying_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-buy', trash=False).first().amount
        free_sell_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-sell', trash=False).first().amount
        out_province_poultry_request_wage_amount = total_wage_type.filter(en_name='poultry-sell-out-province',
                                                                          trash=False).first().amount

        if role == 'KillHouse':
            try:
                user = SystemUserProfile.objects.get(user=self.context.get('request').user)
            except:
                user = SystemUserProfile.objects.get(key=self.context.get('request').GET['key'])
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            # if date1:
            #     finance_info = get_finance_info(kill_house, date1, date2)
            #     slaughter_transactions = InternalTransaction.objects.filter(
            #         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), date__date__gte=date1,
            #         date__date__lte=date2, status='completed',
            #         trash=False)
            #
            # else:
            #     finance_info = get_finance_info(kill_house)
            #     slaughter_transactions = InternalTransaction.objects.filter(
            #         Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), status='completed',
            #         trash=False)
            if date1:
                finance_info = get_finance_info(kill_house, date1, date2)
                if kill_house.killer and kill_house.type == 'public':
                    slaughter_transactions = InternalTransaction.objects.filter(
                        kill_house=kill_house,parent_kill_house=kill_house, date__date__gte=date1,
                        date__date__lte=date2, status='completed',
                        trash=False)
                else:
                    slaughter_transactions = InternalTransaction.objects.filter(
                        Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), date__date__gte=date1,
                        date__date__lte=date2, status='completed',
                        trash=False)

            else:
                finance_info = get_finance_info(kill_house)
                if kill_house.killer and kill_house.type == 'public':

                    slaughter_transactions = InternalTransaction.objects.filter(
                        kill_house=kill_house,parent_kill_house=kill_house, status='completed',
                        trash=False)
                else:
                    slaughter_transactions = InternalTransaction.objects.filter(
                        Q(kill_house=kill_house) | Q(parent_kill_house=kill_house), status='completed',
                        trash=False)

            total_paid_wage += slaughter_transactions.aggregate(total=Sum('amount'))[
                                   'total'] or 0

            return {
                "wage_counting_type": wage_counting_type,
                "total_wage": finance_info['total_price'],
                "total_paid_wage": total_paid_wage,
                "off": kill_house.off,
                "total_unpaid_wage": finance_info['total_price'] - (total_paid_wage + kill_house.off),
                "province_kill_requests_total_wage": finance_info['total_pure_province_carcasses_price'],
                "province_kill_requests_total_weight": finance_info['total_pure_province_carcasses_weight'],
                "free_bars_live_total_wage": finance_info['total_out_live_buying_province_carcasses_price'],
                "free_bars_live_total_weight": finance_info['total_out_live_buying_province_carcasses_weight'],
                "free_bars_carcases_total_wage": finance_info['total_out_carcasses_buying_province_carcasses_price'],
                "free_bars_carcases_total_weight": finance_info['total_out_carcasses_buying_province_carcasses_weight'],
                "free_bars_out_province_carcases_total_wage": finance_info[
                    'total_out_selling_province_carcasses_price'],
                "free_bars_out_province_carcases_total_weight": finance_info[
                    'total_out_selling_province_carcasses_weight'],
                "total_province_live_weight": finance_info['total_province_live_weight'],
                "total_province_carcasses_weight": finance_info['total_province_carcasses_weight'],
                "province_live_wage_amount": province_live_wage_amount,
                "free_buying_live_weight_amount": free_buying_live_weight_amount,
                "free_buying_carcesses_weight_amount": free_buying_carcesses_weight_amount,
                "free_sell_carcesses_weight_amount": free_sell_carcesses_weight_amount,
                "finance_info": finance_info,
                "return_total_province_live_weight": finance_info['return_total_province_live_weight'],
                "total_return_pure_province_carcasses_price": finance_info[
                    'total_return_pure_province_carcasses_price'],
            }

        elif role == 'ChainCompany':
            try:
                user = SystemUserProfile.objects.get(user=self.context.get('request').user)
            except:
                user = SystemUserProfile.objects.get(key=self.context.get('request').GET['key'])
            chain_company = ChainCompany.objects.get(user=user, trash=False)
            chain_allocations = ChainAllocation.objects.filter(chain_company=chain_company, state='accepted',
                                                               trash=False)
            chain_allocations_total_wage = chain_allocations.aggregate(total=Sum('total_wage_amount'))[
                                               'total'] or 0
            total_wage += chain_allocations_total_wage
            chain_allocations_total_weight = chain_allocations.aggregate(total=Sum('weight'))[
                                                 'total'] or 0
            total_weight += chain_allocations_total_weight

            chain_company_transactions = InternalTransaction.objects.filter(chain_company=chain_company,
                                                                            status='completed', trash=False)
            total_paid_wage += chain_company_transactions.aggregate(total=Sum('amount'))[
                                   'total'] or 0

            return {
                "total_weight": total_weight,
                "total_wage": total_wage,
                "chain_allocations_total_wage": chain_allocations_total_wage,
                "chain_allocations_total_weight": chain_allocations_total_weight,
                "total_paid_wage": total_paid_wage,
                "total_unpaid_wage": total_wage - total_paid_wage
            }




        else:

            total_wage=0
            total_paid_wage=0
            off=0
            out_province_poultry_request_weight=0
            out_province_poultry_request_wage=0
            total_pure_province_carcasses_price=0
            province_kill_requests_total_weight=0
            total_out_live_buying_province_carcasses_price=0
            free_bars_live_total_weight=0
            total_out_carcasses_buying_province_carcasses_price=0
            free_bars_carcases_total_weight=0
            total_out_selling_province_carcasses_price=0
            free_bars_out_province_carcases_total_weight=0
            total_province_live_weight=0
            total_province_carcasses_weight=0
            extra_company_amount=0
            shares_list=[]
            return_total_province_live_weight=0
            total_return_pure_province_carcasses_price=0





            total_union_province_kill_request_wage=0
            total_union_return_province_kill_request_wage=0
            total_union_free_buying_live_wage=0
            total_union_free_buying_carcasses_wage=0
            total_union_free_sell_carcasses_wage=0
            total_union_total_wage=0
            total_union_total_paid_wage=0
            total_union_total_unpaid_wage=0

            total_company_province_kill_request_wage=0
            total_company_return_province_kill_request_wage=0
            total_company_free_buying_live_wage=0
            total_company_free_buying_carcasses_wage=0
            total_company_free_sell_carcasses_wage=0
            total_company_total_wage=0
            total_company_total_paid_wage=0
            total_company_total_unpaid_wage=0


            total_guilds_province_kill_request_wage=0
            total_guilds_return_province_kill_request_wage=0
            total_guilds_free_buying_live_wage=0
            total_guilds_free_buying_carcasses_wage=0
            total_guilds_free_sell_carcasses_wage=0
            total_guilds_total_wage=0
            total_guilds_total_paid_wage=0
            total_guilds_total_unpaid_wage=0

            total_other_province_kill_request_wage=0
            total_other_return_province_kill_request_wage=0
            total_other_free_buying_live_wage=0
            total_other_free_buying_carcasses_wage=0
            total_other_free_sell_carcasses_wage=0
            total_other_total_wage=0
            total_other_total_paid_wage=0
            total_other_total_unpaid_wage=0

            if date1:
                poultry_transactions = InternalTransaction.objects.filter(
                    poultry__isnull=False, status='completed', date__date__gte=date1, date__date__lte=date2,
                    trash=False)

                poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
                                                                 province_state__in=('pending', 'accepted'), out=True,
                                                                 out_province_request_cancel=False,
                                                                 temporary_trash=False, send_date__date__gte=date1,
                                                                 send_date__date__lte=date2,
                                                                 wage_pay=True, has_wage=True,
                                                                 temporary_deleted=False)

            else:
                poultry_transactions = InternalTransaction.objects.filter(
                    poultry__isnull=False, status='completed',
                    trash=False)

                poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
                                                                 province_state__in=('pending', 'accepted'), out=True,
                                                                 out_province_request_cancel=False,
                                                                 temporary_trash=False,
                                                                 wage_pay=True, has_wage=True,
                                                                 temporary_deleted=False)


            out_province_poultry_request_weight = \
                poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                    'total'] or 0
            out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('total_wage_amount'))[
                                                    'total'] or 0
            union_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('union_share'))[
                                                          'total'] or 0
            company_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('company_share'))[
                                                            'total'] or 0
            guilds_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('guilds_share'))[
                                                           'total'] or 0
            other_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('other_share'))[
                                                          'total'] or 0
            total_paid_wage = poultry_transactions.aggregate(total=Sum('amount'))[
                                   'total'] or 0
            total_union_total_paid_wage += poultry_transactions.aggregate(total=Sum('union_share'))['total'] or 0
            total_company_total_paid_wage += poultry_transactions.aggregate(total=Sum('company_share'))['total'] or 0
            total_guilds_total_paid_wage += poultry_transactions.aggregate(total=Sum('guilds_share'))['total'] or 0
            total_other_total_paid_wage += poultry_transactions.aggregate(total=Sum('other_share'))['total'] or 0




            total_wage +=out_province_poultry_request_wage
            # kill_houses = KillHouse.objects.filter(out_province=False, trash=False).order_by('id')
            kill_house_ids = KillHousePercentage.objects.filter(kill_house__type='exclusive', trash=False).values_list(
                'kill_house', flat=True)
            kill_houses = KillHouse.objects.filter(out_province=False, trash=False).exclude(
                id__in=kill_house_ids).order_by(
                'id')
            for kill_house in kill_houses:
                finance_info =get_total_wage_info(kill_house)

                total_wage += finance_info['total_wage']
                total_paid_wage += finance_info['total_paid_wage']
                off += finance_info['off']
                # out_province_poultry_request_weight += finance_info['total_wage']
                # out_province_poultry_request_wage += finance_info['total_wage']
                total_pure_province_carcasses_price += finance_info['province_kill_requests_total_wage']
                province_kill_requests_total_weight += finance_info['province_kill_requests_total_weight']
                total_out_live_buying_province_carcasses_price += finance_info['free_bars_live_total_wage']
                free_bars_live_total_weight += finance_info['free_bars_live_total_weight']
                total_out_carcasses_buying_province_carcasses_price += finance_info['free_bars_carcases_total_wage']
                free_bars_carcases_total_weight += finance_info['free_bars_carcases_total_weight']
                total_out_selling_province_carcasses_price += finance_info['free_bars_out_province_carcases_total_wage']
                free_bars_out_province_carcases_total_weight += finance_info['free_bars_out_province_carcases_total_weight']
                total_province_live_weight += finance_info['total_province_live_weight']
                total_province_carcasses_weight += finance_info['total_province_carcasses_weight']
                extra_company_amount += finance_info['extra_company_amount']
                return_total_province_live_weight += finance_info['return_total_province_live_weight']
                total_return_pure_province_carcasses_price += finance_info['total_return_pure_province_carcasses_price']
                total_union_province_kill_request_wage += finance_info['union_province_kill_request_wage']
                total_union_return_province_kill_request_wage += finance_info['return_union_province_kill_request_wage']
                total_union_free_buying_live_wage += finance_info['union_free_buying_live_wage']
                total_union_free_buying_carcasses_wage += finance_info['union_free_buying_carcasses_wage']
                total_union_free_sell_carcasses_wage += finance_info['union_free_sell_carcasses_wage']
                total_union_total_wage += finance_info['union_total_wage']
                total_union_total_paid_wage += finance_info['union_total_paid_wage']
                total_union_total_unpaid_wage += finance_info['union_total_unpaid_wage']

                total_company_province_kill_request_wage += finance_info['company_province_kill_request_wage']
                total_company_return_province_kill_request_wage += finance_info['return_company_province_kill_request_wage']
                total_company_free_buying_live_wage += finance_info['company_free_buying_live_wage']
                total_company_free_buying_carcasses_wage += finance_info['company_free_buying_carcasses_wage']
                total_company_free_sell_carcasses_wage += finance_info['company_free_sell_carcasses_wage']
                total_company_total_wage += finance_info['company_total_wage']
                total_company_total_paid_wage += finance_info['company_total_paid_wage']
                total_company_total_unpaid_wage += finance_info['company_total_unpaid_wage']

                total_guilds_province_kill_request_wage += finance_info['guilds_province_kill_request_wage']
                total_guilds_return_province_kill_request_wage += finance_info['return_guilds_province_kill_request_wage']
                total_guilds_free_buying_live_wage += finance_info['guilds_free_buying_live_wage']
                total_guilds_free_buying_carcasses_wage += finance_info['guilds_free_buying_carcasses_wage']
                total_guilds_free_sell_carcasses_wage += finance_info['guilds_free_sell_carcasses_wage']
                total_guilds_total_wage += finance_info['guilds_total_wage']
                total_guilds_total_paid_wage += finance_info['guilds_total_paid_wage']
                total_guilds_total_unpaid_wage += finance_info['guilds_total_unpaid_wage']

                total_other_province_kill_request_wage += finance_info['other_province_kill_request_wage']
                total_other_return_province_kill_request_wage += finance_info['return_other_province_kill_request_wage']
                total_other_free_buying_live_wage += finance_info['other_free_buying_live_wage']
                total_other_free_buying_carcasses_wage += finance_info['other_free_buying_carcasses_wage']
                total_other_free_sell_carcasses_wage += finance_info['other_free_sell_carcasses_wage']
                total_other_total_wage += finance_info['other_total_wage']
                total_other_total_paid_wage += finance_info['other_total_paid_wage']
                total_other_total_unpaid_wage += finance_info['other_total_unpaid_wage']

        shares_list.append({
            "name": "اتحادیه",
            "out_province_poultry_request_wage": union_out_province_poultry_request_wage,
            "province_kill_request_wage": total_union_province_kill_request_wage,
            "return_province_kill_request_wage": total_union_return_province_kill_request_wage,
            "free_buying_live_wage": total_union_free_buying_live_wage,
            "free_buying_carcasses_wage": total_union_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": total_union_free_sell_carcasses_wage,
            "total_wage": total_union_total_wage,
            "total_paid_wage": total_union_total_paid_wage,
            "total_unpaid_wage": total_union_total_unpaid_wage,

        })

        shares_list.append({
            "name": "شرکت",
            "out_province_poultry_request_wage": company_out_province_poultry_request_wage,
            "province_kill_request_wage": total_company_province_kill_request_wage,
            "return_province_kill_request_wage": total_company_return_province_kill_request_wage,
            "free_buying_live_wage": total_company_free_buying_live_wage,
            "free_buying_carcasses_wage": total_company_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": total_company_free_sell_carcasses_wage,
            "total_wage": total_company_total_wage,
            "total_paid_wage": total_company_total_paid_wage,
            "total_unpaid_wage": total_company_total_unpaid_wage,

        })

        shares_list.append({
            "name": "صنف پروتئین",
            "out_province_poultry_request_wage": guilds_out_province_poultry_request_wage,
            "province_kill_request_wage": total_guilds_province_kill_request_wage,
            "return_province_kill_request_wage": 0,
            "free_buying_live_wage": total_guilds_free_buying_live_wage,
            "free_buying_carcasses_wage": total_guilds_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": total_guilds_free_sell_carcasses_wage,
            "total_wage": total_guilds_total_wage,
            "total_paid_wage": total_guilds_total_paid_wage,
            "total_unpaid_wage": total_guilds_total_unpaid_wage,

        })



        shares_list.append({
            "name": "دامپزشک",
            "out_province_poultry_request_wage": other_out_province_poultry_request_wage,
            "province_kill_request_wage": total_other_province_kill_request_wage,
            "return_province_kill_request_wage": 0,
            "free_buying_live_wage": total_other_free_buying_live_wage,
            "free_buying_carcasses_wage": total_other_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": total_other_free_sell_carcasses_wage,
            "total_wage": total_other_total_wage,
            "total_paid_wage": total_other_total_paid_wage,
            "total_unpaid_wage": total_other_total_unpaid_wage,

        })




        return {
            "wage_counting_type": wage_counting_type,
            "total_wage": total_wage,
            "total_paid_wage": total_paid_wage,
            "off": off,
            "total_unpaid_wage": total_wage - (total_paid_wage + off),
            "out_province_poultry_request_weight": out_province_poultry_request_weight,
            "out_province_poultry_request_wage": out_province_poultry_request_wage,
            "province_kill_requests_total_wage": total_pure_province_carcasses_price,
            "province_kill_requests_total_weight": province_kill_requests_total_weight,
            "free_bars_live_total_wage": total_out_live_buying_province_carcasses_price,
            "free_bars_live_total_weight": free_bars_live_total_weight,
            "free_bars_carcases_total_wage": total_out_carcasses_buying_province_carcasses_price,
            "free_bars_carcases_total_weight": free_bars_carcases_total_weight,
            "free_bars_out_province_carcases_total_wage": total_out_selling_province_carcasses_price,
            "free_bars_out_province_carcases_total_weight": free_bars_out_province_carcases_total_weight,
            "total_province_live_weight": total_province_live_weight,
            "total_province_carcasses_weight": total_province_carcasses_weight,
            "province_live_wage_amount": province_live_wage_amount,
            "free_buying_live_weight_amount": free_buying_live_weight_amount,
            "free_buying_carcesses_weight_amount": free_buying_carcesses_weight_amount,
            "free_sell_carcesses_weight_amount": free_sell_carcesses_weight_amount,
            "out_province_poultry_request_wage_amount": out_province_poultry_request_wage_amount,
            "extra_company_amount": extra_company_amount,
            "shares": shares_list,
            "return_total_province_live_weight": return_total_province_live_weight,
            "total_return_pure_province_carcasses_price": total_return_pure_province_carcasses_price,
        }


class ParentCompanyTotalWageInformationSerializer(serializers.ModelSerializer):
    wage_info = serializers.SerializerMethodField('get_wage_info')

    class Meta:
        model = TotalWageInformation
        fields = ['key', 'wage_info']

    def get_wage_info(self, obj):
        shares_list = []
        total_weight = 0
        total_wage = 0
        total_paid_wage = 0
        total_wage_type = WageType.objects.filter(trash=False)
        province_live_wage_amount = total_wage_type.filter(en_name='province-kill-request', trash=False).first().amount
        free_buying_live_weight_amount = total_wage_type.filter(en_name='live-buy', trash=False).first().amount
        free_buying_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-buy', trash=False).first().amount
        free_sell_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-sell', trash=False).first().amount
        out_province_poultry_request_wage_amount = total_wage_type.filter(en_name='poultry-sell-out-province',
                                                                          trash=False).first().amount

        kill_houses = KillHouse.objects.filter(out_province=False, trash=False).order_by('id')
        province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user__in=kill_houses, trash=False,
                                                                    archive_wage=False, return_to_province=False,
                                                                    state__in=('pending', 'accepted'),
                                                                    first_car_allocated_quantity=0).order_by('id')
        kill_house_requests = KillHouseRequest.objects.filter(
            Q(Q(killhouse_user__in=kill_houses) & Q(killer__in=kill_houses)) | Q(
                Q(killhouse_user__in=kill_houses) & Q(killer__isnull=True)) | Q(
                Q(killhouse_user__in=kill_houses) | Q(killer__in=kill_houses)), archive_wage=False,
            trash=False, calculate_status=True
        )
        kill_house_free_bar_info = KillHouseFreeBarInformation.objects.filter(kill_house__in=kill_houses,
                                                                              archive_wage=False, calculate_status=True,
                                                                              trash=False)
        kill_house_free_sale_bar_info = KillHouseFreeSaleBarInformation.objects.filter(
            kill_house__in=kill_houses,
            archive_wage=False, calculate_status=True,
            trash=False)

        slaughter_transactions = InternalTransaction.objects.filter(
            kill_house__in=kill_houses, status='completed',
            trash=False)

        poultry_transactions = InternalTransaction.objects.filter(
            poultry__isnull=False, status='completed',
            trash=False)

        poultry_requests = PoultryRequest.objects.filter(trash=False, state_process__in=('pending', 'accepted'),
                                                         province_state__in=('pending', 'accepted'), out=True,
                                                         out_province_request_cancel=False, temporary_trash=False,
                                                         wage_pay=True, has_wage=True,
                                                         temporary_deleted=False)

        out_province_poultry_request_weight = \
            poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                'total'] or 0
        out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('total_wage_amount'))[
                                                'total'] or 0
        union_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('union_share'))[
                                                      'total'] or 0
        company_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('company_share'))[
                                                        'total'] or 0
        guilds_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('guilds_share'))[
                                                       'total'] or 0
        other_out_province_poultry_request_wage = poultry_requests.aggregate(total=Sum('other_share'))[
                                                      'total'] or 0

        off = kill_houses.aggregate(total=Sum('off'))[
                  'total'] or 0

        total_paid_wage = slaughter_transactions.aggregate(total=Sum('amount'))[
                              'total'] or 0
        total_paid_wage += poultry_transactions.aggregate(total=Sum('amount'))[
                               'total'] or 0

        total_province_live_weight = province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
                                         'total'] or 0
        total_province_live_weight += kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0
        total_out_selling_province_carcasses_weight = \
            kill_house_free_sale_bar_info.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0
        if wage_counting_type == 'live':
            total_province_carcasses_weight = total_province_live_weight
            total_pure_province_carcasses_weight = total_province_carcasses_weight
        else:

            total_province_carcasses_weight = total_province_live_weight * 0.75
            total_out_carcasses_buying_for_pure_province_carcasses_weight = \
                kill_house_free_bar_info.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
            total_pure_province_carcasses_weight = total_province_carcasses_weight - get_difference_carcasses_weight(
                kill_houses)
        total_out_live_buying_province_carcasses_weight = \
            kill_house_free_bar_info.filter(buy_type='live').aggregate(total=Sum('live_weight'))['total'] or 0
        total_out_carcasses_buying_province_carcasses_weight = \
            kill_house_free_bar_info.filter(buy_type='carcass').aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0
        total_pure_province_carcasses_price = total_pure_province_carcasses_weight * province_live_wage_amount
        total_out_selling_province_carcasses_price = total_out_selling_province_carcasses_weight * free_sell_carcesses_weight_amount
        total_out_live_buying_province_carcasses_price = total_out_live_buying_province_carcasses_weight * free_buying_live_weight_amount
        total_out_carcasses_buying_province_carcasses_price = total_out_carcasses_buying_province_carcasses_weight * free_buying_carcesses_weight_amount
        total_price = total_pure_province_carcasses_price + total_out_selling_province_carcasses_price + total_out_live_buying_province_carcasses_price + total_out_carcasses_buying_province_carcasses_price + out_province_poultry_request_wage

        percentages_wage_type = PercentageOfWageType.objects.filter(trash=False)
        union_province_kill_request_percent = percentages_wage_type.filter(wage_type__en_name='province-kill-request',
                                                                           share_type__en_name='union').first().percent / 100
        company_province_kill_request_percent = percentages_wage_type.filter(wage_type__en_name='province-kill-request',
                                                                             share_type__en_name='company').first().percent / 100
        guilds_province_kill_request_percent = percentages_wage_type.filter(wage_type__en_name='province-kill-request',
                                                                            share_type__en_name='guilds').first().percent / 100
        other_province_kill_request_percent = percentages_wage_type.filter(wage_type__en_name='province-kill-request',
                                                                           share_type__en_name='other').first().percent / 100

        union_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
                                                                      share_type__en_name='union').first().percent / 100
        union_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
                                                                           share_type__en_name='union').first().percent / 100
        company_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
                                                                        share_type__en_name='company').first().percent / 100
        company_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
                                                                             share_type__en_name='company').first().percent / 100
        guilds_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
                                                                       share_type__en_name='guilds').first().percent / 100
        guilds_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
                                                                            share_type__en_name='guilds').first().percent / 100
        other_free_buying_live_percent = percentages_wage_type.filter(wage_type__en_name='live-buy',
                                                                      share_type__en_name='other').first().percent / 100
        other_free_buying_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-buy',
                                                                           share_type__en_name='other').first().percent / 100

        union_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                         share_type__en_name='union').first().percent / 100
        company_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                           share_type__en_name='company').first().percent / 100
        guilds_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                          share_type__en_name='guilds').first().percent / 100
        other_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                         share_type__en_name='other').first().percent / 100

        union_province_kill_request_wage = total_pure_province_carcasses_price * union_province_kill_request_percent
        union_free_buying_live_wage = total_out_live_buying_province_carcasses_price * union_free_buying_live_percent
        union_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * union_free_buying_carcasses_percent
        union_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * union_free_sell_carcasses_percent
        union_total_wage = union_province_kill_request_wage + union_free_buying_live_wage + union_free_buying_carcasses_wage + union_free_sell_carcasses_wage + union_out_province_poultry_request_wage
        union_total_paid_wage = slaughter_transactions.aggregate(total=Sum('union_share'))['total'] or 0
        union_total_paid_wage += poultry_transactions.aggregate(total=Sum('union_share'))['total'] or 0
        union_total_unpaid_wage = union_total_wage - union_total_paid_wage

        shares_list.append({
            "name": "اتحادیه",
            "out_province_poultry_request_wage": union_out_province_poultry_request_wage,
            "province_kill_request_wage": union_province_kill_request_wage,
            "free_buying_live_wage": union_free_buying_live_wage,
            "free_buying_carcasses_wage": union_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": union_free_sell_carcasses_wage,
            "total_wage": union_total_wage,
            "total_paid_wage": union_total_paid_wage,
            "total_unpaid_wage": union_total_unpaid_wage,

        })

        company_province_kill_request_wage = total_pure_province_carcasses_price * company_province_kill_request_percent
        company_free_buying_live_wage = total_out_live_buying_province_carcasses_price * company_free_buying_live_percent
        company_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * company_free_buying_carcasses_percent
        company_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * company_free_sell_carcasses_percent
        company_total_wage = company_province_kill_request_wage + company_free_buying_live_wage + company_free_buying_carcasses_wage + company_free_sell_carcasses_wage + company_out_province_poultry_request_wage
        company_total_paid_wage = slaughter_transactions.aggregate(total=Sum('company_share'))['total'] or 0
        company_total_paid_wage += poultry_transactions.aggregate(total=Sum('company_share'))['total'] or 0
        # company_total_pure_paid_wage = company_total_paid_wage - (company_total_paid_wage * 0.08))
        company_total_unpaid_wage = company_total_wage - company_total_paid_wage

        shares_list.append({
            "name": "شرکت",
            "out_province_poultry_request_wage": company_out_province_poultry_request_wage,
            "province_kill_request_wage": company_province_kill_request_wage,
            "free_buying_live_wage": company_free_buying_live_wage,
            "free_buying_carcasses_wage": company_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": company_free_sell_carcasses_wage,
            "total_wage": company_total_wage,
            "total_paid_wage": company_total_paid_wage,
            "total_unpaid_wage": company_total_unpaid_wage,

        })

        guilds_province_kill_request_wage = total_pure_province_carcasses_price * guilds_province_kill_request_percent
        guilds_free_buying_live_wage = total_out_live_buying_province_carcasses_price * guilds_free_buying_live_percent
        guilds_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * guilds_free_buying_carcasses_percent
        guilds_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * guilds_free_sell_carcasses_percent
        guilds_total_wage = guilds_province_kill_request_wage + guilds_free_buying_live_wage + guilds_free_buying_carcasses_wage + guilds_free_sell_carcasses_wage + guilds_out_province_poultry_request_wage
        guilds_total_paid_wage = slaughter_transactions.aggregate(total=Sum('guilds_share'))['total'] or 0
        guilds_total_paid_wage += poultry_transactions.aggregate(total=Sum('guilds_share'))['total'] or 0
        guilds_total_unpaid_wage = guilds_total_wage - guilds_total_paid_wage

        shares_list.append({
            "name": "صنف پروتئین",
            "out_province_poultry_request_wage": guilds_out_province_poultry_request_wage,
            "province_kill_request_wage": guilds_province_kill_request_wage,
            "free_buying_live_wage": guilds_free_buying_live_wage,
            "free_buying_carcasses_wage": guilds_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": guilds_free_sell_carcasses_wage,
            "total_wage": guilds_total_wage,
            "total_paid_wage": guilds_total_paid_wage,
            "total_unpaid_wage": guilds_total_unpaid_wage,

        })

        other_province_kill_request_wage = total_pure_province_carcasses_price * other_province_kill_request_percent
        other_free_buying_live_wage = total_out_live_buying_province_carcasses_price * other_free_buying_live_percent
        other_free_buying_carcasses_wage = total_out_carcasses_buying_province_carcasses_price * other_free_buying_carcasses_percent
        other_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * other_free_sell_carcasses_percent
        other_total_wage = other_province_kill_request_wage + other_free_buying_live_wage + other_free_buying_carcasses_wage + other_free_sell_carcasses_wage + other_out_province_poultry_request_wage
        other_total_paid_wage = slaughter_transactions.aggregate(total=Sum('other_share'))['total'] or 0
        other_total_paid_wage += poultry_transactions.aggregate(total=Sum('other_share'))['total'] or 0
        other_total_unpaid_wage = other_total_wage - other_total_paid_wage

        shares_list.append({
            "name": "دامپزشک",
            "out_province_poultry_request_wage": other_out_province_poultry_request_wage,
            "province_kill_request_wage": other_province_kill_request_wage,
            "free_buying_live_wage": other_free_buying_live_wage,
            "free_buying_carcasses_wage": other_free_buying_carcasses_wage,
            "free_sell_carcasses_wage": other_free_sell_carcasses_wage,
            "total_wage": other_total_wage,
            "total_paid_wage": other_total_paid_wage,
            "total_unpaid_wage": other_total_unpaid_wage,

        })

        return {
            "wage_counting_type": wage_counting_type,
            "total_wage": total_price,
            "total_paid_wage": total_paid_wage,
            "off": off,
            "total_unpaid_wage": total_price - (total_paid_wage + off),
            "out_province_poultry_request_weight": out_province_poultry_request_weight,
            "out_province_poultry_request_wage": out_province_poultry_request_wage,
            "province_kill_requests_total_wage": total_pure_province_carcasses_price,
            "province_kill_requests_total_weight": total_pure_province_carcasses_weight,
            "free_bars_live_total_wage": total_out_live_buying_province_carcasses_price,
            "free_bars_live_total_weight": total_out_live_buying_province_carcasses_weight,
            "free_bars_carcases_total_wage": total_out_carcasses_buying_province_carcasses_price,
            "free_bars_carcases_total_weight": total_out_carcasses_buying_province_carcasses_weight,
            "free_bars_out_province_carcases_total_wage": total_out_selling_province_carcasses_price,
            "free_bars_out_province_carcases_total_weight": total_out_selling_province_carcasses_weight,
            "total_province_live_weight": total_province_live_weight,
            "total_province_carcasses_weight": total_province_carcasses_weight,
            "province_live_wage_amount": province_live_wage_amount,
            "free_buying_live_weight_amount": free_buying_live_weight_amount,
            "free_buying_carcesses_weight_amount": free_buying_carcesses_weight_amount,
            "free_sell_carcesses_weight_amount": free_sell_carcesses_weight_amount,
            "out_province_poultry_request_wage_amount": out_province_poultry_request_wage_amount,
            "shares": shares_list,
        }


class CityLivestockSerializer(serializers.ModelSerializer):
    address = SystemAddressSerializer(read_only=True)
    user_bank_info = BankCardSerializer(required=False)

    class Meta:
        model = CityLivestock
        fields = ['address', 'user_bank_info', 'identity_documents', 'active']


class ImprovingLivestockSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = ImprovingLivestock
        fields = '__all__'


class ReportSubmissionTimeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ReportSubmissionTime
        fields = '__all__'


class ReportsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Reports
        fields = ['title', 'key', 'description']


class UserReportsForReportsUsersSerializer(serializers.ModelSerializer):
    report = ReportsSerializer(read_only=True)

    class Meta:
        model = UserReports
        fields = ['report', 'active', 'key']


class ReportsUsersSerializer(serializers.ModelSerializer):
    user_reports = serializers.SerializerMethodField('get_user_reports')

    class Meta:
        model = ReportsUsers
        fields = '__all__'

    def get_user_reports(self, obj):
        user_reports = UserReports.objects.filter(user=obj).order_by('id')
        serializer = UserReportsForReportsUsersSerializer(user_reports, many=True)
        return serializer.data


class UserReportsSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserReports
        fields = '__all__'


class MovingTextDashboardStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = MovingTextDashboardStatus
        fields = ['active']


class MovingTextRoleSerializer(serializers.ModelSerializer):
    class Meta:
        model = MovingTextRole
        fields = '__all__'


class MovingTextRoleForMovingTextWithRoleSerializer(serializers.ModelSerializer):
    class Meta:
        model = MovingTextRole
        fields = ['role']


class MovingTextWithRoleForMovingTextSerializer(serializers.ModelSerializer):
    role = serializers.SerializerMethodField('get_role')

    class Meta:
        model = MovingTextWithRole
        fields = ['key', 'active', 'role']

    def get_role(self, obj):
        return obj.role.role


class MovingTextSerializer(serializers.ModelSerializer):
    roles = serializers.SerializerMethodField('get_roles')

    class Meta:
        model = MovingText
        fields = ['key', 'id', 'moving_text', 'active', 'roles']

    def get_roles(self, obj):
        moving_text_with_roles = MovingTextWithRole.objects.filter(moving_text=obj).order_by('id')
        serializer = MovingTextWithRoleForMovingTextSerializer(moving_text_with_roles, many=True)
        return serializer.data


class MovingTextWithRoleSerializer(serializers.ModelSerializer):
    moving_text = MovingTextSerializer(read_only=True)
    role = MovingTextRoleSerializer(read_only=True)

    class Meta:
        model = MovingTextWithRole
        fields = '__all__'


class MovingTextForDashboardSerializer(serializers.ModelSerializer):
    class Meta:
        model = MovingText
        fields = ['moving_text']


class AdminXSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = AdminX
        fields = '__all__'


class SupporterSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = Supporter
        fields = '__all__'


class ZarinPalAccountsSerializer(serializers.ModelSerializer):
    class Meta:
        model = ZarinPalAccounts
        fields = ['key', 'name', 'account', 'en_name']


class PoultryExportSerializer(serializers.ModelSerializer):
    class Meta:
        model = PoultryExport
        fields = ['key', 'allow', 'limitation_status', 'limitation']


class PoultryOutProvinceRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = PoultryOutProvinceRequest
        fields = ['key', 'allow', 'limitation_status', 'limitation']


class VetFarmAggregatePermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = VetFarmAggregatePermission
        fields = ['key', 'allow', 'limitation']


class KillHouseBarLimitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = KillHouseBarLimitation
        fields = ['key', 'allow', 'limitation']


class ProductPricingTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductPricingType
        fields = ['key', 'province']


class OutOfProvinceSellingCarcassesPermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = OutOfProvinceSellingCarcassesPermission
        fields = ['key', 'active', 'type', 'percent']


class KillHouseDistributionManagementStewardGuildSerializer(serializers.ModelSerializer):
    kill_house_operator = KillHouseOperatorForAutoAllocationsSerializer(read_only=True)
    distribution_info = serializers.SerializerMethodField('get_distribution_info')

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

    def get_distribution_info(self, obj):
        province_kill_requests = ProvinceKillRequest.objects.filter(
            return_to_province=False, state__in=('pending', 'accepted'), first_car_allocated_quantity=0,
            trash=False).order_by(
            'kill_request__recive_date')
        kill_house_requests = KillHouseRequest.objects.filter(
            Q(killhouse_user=obj, killer__isnull=True) | Q(killer=obj), trash=False).order_by(
            'kill_request__recive_date')
        total_weight = kill_house_requests.aggregate(total=Sum('accepted_real_quantity'))['total'] or 0
        total_weight += province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
        dates = kill_house_requests.values_list('kill_request__recive_date__date').distinct()
        province_kill_requests_dates = province_kill_requests.values_list('kill_request__recive_date__date').distinct()
        kill_house_relations = KillHouseStewardGuildRelation.objects.filter(kill_house=obj, trash=False)
        stewards = len(kill_house_relations.filter(steward__isnull=False))
        guilds = len(kill_house_relations.filter(guild__isnull=False))
        total_daily_weight = kill_house_relations.aggregate(total=Sum('allocation_limit'))['total'] or 0
        optional_daily_weight = \
            kill_house_relations.filter(allocation_type='optional').aggregate(total=Sum('allocation_limit'))[
                'total'] or 0
        force_daily_weight = \
            kill_house_relations.filter(allocation_type='force').aggregate(total=Sum('allocation_limit'))['total'] or 0

        return {
            "stewards": stewards,
            "guilds": guilds,
            "total_daily_weight": total_daily_weight,
            "optional_daily_weight": optional_daily_weight,
            "force_daily_weight": force_daily_weight,
            "kill_house_requests": len(kill_house_requests),
            "total_weight": total_weight * 0.75 if total_weight > 0 else 0,
            "days": len(set(dates)) + len(set(province_kill_requests_dates)),
            "ave_total_daily_weight": round(total_weight / (len(set(dates)) + len(set(province_kill_requests_dates))),
                                            2) if (len(set(dates)) + len(set(province_kill_requests_dates))) > 0 else 0,
        }


class StewardDistributionManagementGuildSerializer(serializers.ModelSerializer):
    kill_house_operator = KillHouseOperatorForAutoAllocationsSerializer(read_only=True)
    distribution_info = serializers.SerializerMethodField('get_distribution_info')

    class Meta:
        model = Guilds
        fields = ['key', 'name', 'kill_house_operator', 'distribution_info']

    def get_distribution_info(self, obj):
        allocations = StewardAllocation.objects.filter(guilds=obj, kill_house__isnull=False, trash=False).order_by('id')
        total_weight = allocations.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0
        dates = allocations.values_list('date__date').distinct()
        steward_relations = KillHouseStewardGuildRelation.objects.filter(steward=obj, trash=False)
        guilds = len(steward_relations.filter(guild__isnull=False))
        total_daily_weight = steward_relations.aggregate(total=Sum('allocation_limit'))['total'] or 0
        optional_daily_weight = steward_relations.aggregate(total=Sum('allocation_limit'))['total'] or 0
        force_daily_weight = steward_relations.aggregate(total=Sum('allocation_limit'))['total'] or 0

        return {
            "guilds": guilds,
            "total_daily_weight": total_daily_weight,
            "optional_daily_weight": optional_daily_weight,
            "force_daily_weight": force_daily_weight,
            "kill_house_requests": len(allocations),
            "total_weight": total_weight,
            "days": len(set(dates)),
            "ave_total_daily_weight": round(total_weight / len(set(dates)), 2) if len(set(dates)) > 0 else 0,
        }


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


class BaseOutProvinceCarcassesBuyerFordispensersSerializer(serializers.ModelSerializer):
    kill_houses = serializers.SerializerMethodField('get_kill_houses')
    requests_info = serializers.SerializerMethodField('get_requests_info')

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

    def get_kill_houses(self, obj):
        kill_houses = OutProvinceCarcassesBuyer.objects.filter(trash=False, buyer=obj)
        kill_houses = kill_houses.values_list('Kill_house__name', flat=True).distinct() if kill_houses else []
        return kill_houses

    def get_requests_info(self, obj):
        free_sales = KillHouseFreeSaleBarInformation.objects.filter(trash=False, buyer__buyer=obj)

        total_quantity = free_sales.aggregate(total=Sum('number_of_carcasses'))[
                             'total'] or 0
        total_weight = free_sales.aggregate(total=Sum('weight_of_carcasses'))[
                           'total'] or 0

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


class OutProvinceCarcassesBuyerrSerializer(serializers.ModelSerializer):
    type_activity = TypeActivitySerializer(read_only=True)
    Kill_house = KillHouseForAutoAllocationSerializer(read_only=True)
    steward = GeneralGuildsSerializer(read_only=True)

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


class OutProvinceCarcassesBuyerForChoosingBuyerSerializer(serializers.ModelSerializer):
    class Meta:
        model = OutProvinceCarcassesBuyer
        fields = ['key', 'fullname', 'mobile', 'unit_name', 'city', 'province']


class OutProvinceCarcassesBuyerForBuyerRequestSerializer(serializers.ModelSerializer):
    # type_activity = TypeActivitySerializer(read_only=True)
    Kill_house = KillHouseForAutoAllocationSerializer(read_only=True)
    # steward = GeneralGuildsSerializer(read_only=True)
    buyer = BaseOutProvinceCarcassesBuyerSerializer(read_only=True)
    requests_info = serializers.SerializerMethodField('get_requests_info')

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

    def get_requests_info(self, obj):
        role = self.context.get('request').GET['role']
        total_quantity = 0
        total_weight = 0
        total_weight = 0
        if role == 'KillHouse':
            free_sales = KillHouseFreeSaleBarInformation.objects.filter(trash=False, buyer=obj)
        else:
            free_sales = StewardFreeSaleBarInformation.objects.filter(trash=False, buyer=obj)

        total_quantity = free_sales.aggregate(total=Sum('number_of_carcasses'))[
                             'total'] or 0
        total_weight = free_sales.aggregate(total=Sum('weight_of_carcasses'))[
                           'total'] or 0

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


class KillHousePricePermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = KillHousePricePermission
        fields = ['allow']


class AutomaticDirectBuyingPermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = AutomaticDirectBuyingPermission
        fields = '__all__'


class ProductsTransactionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductsTransactions
        fields = '__all__'


class NewPosMachineTransactionsSerializer(serializers.ModelSerializer):
    products = serializers.SerializerMethodField('get_products')

    class Meta:
        model = PosMachineTransactions
        fields = '__all__'

    def get_products(self, obj):
        transactions = ProductsTransactions.objects.filter(transaction=obj, trash=False)
        serializer = ProductsTransactionsSerializer(transactions, many=True)
        return serializer.data


class PosMachineTransactionsForLiveStockSerializer(serializers.ModelSerializer):
    products = serializers.SerializerMethodField('get_products')
    shares = serializers.SerializerMethodField('get_shares')
    pos = POSMachineForLiveStockTransactionsSerializer(read_only=True)

    class Meta:
        model = PosMachineTransactions
        fields = '__all__'

    def get_products(self, obj):
        transactions = ProductsTransactions.objects.filter(transaction=obj, trash=False)
        serializer = ProductsTransactionsSerializer(transactions, many=True)
        return serializer.data

    def get_shares(self, obj):
        product_transaction = ProductsTransactions.objects.get(
            trash=False,
            live_stack_products__isnull=False,
            transaction=obj
        )

        total_union_price = 0
        total_company_price = 0

        additional_data = json.loads(obj.additional)
        for share in additional_data.get('shares', []):
            share_price = int(share.get('price', 0))
            if share.get('name') == 'union':
                total_union_price = share_price * product_transaction.cur_weight
            else:
                total_company_price = share_price * product_transaction.cur_weight
        total_cooperative_price = additional_data.get('cooperative_price', 0)
        cur_heavy = additional_data.get('cur_heavy', 0)
        cur_light = additional_data.get('cur_light', 0)
        weight = product_transaction.cur_weight

        dict_result = {
            'totalCooperativePrice': total_cooperative_price,
            'totalUnionPrice': total_union_price,
            'totalCompanyPrice': total_company_price,
            'curHeavy': cur_heavy,
            'curLight': cur_light,
            'curWeight': weight,
        }
        return dict_result


class PosMachineTransactionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosMachineTransactions
        fields = '__all__'


class PosMachineTransactionsForInspectionSerializer(serializers.ModelSerializer):
    pos = POSMachineForTransactionInspectionsSerializer(read_only=True)
    product = RolesProductsForInspectionSerializer(read_only=True)

    class Meta:
        model = PosMachineTransactions
        fields = '__all__'


class PosAllocationTransactionsSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosAllocationTransactions
        fields = '__all__'

    # cart = serializers.CharField(allow_null=True, allow_blank=True, required=False)
    # refnum = serializers.CharField(allow_null=True, allow_blank=True, required=False)
    # terminal = serializers.CharField(allow_null=True, allow_blank=True,required=False)
    # additional = serializers.CharField(allow_null=True, allow_blank=True,required=False)


class BroadcastPriceSerializer(serializers.ModelSerializer):
    class Meta:
        model = BroadcastPrice
        fields = ['active', 'kill_house_price', 'steward_price', 'guild_price']


class OutProvinceSaleLimitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = OutProvinceSaleLimitation
        fields = ['active', 'kill_house', 'steward', 'guild']


class ParentCompanySerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = ParentCompany
        fields = '__all__'


class CityGuildSerializer(serializers.ModelSerializer):
    user = SystemUserProfileSerializer(read_only=True)
    address = SystemAddressSerializer(read_only=True)

    class Meta:
        model = CityGuild
        fields = '__all__'


class CityGuildForSubSectorSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)
    wage_info = serializers.SerializerMethodField('get_wage_info')

    class Meta:
        model = CityGuild
        fields = ['key', 'user', 'wage_info']

    def get_wage_info(self, obj):
        total_wage_type = WageType.objects.filter(trash=False)
        province_live_wage_amount = total_wage_type.filter(en_name='province-kill-request', trash=False).first().amount
        percentages_wage_type = PercentageOfWageType.objects.filter(trash=False)
        other_province_kill_request_percent = percentages_wage_type.filter(
            wage_type__en_name='province-kill-request', share_type__en_name='other').first().percent / 100
        if self.context.get('request').GET.get('date1'):
            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()
            transactions = PosMachineTransactions.objects.filter(paid=True, pos__guild__user__city=obj.user.city,
                                                                 trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2)
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__user__city=obj.user.city,
                                                           calculate_status=True, temporary_trash=False,
                                                           temporary_deleted=False, receiver_state='accepted',
                                                           date__date__gte=date1, date__date__lte=date2)
            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild=obj, date__date__gte=date1,
                                                                    date__date__lte=date2)
        else:
            transactions = PosMachineTransactions.objects.filter(paid=True, pos__guild__user__city=obj.user.city,
                                                                 trash=False)
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__user__city=obj.user.city,
                                                           calculate_status=True, temporary_trash=False,
                                                           temporary_deleted=False, receiver_state='accepted')
            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild=obj)
        allocations_weight = allocations.aggregate(total=Sum('real_weight_of_carcasses'))[
                                 'total'] or 0

        transactions_weight = transactions.aggregate(total=Sum('weight'))[
                                  'total'] or 0
        transactions_weight = transactions_weight / 1000 if transactions_weight > 0 else 0
        total_wage = transactions_weight * (province_live_wage_amount * other_province_kill_request_percent)

        sub_transactions_amount = sub_transactions.aggregate(total=Sum('amount'))[
                                      'total'] or 0
        remain_wage = total_wage - sub_transactions_amount

        result = {
            "buy_weight": allocations_weight,
            "sell_weight": transactions_weight,
            "total_wage": total_wage,
            "guild_deposit": sub_transactions_amount,
            "remain_wage": remain_wage
        }
        return result


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

    class Meta:
        model = CityGuild
        fields = ['key', 'user']


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

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


class SubSectorTransactionsSerializer(serializers.ModelSerializer):
    city_operator = CityOperatorForSubSectorTransactionsSerializer(read_only=True)
    vet = VetForSubSectorTransactionsSerializer(read_only=True)
    city_guild = CityGuildForSubsectorTransactionSerializer(read_only=True)

    class Meta:
        model = SubSectorTransactions
        fields = '__all__'


class PosSegmentationSerializer(serializers.ModelSerializer):
    buyer = serializers.SerializerMethodField('get_buyer')

    class Meta:
        model = PosSegmentation
        fields = ['key', 'buyer', 'date', 'weight', 'production_date', 'distribution_type', 'amount', 'total_amount',
                  'sale_type', 'quota']

    # def get_buyer(self, obj):
    #     buyer = obj.guild
    #     type = 'guild'
    #     return {
    #         "fullname": buyer.user.fullname,
    #         "mobile": buyer.user.mobile,
    #         "shop": buyer.guilds_name,
    #         "type": type,
    #
    #     }
    def get_buyer(self, obj):
        buyer = obj.guild if obj.guild else obj.kill_house
        type = 'guild' if obj.guild else 'kill_house'
        return {
            "fullname": buyer.user.fullname if obj.guild else buyer.kill_house_operator.user.fullname,
            "mobile": buyer.user.mobile if obj.guild else buyer.kill_house_operator.user.mobile,
            "shop": buyer.guilds_name if obj.guild else buyer.name,
            "type": type,

        }


class AppSegmentationSerializer(serializers.ModelSerializer):
    buyer = serializers.SerializerMethodField('get_buyer')
    to_guild = GuildsForBroadcastManagementSerializer(read_only=True)

    class Meta:
        model = PosSegmentation
        fields = ['key', 'buyer', 'date', 'weight', 'to_guild', 'sale_type', 'quota', 'production_date', 'amount',
                  'total_amount']

    def get_buyer(self, obj):
        buyer = obj.guild if obj.guild else obj.kill_house
        type = 'guild' if obj.guild else 'kill_house'
        return {
            "fullname": buyer.user.fullname if obj.guild else buyer.kill_house_operator.user.fullname,
            "mobile": buyer.user.mobile if obj.guild else buyer.kill_house_operator.user.mobile,
            "shop": buyer.guilds_name if obj.guild else buyer.name,
            "type": type,

        }


class GuildsPosMachineForTransactionsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    transaction = serializers.SerializerMethodField()

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user', 'transaction']

    def get_transaction(self, obj):
        request = self.context.get('request')
        date1, date2 = self._get_dates_from_request(request)

        pos_data = self._get_pos_transaction_data(obj, date1, date2)
        allocation_data = self._get_allocation_data(obj, date1, date2)
        product_data = self._get_product_data(obj, allocation_data)

        return {
            **pos_data,
            **product_data,
        }

    def _get_dates_from_request(self, request):
        date1_str = request.GET.get('date1')
        date2_str = request.GET.get('date2')

        date1 = datetime.strptime(date1_str, '%Y-%m-%d').date() if date1_str else None
        date2 = datetime.strptime(date2_str, '%Y-%m-%d').date() if date2_str else None

        return date1, date2

    def _get_pos_transaction_data(self, guild, date1, date2):
        pos_transactions = PosMachineTransactions.objects.filter(
            trash=False, pos__guild=guild, paid=True
        )

        if date1 and date2:
            pos_transactions = pos_transactions.filter(
                date__date__gte=date1, date__date__lte=date2
            )

        len_pos = pos_transactions.count()
        total_price = pos_transactions.aggregate(total=Sum('price'))['total'] or 0
        real_allocated_weight = pos_transactions.aggregate(total=Sum('weight'))['total'] or 0
        if real_allocated_weight > 0:
            real_allocated_weight = round(real_allocated_weight / 1000, 1)

        return {
            "len_transaction": len_pos,
            "total_price": total_price,
            "real_allocated_weight": real_allocated_weight,
        }

    def _get_allocation_data(self, guild, date1, date2):
        allocations = StewardAllocation.objects.filter(
            (Q(to_steward=guild) | Q(steward=guild)),
            trash=False, calculate_status=True,
            receiver_state__in=('pending', 'accepted')
        ).order_by('id')

        free_sale_bars = StewardFreeSaleBarInformation.objects.filter(
            (Q(guild=guild) | Q(steward=guild)), trash=False
        )

        if date1 and date2:
            allocations = allocations.filter(date__date__gte=date1, date__date__lte=date2)
            free_sale_bars = free_sale_bars.filter(date__date__gte=date1, date__date__lte=date2)

        return {
            "allocations": allocations,
            "free_sale_bars": free_sale_bars,
        }

    def _get_product_data(self, guild, allocation_data):
        allocations = allocation_data["allocations"]
        free_sale_bars = allocation_data["free_sale_bars"]

        product = RolesProducts.objects.filter(trash=False, guild=guild).first()

        if product:
            recive_allocation = allocations.filter(to_steward=guild, receiver_state__in=('pending', 'accepted'))

            real_weight_of_carcasses = recive_allocation.aggregate(
                total=Sum('real_weight_of_carcasses')
            )['total'] or 0

            weight_free_sale_bars = free_sale_bars.aggregate(
                total=Sum('weight_of_carcasses')
            )['total'] or 0

            product_total_carcasses_weight = real_weight_of_carcasses + weight_free_sale_bars

            return {
                "product": product.name,
                "total_carcasses_weight": product_total_carcasses_weight,
                "total_remain_weight": product.total_remain_weight,
            }
        else:
            return {
                "product": '-',
                "total_carcasses_weight": 0,
                "total_remain_weight": 0,
                "real_allocated_weight": 0,
            }


class CooperativeForAllocationsReportSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForInspectionSerializer(read_only=True)
    info = serializers.SerializerMethodField('get_info')

    class Meta:
        model = Cooperative
        fields = ['key', 'user', 'name', 'info']

    def get_info(self, obj):
        products = {
            "bran": "سبوس",
            "barley": "جو",
            "soy": "سویا",
            "corn": "ذرت",
            "sheep_concentrate": "کنسانتره گوسفندی",
            "high_cow_concentrate": "کنسانتره گاو شیری پرتولید",
            "medium_cow_concentrate": "کنسانتره گاو شیری متوسط",
            "fattening_calf_concentrate": "کنسانتره گوساله پرواری",
        }
        name = products[self.context.get('request').GET.get('name')]
        cooperative_roles = LiveStockRolseProduct.objects.get(cooperative=obj, parent_product__name=name)
        product_transactions = ProductsTransactions.objects.filter(live_stack_products=cooperative_roles,
                                                                   transaction__paid=True)
        transactions = PosMachineTransactions.objects.filter(
            pk__in=product_transactions.values_list('transaction', flat=True), trash=False)
        transactions_amount = product_transactions.aggregate(
            total=Sum('total_price')
        )['total'] or 0

        total_transactions_weight = product_transactions.aggregate(
            total=Sum('cur_weight')
        )['total'] or 0

        total_weight = cooperative_roles.total_weight
        total_receipt_weight = cooperative_roles.total_receipt_weight
        total_allocated_weight = cooperative_roles.total_allocated_weight
        total_remain_weight = cooperative_roles.total_remain_weight
        return {
            "total_transactions_price": transactions_amount,
            "total_transactions_weight": total_transactions_weight,
            "transactions": len(transactions),
            "total_weight": total_weight,
            "total_receipt_weight": total_receipt_weight,
            "total_allocated_weight": total_allocated_weight,
            "total_remain_weight": total_remain_weight,
        }


class PriceConfirmationSerializer(serializers.ModelSerializer):
    class Meta:
        model = PriceConfirmation
        fields = ['key', 'poultry_status']


class CityGuildForSubSectorSerializerForExcel(serializers.ModelSerializer):
    user = SystemUserProfileForGuildSerializer(read_only=True)
    wage_info = serializers.SerializerMethodField('get_wage_info')

    class Meta:
        model = CityGuild
        fields = ['key', 'user', 'wage_info']

    def get_wage_info(self, obj):
        total_wage_type = WageType.objects.filter(trash=False)
        province_live_wage_amount = total_wage_type.filter(en_name='province-kill-request', trash=False).first().amount
        percentages_wage_type = PercentageOfWageType.objects.filter(trash=False)
        other_province_kill_request_percent = percentages_wage_type.filter(
            wage_type__en_name='province-kill-request', share_type__en_name='other').first().percent / 100
        if self.context.get('request').GET['date1']:
            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()
            transactions = PosMachineTransactions.objects.filter(paid=True, pos__guild__user__city=obj.user.city,
                                                                 trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2)
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__user__city=obj.user.city,
                                                           calculate_status=True, temporary_trash=False,
                                                           temporary_deleted=False, receiver_state='accepted',
                                                           date__date__gte=date1, date__date__lte=date2)
            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild=obj, date__date__gte=date1,
                                                                    date__date__lte=date2)
        else:
            transactions = PosMachineTransactions.objects.filter(paid=True, pos__guild__user__city=obj.user.city,
                                                                 trash=False)
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__user__city=obj.user.city,
                                                           calculate_status=True, temporary_trash=False,
                                                           temporary_deleted=False, receiver_state='accepted')

            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild=obj)

        allocations_weight = allocations.aggregate(total=Sum('real_weight_of_carcasses'))[
                                 'total'] or 0

        transactions_weight = transactions.aggregate(total=Sum('weight'))[
                                  'total'] or 0
        transactions_weight = transactions_weight / 1000 if transactions_weight > 0 else 0
        total_wage = transactions_weight * (province_live_wage_amount * other_province_kill_request_percent)

        sub_transactions_amount = sub_transactions.aggregate(total=Sum('amount'))[
                                      'total'] or 0
        remain_wage = total_wage - sub_transactions_amount

        result = {
            "buy_weight": allocations_weight,
            "sell_weight": transactions_weight,
            "total_wage": total_wage,
            "guild_deposit": sub_transactions_amount,
            "remain_wage": remain_wage
        }
        return result


class ProductsTransactionsSerializerForExcel(serializers.ModelSerializer):
    class Meta:
        model = ProductsTransactions
        fields = ['name', 'cur_weight', 'cur_weight']


class PosMachineTransactionsForLiveStockSerializerForExcel(serializers.ModelSerializer):
    products = serializers.SerializerMethodField('get_products')
    pos = POSMachineForLiveStockTransactionsSerializer(read_only=True)

    class Meta:
        model = PosMachineTransactions
        fields = ['fullname', 'additional', 'date', 'natcode', 'mobile', 'pos', 'result', 'products', 'price']

    def get_products(self, obj):
        transactions = ProductsTransactions.objects.filter(transaction=obj, trash=False)
        serializer = ProductsTransactionsSerializerForExcel(transactions, many=True)
        return serializer.data


class CompanyBeneficiaryAccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = CompanyBeneficiaryAccount
        fields = ['key', 'name', 'shaba', 'percent', 'in_province', 'out_province']


class POSMachineForCompanySerializer(serializers.ModelSerializer):
    pos_company = serializers.SerializerMethodField('get_pos_company')
    user_info = serializers.SerializerMethodField('get_user_info')

    class Meta:
        model = POSMachine
        fields = ['pos_id', 'key', 'receiver_number', 'receiver_number', 'terminal_number', 'Lat',
                  'active', 'Long', 'serial', 'password', 'user_info', 'pos_company']

    def get_pos_company(self, obj):
        pos_company = PosCompany.objects.get(key=obj.pos_company.key, trash=False)
        return pos_company.name

    def get_user_info(self, obj):
        if obj.kill_house:
            dict_info = {
                'name': obj.kill_house.name,
                'mobile': obj.kill_house.kill_house_operator.user.mobile,
                'fullname': obj.kill_house.kill_house_operator.user.fullname,
                'national_code': obj.kill_house.kill_house_operator.user.national_code,
                'type': 'کشتارگاه',
            }
        elif obj.guild:
            dict_info = {
                'name': obj.guild.guilds_name,
                'mobile': obj.guild.user.mobile,
                'fullname': obj.guild.user.fullname,
                'national_code': obj.guild.user.national_code,
                'type': 'صنف',
            }
        else:
            dict_info = {
                'name': obj.cooperative.name,
                'mobile': obj.cooperative.user.mobile,
                'fullname': obj.cooperative.user.fullname,
                'national_code': obj.cooperative.user.national_code,
                'type': 'سامانه دام',
            }
        return dict_info


class POSDeviceSessionForCompanySerializer(serializers.ModelSerializer):
    pos = POSMachineForCompanySerializer(read_only=True)

    class Meta:
        model = POSDeviceSession
        fields = ['key', 'name', 'serial', 'password', 'session_create_date', 'session_last_seen_date', 'pos']


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

    class Meta:
        model = ProteinGuild
        fields = ['key', 'user', 'address', 'user_bank_info']


class PosCompanyForPosVersionSerializer(serializers.ModelSerializer):
    class Meta:
        model = PosCompany
        fields = ['id', 'active', 'name', 'en_name', 'trash', 'key']


class PosDeviceVersionForOneCompanySerializer(serializers.ModelSerializer):
    company = PosCompanyForPosVersionSerializer(read_only=True)

    class Meta:
        model = PosDeviceVersion
        fields = ["key", "trash", "name", "id", "code", "description", "enable", "remove", "company"]


class CommonlyUsedSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForCommonlyUsedSerializer(read_only=True)
    guild = GuildsForBroadcastManagementSerializer(read_only=True)
    steward = GuildsForBroadcastManagementSerializer(read_only=True)
    exclusive = serializers.SerializerMethodField('get_exclusive')

    class Meta:
        model = CommonlyUsed
        fields = ["key", "kill_house", "guild", "steward", "exclusive"]

    def get_exclusive(self, obj):
        if obj.kill_house:
            kill_house = obj.kill_house

            guild_ids = list(kill_house.guild_kill_houses.values_list('id', flat=True))
            steward_ids = list(kill_house.steward_kill_houses.values_list('id', flat=True))

            combined_ids = guild_ids + steward_ids
        else:
            steward = obj.steward
            guild_ids = list(steward.guild_stewards.all().values_list('id', flat=True))
            combined_ids = guild_ids

        guilds_exist = Guilds.objects.filter(
            id__in=combined_ids,
            trash=False,
            active=True
        ).exists()

        return guilds_exist


class GetAllGuildsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryLocSerializer(read_only=True)

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user']


class GuildsForGeneralConfigsSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryLocSerializer(read_only=True)

    class Meta:
        model = Guilds
        exclude = (
            'id',
            'create_date',
            'modify_date',
            'trash',
            'created_by',
            'modified_by',
            'address',
            'user_bank_info',
            'wallet',
            'guild_area_activity',
            'guild_type_activity',
            'cars',
            'kill_house',
            'steward_kill_house',
            'stewards',
            'user_level',

        )


class PercentageDropLimitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = PercentageDropLimitation
        fields = ['key', 'kill_house_limit_percent_down', 'kill_house_limit_percent_up']


class UploadImageLimitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = UploadImageLimitation
        fields = ['key', 'kill_house_allocation', 'kill_house_free_sale', 'steward_allocation', 'steward_free_sale']


class ApkInfoSerializer(serializers.ModelSerializer):
    class Meta:
        model = ApkInfo
        fields = ['key', 'info', 'download_link']


class DirectBuyingVerificationSerializer(serializers.ModelSerializer):
    class Meta:
        model = DirectBuyingVerification
        fields = ['key', 'poultry_code_mandatory', 'payment_deadline', 'payment_deadline_days']


class FinePermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = FinePermission
        fields = ['key', 'name', 'start_time', 'end_time', 'fine_coefficient', 'fine']


class ShowMarketRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = ShowMarketRequest
        fields = ['key', 'allow', 'start_time', 'end_time']


class IndexWeightCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = IndexWeightCategory
        fields = ['key', 'name', 'min_value', 'max_value']


class GuildsGeneralConfigsSerializer(serializers.ModelSerializer):
    class Meta:
        model = GuildsGeneralConfigs
        fields = '__all__'


class PoultryScienceSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryScienceWithoutRoleSerializer(read_only=True)
    poultry = PoultryDetailForPoultryScienceSerializer(read_only=True, many=True)

    class Meta:
        model = PoultryScience
        fields = '__all__'


class PoultryScienceForReportSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForPoultryScienceWithoutRoleSerializer(read_only=True)

    class Meta:
        model = PoultryScience
        fields = '__all__'


class PoultryScienceReportSerializer(serializers.ModelSerializer):
    poultry_science = PoultryScienceForReportSerializer(read_only=True)
    hatching = PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer(read_only=True)
    user = SystemUserProfileForPoultryScienceWithoutRoleSerializer(read_only=True)

    class Meta:
        model = PoultryScienceReport
        fields = '__all__'


class AllowRegisterCodeForGuildsSerializer(serializers.ModelSerializer):
    class Meta:
        model = AllowRegisterCodeForGuilds
        fields = '__all__'


class StewardAppLoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = StewardAppLogin
        fields = '__all__'


class StewardRequestSerializer(serializers.ModelSerializer):
    class Meta:
        model = StewardRequest
        fields = '__all__'


class RestrictionCarcassDistributionSerializer(serializers.ModelSerializer):
    class Meta:
        model = RestrictionCarcassDistribution
        fields = '__all__'


class AllowRegisterCodeForKillHouseFreeSaleBarInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = AllowRegisterCodeForKillHouseFreeSaleBarInformation
        fields = '__all__'


class AllowRegisterCodeForStewardFreeSaleBarInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = AllowRegisterCodeForStewardFreeSaleBarInformation
        fields = '__all__'


class LimitationForDirectPurchaseAndBarInformationSerializer(serializers.ModelSerializer):
    class Meta:
        model = LimitationForDirectPurchaseAndBarInformation
        fields = '__all__'


class GuildsPosMachineForTransactionsNewSerializer(serializers.ModelSerializer):
    user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
    transaction = serializers.SerializerMethodField()

    class Meta:
        model = Guilds
        fields = ['key', 'guilds_name', 'user', 'transaction', 'guilds_id', 'license_number', 'type_activity',
                  'area_activity']

    def get_transaction(self, obj):
        request = self.context.get('request')
        date1, date2 = self._get_dates_from_request(request)

        pos_data = self._get_pos_transaction_data(obj, date1, date2)
        allocation_data = self._get_allocation_data(obj, date1, date2)
        product_data = self._get_product_data(obj, allocation_data)

        return {
            **pos_data,
            **product_data,
        }

    def _get_dates_from_request(self, request):
        date1_str = request.GET.get('date1')
        date2_str = request.GET.get('date2')

        date1 = datetime.strptime(date1_str, '%Y-%m-%d').date() if date1_str else None
        date2 = datetime.strptime(date2_str, '%Y-%m-%d').date() if date2_str else None

        return date1, date2

    def _get_pos_transaction_data(self, guild, date1, date2):
        pos_transactions = PosMachineTransactions.objects.filter(
            trash=False, pos__guild=guild, paid=True
        )
        pos_segmentation = PosSegmentation.objects.filter(trash=False, guild=guild)

        if date1 and date2:
            pos_transactions = pos_transactions.filter(
                date__date__gte=date1, date__date__lte=date2
            )
            pos_segmentation = pos_segmentation.filter(
                date__date__gte=date1, date__date__lte=date2
            )

        len_pos = pos_transactions.count()
        total_price = pos_transactions.aggregate(total=Sum('price'))['total'] or 0
        real_allocated_weight = pos_transactions.aggregate(total=Sum('weight'))['total'] or 0
        if real_allocated_weight > 0:
            real_allocated_weight = round(real_allocated_weight / 1000, 1)
        pos_segmentation_weight = pos_segmentation.aggregate(total=Sum('weight'))['total'] or 0
        if pos_segmentation_weight > 0:
            pos_segmentation_weight = round(pos_segmentation_weight / 1000, 1)
        return {
            "len_transaction": len_pos,
            "total_price": total_price,
            "real_allocated_weight": real_allocated_weight + pos_segmentation_weight,
        }

    def _get_allocation_data(self, guild, date1, date2):
        allocations = StewardAllocation.objects.filter(
            to_guilds=guild,
            trash=False, calculate_status=True,
            receiver_state__in=('pending', 'accepted')
        ).order_by('id')

        # allocations = StewardAllocation.objects.filter(
        #     (Q(to_steward=guild) | Q(to_guilds=guild)),
        #     trash=False, calculate_status=True,
        #     receiver_state__in=('pending', 'accepted')
        # ).order_by('id')

        # free_sale_bars = StewardFreeSaleBarInformation.objects.filter(
        #     (Q(guild=guild) | Q(steward=guild)), trash=False
        # )

        if date1 and date2:
            allocations = allocations.filter(date__date__gte=date1, date__date__lte=date2)
            # free_sale_bars = free_sale_bars.filter(date__date__gte=date1, date__date__lte=date2)

        return {
            "allocations": allocations,
            # "free_sale_bars": free_sale_bars,
        }

    def _get_product_data(self, guild, allocation_data):
        allocations = allocation_data["allocations"]
        # free_sale_bars = allocation_data["free_sale_bars"]

        product = RolesProducts.objects.filter(trash=False, guild=guild).first()

        if product:
            recive_allocation = allocations

            real_weight_of_carcasses = recive_allocation.aggregate(
                total=Sum('real_weight_of_carcasses')
            )['total'] or 0

            # weight_free_sale_bars = free_sale_bars.aggregate(
            #     total=Sum('weight_of_carcasses')
            # )['total'] or 0

            # product_total_carcasses_weight = real_weight_of_carcasses + weight_free_sale_bars
            product_total_carcasses_weight = real_weight_of_carcasses

            return {
                "product": product.name,
                "total_carcasses_weight": product_total_carcasses_weight,
                "total_remain_weight": product.total_remain_weight,
            }
        else:
            return {
                "product": '-',
                "total_carcasses_weight": 0,
                "total_remain_weight": 0,
                "real_allocated_weight": 0,
            }


# class GuildsPosMachineForTransactionsNewSerializer(serializers.ModelSerializer):
#     # user = SystemUserProfileForAutoAllocationSerializer(read_only=True)
#     fullname = serializers.CharField(source='user.fullname', read_only=True)
#     mobile = serializers.CharField(source='user.mobile', read_only=True)
#     city = serializers.CharField(source='user.city.name', read_only=True)
#     transaction = serializers.SerializerMethodField()
#
#     class Meta:
#         model = Guilds
#         fields = ['key', 'guilds_name', 'fullname','mobile','city','guilds_id','license_number','type_activity','area_activity','transaction']
#
#     def get_transaction(self, obj):
#         # Read precomputed map passed by the view
#         precomputed = self.context.get('precomputed_transactions', {})
#         # obj.id is the guild id
#         data = precomputed.get(obj.id)
#         if not data:
#             return {
#                 "len_transaction": 0,
#                 "total_price": 0,
#                 "real_allocated_weight": 0,
#                 "product": '-',
#                 "total_carcasses_weight": 0,
#                 "total_remain_weight": 0,
#             }
#         return data


class WarehouseArchiveSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForReturnBuyingSerializer(read_only=True)
    steward = GuildsForStewardMenueSerializer(read_only=True)
    guild = GuildsForStewardMenueSerializer(read_only=True)

    class Meta:
        model = WarehouseArchive
        fields = '__all__'


class SmsRecipientSerializer(serializers.ModelSerializer):
    class Meta:
        model = SmsRecipient
        fields = ['id', 'phone_number', 'name', 'is_active', 'create_date', 'modify_date']
        read_only_fields = ['id', 'create_date', 'modify_date']


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

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

    def get_info(self, obj):
        product = RolesProducts.objects.filter(guild=obj, trash=False, name='مرغ گرم').first()
        archives = WarehouseArchive.objects.filter(Q(steward=obj) | Q(guild=obj), trash=False)
        guild_steward_allocations = StewardAllocation.objects.filter(
            Q(guilds=obj) | Q(to_guilds=obj) | Q(steward=obj) | Q(to_steward=obj),
            trash=False, calculate_status=True, warehouse=True, steward_warehouse=True
        )
        output_steward_allocations = guild_steward_allocations.filter(Q(guilds=obj) | Q(steward=obj))
        input_steward_allocations = guild_steward_allocations.filter(Q(to_guilds=obj) | Q(to_steward=obj))

        steward_free_bar_informations = StewardFreeBarInformation.objects.filter(
            steward=obj, trash=False, temporary_trash=False, temporary_deleted=False, warehouse=True
        )
        steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
            steward=obj, trash=False, temporary_trash=False, temporary_deleted=False, warehouse=True
        )
        segmentations = PosSegmentation.objects.filter(guild=obj, trash=False, warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True, trash=False,
                                                           warehouse=True)

        days_set = set()
        days_set.update(input_steward_allocations.values_list('date__date', flat=True))
        days_set.update(output_steward_allocations.values_list('production_date__date', flat=True))
        days_set.update(steward_free_bar_informations.values_list('date__date', flat=True))
        days_set.update(steward_free_Sale_bar_informations.values_list('production_date__date', flat=True))
        days_set.update(segmentations.values_list('production_date__date', flat=True))
        days_set.update(transactions.values_list('transaction__date__date', flat=True))
        days_set.update(archives.values_list('date__date', flat=True))
        days_set = {day for day in days_set if day is not None}

        days = sorted(days_set)
        today = datetime.now().date()
        yesterday = today - timedelta(days=1)
        two_days_ago = yesterday - timedelta(days=1)
        date_list = [two_days_ago, yesterday, two_days_ago]

        governmental_list = []
        free_list = []
        final_dict = {}

        for day in days:
            input_steward_allocations_info = input_steward_allocations.aggregate(
                total_input_allocations_governmental_weight=Sum('real_weight_of_carcasses',
                                                                filter=Q(receiver_state='accepted',
                                                                         quota='governmental', date__date=day)),
                total_input_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                        filter=Q(receiver_state='accepted', quota='free',
                                                                 date__date=day))
            )
            output_steward_allocations_info = output_steward_allocations.aggregate(
                total_output_allocations_governmental_weight=Sum('real_weight_of_carcasses',
                                                                 filter=Q(quota='governmental',
                                                                          production_date__date=day)),
                total_output_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                         filter=Q(quota='free', production_date__date=day))
            )
            steward_free_bar_info = steward_free_bar_informations.aggregate(
                total_free_bar_weight=Sum('weight_of_carcasses', filter=Q(date__date=day)),
            )
            steward_free_Sale_bar_info = steward_free_Sale_bar_informations.aggregate(
                total_free_Sale_bar_governmental_weight=Sum('weight_of_carcasses',
                                                            filter=Q(quota='governmental', production_date__date=day)),
                total_free_Sale_bar_free_weight=Sum('weight_of_carcasses',
                                                    filter=Q(quota='free', production_date__date=day))
            )
            segmentations_info = segmentations.aggregate(
                segmentations_governmental_weight=Sum('weight',
                                                      filter=Q(quota='governmental', production_date__date=day)),
                segmentations_free_weight=Sum('weight', filter=Q(quota='free', production_date__date=day)),
            )
            pos_allocated_weight_info = transactions.aggregate(
                pos_governmental_allocated_weight=Sum('cur_weight',
                                                      filter=Q(price_approved=True, transaction__date__date=day)),
                pos_free_allocated_weight=Sum('cur_weight',
                                              filter=Q(price_approved=False, transaction__date__date=day)),
            )
            archives_info = archives.aggregate(
                archives_governmental_weight=Sum('weight',
                                                 filter=Q(quota='governmental', date__date=day)),
                archives_free_weight=Sum('weight',
                                         filter=Q(quota='free', date__date=day)),
            )

            total_input_steward_allocations_governmental_weight = input_steward_allocations_info[
                                                                      'total_input_allocations_governmental_weight'] or 0
            total_input_steward_allocations_free_weight = input_steward_allocations_info[
                                                              'total_input_allocations_free_weight'] or 0
            total_steward_free_buying_bars_weight = steward_free_bar_info['total_free_bar_weight'] or 0
            total_output_steward_allocations_governmental_weight = output_steward_allocations_info[
                                                                       'total_output_allocations_governmental_weight'] or 0
            total_output_steward_allocations_free_weight = output_steward_allocations_info[
                                                               'total_output_allocations_free_weight'] or 0
            total_steward_free_sale_bars_governmental_weight = steward_free_Sale_bar_info[
                                                                   'total_free_Sale_bar_governmental_weight'] or 0
            total_steward_free_sale_bars_free_weight = steward_free_Sale_bar_info[
                                                           'total_free_Sale_bar_free_weight'] or 0
            segmentations_governmental_weight = segmentations_info['segmentations_governmental_weight'] or 0
            segmentations_free_weight = segmentations_info['segmentations_free_weight'] or 0
            pos_governmental_allocated_weight = pos_allocated_weight_info['pos_governmental_allocated_weight'] or 0
            pos_free_allocated_weight = pos_allocated_weight_info['pos_free_allocated_weight'] or 0
            archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
            archives_free_weight = archives_info['archives_free_weight'] or 0

            total_governmental_input = total_input_steward_allocations_governmental_weight
            total_free_input = total_input_steward_allocations_free_weight + total_steward_free_buying_bars_weight
            total_governmental_output = total_output_steward_allocations_governmental_weight + total_steward_free_sale_bars_governmental_weight + segmentations_governmental_weight + int(
                pos_governmental_allocated_weight / 1000)
            total_free_output = total_output_steward_allocations_free_weight + total_steward_free_sale_bars_free_weight + segmentations_free_weight + int(
                pos_free_allocated_weight / 1000)

            governmental_amount = (
                                          total_governmental_input - total_governmental_output) - archives_governmental_weight
            free_amount = (total_free_input - total_free_output) - archives_free_weight

            governmental_data = {
                'day': day,
                'amount': governmental_amount,
            }
            free_data = {
                'day': day,
                'amount': free_amount,
            }

            if day not in date_list:

                if governmental_amount > 0:
                    governmental_list.append(governmental_data)
                if free_amount > 0:
                    free_list.append(free_data)

        final_dict['governmental'] = governmental_list
        final_dict['free'] = free_list

        return (final_dict)


# class TotalStewardRemainWeightSerializer(serializers.ModelSerializer):
#     info = serializers.SerializerMethodField()
#
#     class Meta:
#         model = Guilds
#         fields = [
#             'id',
#             'guilds_name',
#             'user',
#             'steward',
#             'total_remain_warehouse_weight',
#             'info',
#         ]
#
#     def get_info(self, obj):
#         precomputed = self.context.get('precomputed_data', {})
#         data = precomputed.get(obj.id, {})
#
#         governmental = data.get('governmental', [])
#         free = data.get('free', [])
#
#         return {
#             'governmental': [
#                 {'day': item['day'], 'amount': float(item['amount'])} for item in governmental
#             ],
#             'free': [
#                 {'day': item['day'], 'amount': float(item['amount'])} for item in free
#             ],
#         }


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

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

    def get_info(self, obj):
        date1 = self.context.get('date1')
        date2 = self.context.get('date2')
        owner_type = self.context.get('owner_type')
        if date1:
            if owner_type == 'steward':
                archives = WarehouseArchive.objects.filter(trash=False, steward=obj, create_date__date__gte=date1,
                                                           create_date__date__lte=date2)
            else:
                archives = WarehouseArchive.objects.filter(trash=False, guild=obj, create_date__date__gte=date1,
                                                           create_date__date__lte=date2)

        else:
            if owner_type == 'steward':
                archives = WarehouseArchive.objects.filter(trash=False, steward=obj)
            else:
                archives = WarehouseArchive.objects.filter(trash=False, guild=obj)

        archives_info = archives.aggregate(
            total_count=Count('id'),
            total_governmental_count=Count('id', filter=Q(quota='governmental')),
            total_free_count=Count('id', filter=Q(quota='free')),
            total_weight=Sum('weight'),
            total_governmental_weight=Sum('weight', filter=Q(quota='governmental')),
            total_free_weight=Sum('weight', filter=Q(quota='free')),
        )

        total_count = archives_info['total_count'] or 0
        total_governmental_count = archives_info['total_governmental_count'] or 0
        total_free_count = archives_info['total_free_count'] or 0
        total_weight = archives_info['total_weight'] or 0
        total_governmental_weight = archives_info['total_governmental_weight'] or 0
        total_free_weight = archives_info['total_free_weight'] or 0

        result = {
            'total_count': total_count,
            'total_governmental_count': total_governmental_count,
            'total_free_count': total_free_count,
            'total_weight': total_weight,
            'total_governmental_weight': total_governmental_weight,
            'total_free_weight': total_free_weight,
        }
        return result


class MarketDailyLimitationSerializer(serializers.ModelSerializer):
    market = serializers.SerializerMethodField('get_market')

    class Meta:
        model = MarketDailyLimitation
        fields = ['key', 'active', 'quantity', 'register_role', 'register_fullname', 'register_mobile', 'market']

    def get_market(self, obj):
        return market_daily_limitation_info()


class HatchingArchivePercentSerializer(serializers.ModelSerializer):
    class Meta:
        model = HatchingArchivePercent
        fields = ['key', 'active', 'percent']


class POSMachineTransferSerializer(serializers.Serializer):
    recipient_type = serializers.ChoiceField(
        choices=['owner', 'current_user', 'representative']
    )
    recipient_key = serializers.CharField()

    def validate(self, data):
        recipient_type = data['recipient_type']
        key = data['recipient_key']

        if recipient_type in ['owner', 'current_user']:
            data['recipient'] = SystemUserProfile.objects.get(key=key, trash=False)

        elif recipient_type == 'representative':
            data['recipient'] = Representative.objects.get(key=key, trash=False)

        return data

    def save(self, **kwargs):
        pos = self.context['pos']
        user = self.context['request'].user

        return POSTransferService.transfer(
            pos=pos,
            recipient_type=self.validated_data['recipient_type'],
            recipient=self.validated_data['recipient'],
            performed_by=user
        )


class POSAccessLevelSerializer(serializers.ModelSerializer):
    class Meta:
        model = POSAccessLevel
        fields = '__all__'


class POSMachineReadSerializer(serializers.ModelSerializer):
    access_levels = POSAccessLevelSerializer(many=True, read_only=True)

    class Meta:
        model = POSMachine
        fields = '__all__'


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

    class Meta:
        model = Steward
        fields = ['key', 'user', 'city']


class RepresentativeSerializer(serializers.ModelSerializer):
    kill_house = KillHouseForReturnBuyingSerializer(read_only=True)
    steward = StewardForRepresentativeSerializer(read_only=True)

    class Meta:
        model = Representative
        fields = '__all__'


class UserPOSMachineSerializer(serializers.ModelSerializer):
    owner = SystemUserProfileForGuildSerializer(read_only=True)
    current_user = SystemUserProfileForGuildSerializer(read_only=True)
    current_representative = RepresentativeSerializer(read_only=True)
    access_levels = POSAccessLevelSerializer(many=True, read_only=True)

    class Meta:
        model = POSMachine
        fields = '__all__'
