import json
import logging
import math
# import time
import threading
import traceback
from collections import defaultdict
from io import BytesIO
from itertools import chain
import difflib

import openpyxl
from django.db import transaction
from django.db.models import Count
from django.db.models import Sum, F, Q, Prefetch
from django.db.models.functions import Cast
from django.http import QueryDict
from django.shortcuts import get_object_or_404
from django.utils.timezone import now
from num2fawords import words
from rest_framework.generics import GenericAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.views import APIView

from GateWay import PaymentGateway, PaymentGatewayZarinPal
from LiveStock.helpers import build_query
from LiveStock.models import LiveStockRolseProduct, Cooperative
from RasadyaarBale.models import User_Bale
from RasadyaarBale.views import send_transaction
from authentication.arvan_image.arvan_storage import upload_object, upload_object_resize
from authentication.helper.helper import register_user
from authentication.sahandsms.sms import price_reminder
from authentication.sms_management import province_kill_request_reject_sms, allow_poultry_city_province_sms, \
    allow_poultry_city_for_poultry_sms, \
    allow_poultry_province_for_poultry_sms, steward_allocation_sms, transaction_sms_threading, \
    transaction_sms_threading_for_company, transaction_sms_threading_appreciation, province_out_request_transaction_sms, \
    send_sms_for_final_approval_out_province_threading, confirmation_of_the_need_for_slaughterhouse_sms_threading, \
    confirm_price_poultry_request_direct_buying_sms, \
    operator_out_poultry_request_sms, transaction_sms_threading_in_province, send_sms_for_guild, send_sms_for_sale_bar, \
    send_sms_for_sale_bar_for_steward
from bot_eata import bot_eitaa_for_each_province_kill_request, bot_eitaa_out_province_live_bar, transaction_for_eata
from deposit_id import sha_deposit_id, arta_deposit_id, ar_deposit_id, ha_deposit_id, ma_deposit_id, guilds_deposit_id, \
    wage_counting_type
from general_urls import base_pos_id, base_url_for_sms_report
from panel.KillHouse.helpers import kill_house_cold_house_allocations_product_warehousing, \
    kill_house_allocations_product_warehousing, get_finance_info, kill_house_cold_house_allocations, \
    get_difference_carcasses_weight, get_kill_house_percent, cold_house_warehousing, kill_house_archive_warehousing
from panel.ProvinceOperator.helpers import guild_steward_allocations_product_warehousing, \
    guild_steward_free_buying_product_warehousing, guild_steward_free_sale_product_warehousing, \
    allocation_calculate_price, pos_allocation_weight_for_product, guild_steward_product_segmentation, \
    cooperative_warehousing, rancher_warehousing, guild_steward_archive_warehousing, _normalize_fa_ar
from panel.ProvinceOperator.serializers import (
    PricingSerializer,
    ProvinceCheckOperatorRequestSerializer,
    ProvinceCheckInformationSerializer,
    ProvinceFactorToKillHouseSerializer,
    KillHouseFactorToProvinceSerializer,
    ProvinceCheckKillHouseFactorSerializer,
    DepositAllocationSerializer,
    PovinceInspectorSerializer,
    PriceAnalysisorSerializer,
    WareHouseFactorSerializer,
    ProvinceOperatorSerializer, ProvinceRequestActionSerializer, ProvincePercentLeftOverSerializer,
    InspectorOperatorSerializer, ShareOfAllocationSerializer,
    PaymentDeadLineSerializer, MonthlyProfitPercentageSerializer, ProvinceFactorToKillHouseForPoultrySerializer,
    KillHouseFactorToPoultrySerializer,
    walletSerializer,
    ItransactionSerializer,
    DebtSerializer,
    PenaltySerializer,
    DepositSerializer,
    # IwalletSerializer,
    FinancialDocumentSerializer,
    FinancialTransactionSerializer, AdminSerializer, ProvinceImportKillHouseOutFactorsSerializer,
    VetSupervisorSerializer, JahadSerializer, ProvincialGovernmentSerializer, VetCheckAllocationsSerializer,
    HourLimitSerializer, SmsLicenseSerializer, PoultryAllowCityProvinceSerializer,
    ProvinceAllowKillHouseRegisterCarSerializer, ProvinceAllowPoultryChooseKillHouseSerializer,
    ProvinceAllowPoultryChooseKillHouseTotalSerializer, ProvinceAllowPoultrySellFreeSerializer,
    ProvinceAllowPoultrySellFreeTotalSerializer, ProvinceCheckOperatorOutRequestSerializer,
    ProvinceAutoAllocationSerializer, AutoAcceptProvinceKillRequestSerializer, AutoMakeKillHouseRequestSerializer,
    CityJahadForAllUserSerializer, GuildsSerializer, StewardSerializer, KillHousePercentageOfLossesSerializer,
    StewardAllocationSerializer, ProvinceAllowKillHouseChooseStewardGuildsSerializer, StewardWareHouseSerializer,
    GuildsWareHouseSerializer, CommerceSerializer, CityCommerceSerializer, HatchingLossesPermissionSerializer,
    GuildsForKillHousePercentageSerializer, WagePaymentSerializer, ProvinceAllowKillHouseDirectBuyingSerializer,
    ProvinceAllowKillHouseDirectBuyingTotalSerializer, ProvinceAllowKillHouseRegisterGuildsSerializer,
    ProvinceAllowKillHouseRegisterGuildsTotalSerializer, CityVetSerializer, KillHouseHourLimitSerializer,
    AutomaticStewardAllocationSerializer, FreeSaleWithinprovinceSerializer, ObservatorySerializer,
    ProvinceSupervisorSerializer, CarSerializer, ProductSerializer, PosItemSerializer, PosVersiontSerializer,
    GuildRoomSerializer, PosCompanySerializer, POSIdSerializer, POSMachineSerializer, GuildsForCompaniesSerializer,
    AdditionalProductsSerializer, GuildsForInspectionSerializer, POSTransactionsSerializer,
    POSMachineForServerSerializer, TotalGuildsForPosSerializer, GuildInfoForPosSerializer,
    StewardFreeBarInformationSerializer, StewardWareHouseForDailyBroadCastOInDetailsSerializer, TypeActivitySerializer,
    AreaActivitySerializer, POSMachineForInspectionSerializer, EvacuationPermitSerializer, SellForFreezingSerializer,
    LiveStockSupportSerializer, ColdHouseSerializer, ColdHouseAllocationsSerializer, OperationLimitationSerializer,
    ApprovedPriceSerializer, AnnouncementsSerializer, ChickenAgeRangeSerializer,
    TimeRangeSerializer, CitySupervisorSerializer, JahadInspectorSerializer, SystemWalletSerializer,
    SuperAdminSerializer, PaymentGatewayPercentageSerializer, WageTypeSerializer, PercentageOfWageTypeSerializer,
    ShareTypeSerializer, TotalWageInformationSerializer, InternalTransactionSerializer,
    TotalPaymentGatewayPercentageSerializer, WageTypeForPoultryOutProvinceRequestSerializer,
    StewardFreeSaleBarInformationSerializer, CityLivestockSerializer, ImprovingLivestockSerializer, ReportsSerializer,
    ReportsUsersSerializer, UserReportsSerializer, ReportSubmissionTimeSerializer, MovingTextSerializer,
    MovingTextForDashboardSerializer, MovingTextDashboardStatusSerializer, MovingTextWithRoleSerializer,
    NewProductSerializer, AdminXSerializer, SupporterSerializer, ZarinPalAccountsSerializer, PoultryExportSerializer,
    PoultryOutProvinceRequestSerializer, DispenserSerializer, DispenserAllocationSerializer, GeneralGuildsSerializer,
    TestGuildsSerializer, VetFarmAggregatePermissionSerializer,
    KillHouseBarLimitationSerializer, CityPoultrySerializer, KillHouseDistributionManagementStewardGuildSerializer,
    GuildsForDistributionManagementSerializer, StewardDistributionManagementGuildSerializer,
    OutOfProvinceSellingCarcassesPermissionSerializer, OutProvinceCarcassesBuyerrSerializer,
    OutProvinceCarcassesBuyerForBuyerRequestSerializer, ProductPricingTypeSerializer,
    PoultryOutRequestInternalTransactionSerializer, KillHousePricePermissionSerializer,
    BaseOutProvinceCarcassesBuyerSerializer, OutProvinceCarcassesBuyerForChoosingBuyerSerializer,
    BaseOutProvinceCarcassesBuyerFordispensersSerializer, RolesProductsSerializer,
    GuildsForBroadcastManagementSerializer, AutomaticDirectBuyingPermissionSerializer, PosRolesProductsSerializer,
    PosGuildsForBroadcastManagementSerializer, PosStewardAllocationSerializer, PosMachineTransactionsSerializer,
    BroadcastPriceSerializer, PosGuildsSerializer, OutProvinceSaleLimitationSerializer,
    PosAllocationTransactionsSerializer, ParentCompanySerializer, ParentCompanyTotalWageInformationSerializer,
    GuildsForColdHouseSerializer, GuildsForTotalColdHouseSerializer, StewardColdHousesSerializer,
    POSDeviceSessionSerializer, PosDeviceVersionSerializer, SubSectorTransactionsSerializer,
    SubSectorPercentageOfWageTypeSerializer, PosStewardFreeBarInformationSerializer, PosSegmentationSerializer,
    POSDeviceSessionForInspectionSerializer, CityGuildSerializer,
    CityGuildForSubSectorSerializer, CityGuildForSubsectorTransactionSerializer,
    PosMachineTransactionsForInspectionSerializer, GuildsPosMachineForTransactionsSerializer, RealGuildsSerializer,
    PosOtherProductsSerializer, CombinedPosProductSerializer, NewPosMachineTransactionsSerializer,
    PosMachineTransactionsForLiveStockSerializer, CooperativeForAllocationsReportSerializer,
    PriceConfirmationSerializer,
    POSMachineForLiveStockSerializer, CompanyBeneficiaryAccountSerializer, POSDeviceSessionForCompanySerializer,
    ProteinGuildSerializer, PosCompanyForPosVersionSerializer,
    PosDeviceVersionForOneCompanySerializer, CommonlyUsedSerializer, InProvinceAllocationSerializer,
    GetAllGuildsSerializer, RealGuildsForDashboardSerializer, PercentageDropLimitationSerializer,
    UploadImageLimitationSerializer, ApkInfoSerializer, AppSegmentationSerializer, DirectBuyingVerificationSerializer,
    FinePermissionSerializer, ShowMarketRequestSerializer, IndexWeightCategorySerializer, PoultryScienceSerializer,
    PoultryScienceReportSerializer, AllowRegisterCodeForGuildsSerializer, GuildsGeneralConfigsSerializer,
    GuildsForGeneralConfigsSerializer, StewardAppLoginSerializer, StewardRequestSerializer,
    RestrictionCarcassDistributionSerializer, AllowRegisterCodeForKillHouseFreeSaleBarInformationSerializer,
    AllowRegisterCodeForStewardFreeSaleBarInformationSerializer, LimitationForDirectPurchaseAndBarInformationSerializer,
    GuildsPosMachineForTransactionsNewSerializer, WarehouseArchiveSerializer, SmsRecipientSerializer,
    NewPOSMachineSerializer, TotalStewardRemainWeightSerializer, TotalGuildStewardWarehouseArchiveDashboardSerializer,
    MarketDailyLimitationSerializer, HatchingArchivePercentSerializer, POSMachineReadSerializer,
    POSMachineTransferSerializer, UserPOSMachineSerializer, DispenserInformationSerializer, NewDispenserSerializer,
    RepresentativeSerializer, NewCombinedPosProductSerializer)
from panel.ProvinceOperator.services.pos_transfer_service import POSTransferService
from panel.ReportingPanel.views import get_gid
from panel.admin import PROJECT_API_KEY
from panel.poultry.helpers import poultry_prediction, create_update_chicken_commission_prices
from panel.validate_headers import get_client_ip, PosDeviceValidator

# test
from ticket.helper import send_image_to_server, send_image_to_server_for_poultry_science

logger = logging.getLogger(__name__)


def update_out_province_hatching(poultry_hatching):
    poultry_requests = PoultryRequest.objects.filter(trash=False, hatching=poultry_hatching, state_process='accepted',
                                                     province_state='accepted', out_province_request_cancel=False,
                                                     wage_pay=True)
    total_killed_quantity = poultry_requests.aggregate(total=Sum('quantity'))['total'] or 0
    total_killed_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))['total'] or 0

    poultry_hatching.out_province_killed_quantity = total_killed_quantity
    poultry_hatching.out_province_killed_weight = total_killed_weight
    poultry_hatching.save()


def update_steward_allocations_on_role_change(system_profile, guilds, is_steward_now):
    if not guilds:
        return

    allocations = StewardAllocation.objects.filter(
        Q(guilds=guilds) | Q(to_guilds=guilds) | Q(steward=guilds) | Q(to_steward=guilds),
        trash=False
    )

    for allocation in allocations:

        is_sender = (allocation.guilds == guilds) or (allocation.steward == guilds)
        is_receiver = (allocation.to_guilds == guilds) or (allocation.to_steward == guilds)

        if is_steward_now:
            if is_sender:

                if allocation.guilds == guilds:
                    allocation.steward = guilds
                    allocation.guilds = None

            if is_receiver:

                if allocation.to_guilds == guilds:
                    allocation.to_steward = guilds
                    allocation.to_guilds = None

        else:

            if is_sender:

                if allocation.steward == guilds:
                    allocation.guilds = guilds
                    allocation.steward = None

            if is_receiver:

                if allocation.to_steward == guilds:
                    allocation.to_guilds = guilds
                    allocation.to_steward = None

        if allocation.to_cold_house or allocation.other_cold_house:

            pass
        elif allocation.to_steward:
            if allocation.steward:
                allocation.type = 'steward_steward'
            elif allocation.kill_house:
                allocation.type = 'killhouse_steward'
        elif allocation.to_guilds:
            if allocation.steward:
                allocation.type = 'steward_guild'
            elif allocation.kill_house:
                allocation.type = 'killhouse_guild'

        allocation.save()

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


from panel.KillHouse.serializers import (
    KillHouseADDCARSerializer,
    KillRequestSerializer, TotalKillHouseRemainWeightViewSetSerializer,
    TotalKillHouseWarehouseArchiveDashboardSerializer
)

from oauth2_provider.contrib.rest_framework import (
    TokenHasReadWriteScope,
)
from authentication.models import UserProfile, User, UserMessage, BankCard, Province, SystemAddress, ExternalTransaction

from panel.helper import UNION_NUMBER, COMPANY_NUMBER, GUILD_NUMBER
from province_orderid import sha_order_id, test_order_id, ha_order_id, ar_order_id, ma_order_id

ARTA_URL_REGISTER = "https://userbackend.rasadyar.com/api/register/"

from rest_framework.response import Response
from django.contrib.auth.models import Group

from panel.models import (
    CityOperatorCheckRequest,
    PoultryRequest,
    Pricing,
    KillHouse,
    KillHouseRequest,
    KillRequest,
    ProvinceCheckOperatorRequest,
    ProvinceCheckInformation,
    KillHouseAssignmentInformation,
    ProvinceFactorToKillHouse,
    KillHouseFactorToProvince,
    KillHouseCheckRequest,
    ProvinceCheckKillHouseFactor,
    DepositAllocation,
    PovinceInspector,
    PriceAnalysis,
    WareHouseFactor,
    ProvinceKillRequest,
    ProvinceOperator,
    ProvinceRequestAction,
    PoultryRequestAuction,
    ProvincePercentLeftOver,
    KillHouseADDCAR,
    KillHouseDriver, InspectorOperator, ShareOfAllocation, KillHouseOperator, Vet, KillHouseVet, PoultryHatching,
    VetFarm, KillHouseRequestActionWinner, PaymentDeadLine, MonthlyProfitPercentage,
    ProvinceFactorToKillHouseForPoultry, KillHouseFactorToPoultry, Poultry,
    Wallet,
    Itransaction,
    Debt,
    Penalty,
    Deposit, CityOperator, FinancialDocument, FinancialTransaction, Admin, KillHouseComplaint,
    ProvinceImportKillHouseOutFactors, VetSupervisor, Jahad, ProvincialGovernment, VetCheckAllocations, HourLimit,
    SmsLicense, KillRequestFactorPayment, KillRequestFactor, PoultryAllowCityProvince,
    ProvinceAllowKillHouseRegisterCar, ProvinceAllowPoultryChooseKillHouse, ProvinceAllowPoultryChooseKillHouseTotal,
    ProvinceAllowPoultrySellFree, ProvinceAllowPoultrySellFreeTotal, ProvinceCheckOperatorOutRequest,
    KillHousePercentage, KillHouseDailyQuota, ProvinceAutoAllocation, AutoAcceptProvinceKillRequest,
    AutoMakeKillHouseRequest, CityJahad, Guilds, Steward, KillHousePercentageOfLosses, StewardAllocation,
    KillHouseWareHouse, ProvinceAllowKillHouseChooseStewardGuilds, StewardWareHouse, GuildsWareHouse, Commerce,
    CityCommerce, HatchingLossesPermission, WagePayment, ProvinceAllowKillHouseDirectBuying,
    ProvinceAllowKillHouseDirectBuyingTotal, 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, SlaughterHouseTransaction, WageType, PercentageOfWageType, ShareType,
    TotalWageInformation, InternalTransaction, ChainCompany, ChainAllocation,
    TotalPaymentGatewayPercentage, StewardFreeSaleBarInformation, CityLivestock,
    ImprovingLivestock, OutProvincePoultryRequestBuyer, Reports, ReportsUsers, UserReports,
    ReportSubmissionTime, MovingText, MovingTextDashboardStatus, MovingTextWithRole, MovingTextRole, NewProduct, AdminX,
    Supporter, ZarinPalAccounts, PoultryExport, PoultryOutProvinceRequest, Dispenser, VetFarmAggregatePermission,
    KillHouseBarLimitation, CityPoultry, KillHouseStewardGuildRelation,
    OutOfProvinceSellingCarcassesPermission, OutProvinceCarcassesBuyer, ProductPricingType, KillHousePricePermission,
    BaseOutProvinceCarcassesBuyer, RolesProducts, AutomaticDirectBuyingPermission, PosMachineTransactions,
    BroadcastPrice, OutProvinceSaleLimitation, PosAllocationTransactions, ParentCompany, POSDeviceSession,
    PosDeviceVersion, SubSectorTransactions, SubSectorPercentageOfWageType, PosSegmentation, CityGuild,
    BarDifferenceRequest, OtherProducts, ProductsTransactions, PriceConfirmation,
    CompanyBeneficiaryAccount, ProteinGuild, CommonlyUsed, PercentageDropLimitation, UploadImageLimitation, ApkInfo,
    DirectBuyingVerification, FinePermission, ShowMarketRequest, IndexWeightCategory, PoultryScience,
    PoultryScienceReport, AllowRegisterCodeForGuilds, AllowRegisterCodeForStewardAllocation, GuildsGeneralConfigs,
    StewardAppLogin, StewardRequest, RestrictionCarcassDistribution,
    AllowRegisterCodeForKillHouseFreeSaleBarInformation, AllowRegisterCodeForStewardFreeSaleBarInformation,
    KillHouseFreeBarInformation, KillHouseFreeSaleBarInformation, LimitationForDirectPurchaseAndBarInformation,
    WarehouseArchive, SmsRecipient, MarketDailyLimitation, HatchingArchivePercent, Representative, DispenserInformation

)
from authentication.models import City
from url_filter.integrations.drf import DjangoFilterBackend
from panel.filterset import (PoultryFilterSet, ProvinceOperatorFilterSet, KillHouseFilterSet,
                             VetFilterSet, CityOperatorFilterSet, KillHouseOperatorFilterSet, KillHouseDriverFilterSet,
                             InspectorOperatorFilterSet, GuildsFilterSet, WagePaymentFilterSet,
                             InternalTransactionFilterSet, ReportsUsersFilterSet, DispenserFilterSet,
                             DispenserAllocationFilterSet, TestGuildsFilterSet, OutProvinceCarcassesBuyerFilterSet,
                             BaseOutProvinceCarcassesBuyerFilterSet, StewardAllocationFilterSet,
                             ColdHouseAllocationsFilterSet, ColdHouseFilterSet, SubSectorTransactionsFilterSet,
                             StewardFreeBarInformationFilterSet, PosSegmentationFilterSet, CooperativeFilterSet,
                             PosMachineTransactionsFilterSet, GuildsForPostationFilterSet,
                             POSDeviceSessionForCompanyFilterSet, CommonlyUsedFilterSet,
                             StewardFreeSaleBarInformationFilterSet, StewardAllocationDashboardFilterSet,
                             PoultryScienceFilterSet, PoultryScienceReportFilterSet, GuildsForGeneralConfigsFilterSet,
                             WarehouseArchiveFilterSet, POSMachineFilterSet, GuildsForArchiveFilterSet,
                             DispenserInformationFilterSet, RepresentativeFilterSet)
from authentication.models import SystemUserProfile
from panel.KillHouse.serializers import (
    KillHouseSerializer,
)
from panel.poultry.serializers import PoultryRequestSerializer, PoultrySerializer, GetAllPoultrySerializer, \
    GetAllPoultryForPoultryScienceSerializer, PoultryDetailForPoultryScienceSerializer, \
    PoultryHatchingForBazrasiSerializer, PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer
from rest_framework.decorators import api_view, permission_classes, action
from django.views.decorators.csrf import csrf_exempt
from rest_framework.permissions import AllowAny
from rest_framework import viewsets
from rest_framework import status
# from datetime import datetime
# import datetime
from datetime import datetime, timedelta, timezone
# from backports.datetime_fromisoformat import MonkeyPatch
# import pandas as pd
import jdatetime
from datetime import date
import pytz
import string
import random
import requests

ARTA_URL_CHANGE_MOBILE_NUMBER = "https://userbackend.rasadyar.com/change_mobile_number/"
ARTA_URL_REMOVE_USER_ROLE = "https://userbackend.rasadyar.com/api/remove_user_role/"

ARVAN_Kill_house_URL = 'https://profileimagedefault.s3.ir-thr-at1.arvanstorage.ir/'
ARVAN_poultry_URL = 'https://profileimagedefault.s3.ir-thr-at1.arvanstorage.ir/'
ARVAN_deposit_URL = 'https://profileimagedefault.s3.ir-thr-at1.arvanstorage.ir/'
ARVAN_Kill_house_Factor_URL = 'https://profileimagedefault.s3.ir-thr-at1.arvanstorage.ir/'
# arta_shaba_id='IR200120020000009055694184'
# ha_shaba_id='IR540160000000000318967648'
# ma_shaba_id='IR580160000000000656171877'
# guilds_shaba_id='IR200120020000009055694184'

# ARVAN_Kill_house_URL = 'https://kill-house-gallery.s3.ir-thr-at1.arvanstorage.ir/'
# ARVAN_poultry_URL = 'https://poultry-gallery.s3.ir-thr-at1.arvanstorage.ir/'
# ARVAN_deposit_URL = 'https://deposit-gallery.s3.ir-thr-at1.arvanstorage.ir/'
# ARVAN_Kill_house_Factor_URL = 'https://kill-house-factor-gallery.s3.ir-thr-at1.arvanstorage.ir/'

utc = pytz.UTC


# MonkeyPatch.patch_fromisoformat()


class CustomPagination(PageNumberPagination):
    page_size = 10


class EvacuationPermitViewSet(viewsets.ModelViewSet):
    queryset = EvacuationPermit.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = EvacuationPermitSerializer

    def list(self, request, *args, **kwargs):
        evacuation_permit = EvacuationPermit.objects.all().first()
        serializer = self.serializer_class(evacuation_permit)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        evacuation_permit = EvacuationPermit.objects.all().first()
        serializer = self.serializer_class(evacuation_permit)
        serializer.update(instance=evacuation_permit, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class SellForFreezingViewSet(viewsets.ModelViewSet):
    queryset = SellForFreezing.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SellForFreezingSerializer

    def list(self, request, *args, **kwargs):
        sell_for_freezing = SellForFreezing.objects.all().first()
        serializer = self.serializer_class(sell_for_freezing)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        sell_for_freezing = SellForFreezing.objects.all().first()
        serializer = self.serializer_class(sell_for_freezing)
        serializer.update(instance=sell_for_freezing, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProductSerializer


class CarViewSet(viewsets.ModelViewSet):
    queryset = Car.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CarSerializer

    # def create(self, request, *args, **kwargs):
    #     user = SystemUserProfile.objects.get(user=request.user, trash=False)
    #     role = request.data['role']
    #     request.data.pop('role')
    #     kill_house = None
    #     guild = None
    #     if 'kill_house_key' in request.data.keys():
    #         if request.data['kill_house_key'] != None:
    #             kill_house = KillHouse.objects.get(key=request.data['kill_house_key'])
    #         request.data.pop('kill_house_key')
    #     elif 'guild_key' in request.data.keys():
    #         if request.data['guild_key'] != None:
    #             kill_house = Guilds.objects.get(key=request.data['guild_key'])
    #         request.data.pop('guild_key')
    #     if role == 'KillHouse':
    #         kill_house_operator = KillHouseOperator.objects.get(user=user, trash=False)
    #         kill_house = KillHouse.objects.filter(kill_house_operator=kill_house_operator, trash=False)
    #     elif role == 'Guilds':
    #         guild = Guilds.objects.get(user=user,trash=False)
    #     person = SystemUserProfile.objects.get(user=request.user)
    #     group = Group.objects.get(name__exact="Driver")
    #     city = City.objects.get(name=request.data['city_name'])
    #     province = Province.objects.get(key=user.province.key)
    #     request.data.pop('city_name')
    #     if Car.objects.filter(pelak=request.data['pelak'], trash=False).exists():
    #         return Response({"result": "این ماشین قبلا ثبت شده!"}, status=status.HTTP_403_FORBIDDEN)
    #     system_profile = SystemUserProfile.objects.filter(mobile=request.data['driver_mobile'], trash=False)
    #     if system_profile.count() > 0:
    #         system_profile = system_profile.last()
    #         if group not in system_profile.role.all():
    #             system_profile.role.add(group)
    #
    #     else:
    #
    #         password = "00100"
    #         data = {
    #             "username": request.data['driver_mobile'],
    #             "password": password,
    #             "api_key": PROJECT_API_KEY
    #         }
    #         req = requests.post(
    #             url=ARTA_URL_REGISTER,
    #             data=data,
    #             verify=False
    #         )
    #         if req.status_code == 200:
    #             user = User(username=request.data['driver_mobile'], first_name=request.data['first_name'],
    #                         last_name=request.data['last_name'])
    #             user.save()
    #             base_id = SystemUserProfile.objects.all()
    #             if base_id.count() > 0:
    #                 base_id = int(base_id.last().base_order) + 1
    #             else:
    #                 base_id = 1000
    #             system_profile = SystemUserProfile(
    #                 mobile=request.data['driver_mobile'],
    #                 first_name=request.data['first_name'],
    #                 last_name=request.data['last_name'],
    #                 fullname=request.data['first_name'] + " " + request.data['last_name'],
    #                 user=user,
    #                 base_order=base_id,
    #                 password=password,
    #                 city=city,
    #                 province=province
    #             )
    #             system_profile.save()
    #             system_profile.role.add(group)
    #
    #
    #         else:
    #             return Response({"result": "در ثبت کاربر مشکلی پیش آمده است!"}, status=status.HTTP_403_FORBIDDEN)
    #
    #     wallet = Wallet()
    #     wallet.save()
    #     serializer = self.serializer_class(data=request.data)
    #     if serializer.is_valid():
    #         full_name = request.data['first_name'] + " " + request.data['last_name']
    #         request.data.pop('first_name')
    #         request.data.pop('last_name')
    #         car = serializer.create(validated_data=request.data)
    #         car.user = system_profile
    #         car.wallet = wallet
    #         car.registrar = {
    #             "role": role,
    #             "full_name": person.fullname,
    #             "mobile": person.mobile,
    #             "date": str(car.create_date)
    #         }
    #         car.driver_name = full_name
    #         car.save()
    #         if kill_house != None:
    #             if KillHouseADDCAR.objects.filter(kill_house__in=kill_house, driver=kill_house_driver,
    #                                               trash=False).exists():
    #                 return Response({"result": "این ماشین قبلا برای کشتارگاه ثبت شده!"},
    #                                 status=status.HTTP_403_FORBIDDEN)
    #             else:
    #                 add_car = KillHouseADDCAR(
    #                     kill_house=kill_house.last(),
    #                     driver=kill_house_driver
    #                 )
    #                 add_car.save()
    #         else:
    #             kill_houses = KillHouse.objects.filter(kill_house_operator__user__province=user.province, trash=False)
    #             for kill_house in kill_houses:
    #                 add_car = KillHouseADDCAR(
    #                     kill_house=kill_house,
    #                     driver=kill_house_driver
    #                 )
    #                 add_car.save()
    #
    #         return Response({"result": "ماشین با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
    #     return Response(serializer.errors)


class HatchingLossesPermissionViewSet(viewsets.ModelViewSet):
    queryset = HatchingLossesPermission.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = HatchingLossesPermissionSerializer

    def list(self, request, *args, **kwargs):
        hatching_losses = HatchingLossesPermission.objects.all().last()
        if not hatching_losses:
            hatching_losses = HatchingLossesPermission()
            hatching_losses.save()
        serializer = self.serializer_class(hatching_losses)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        hatching_losses = HatchingLossesPermission.objects.get(key=request.data['permission_key'], trash=False)
        request.data.pop('permission_key')
        serializer = self.serializer_class(hatching_losses)
        serializer.update(instance=hatching_losses, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


# def auto_steward_allocation(kill_house_key, quantity, weight, date):
#     kill_house = KillHouse.objects.get(key=kill_house_key, trash=False)
#     stewards = Steward.objects.filter(guilds__steward=True, trash=False).order_by('id')
#     stewards_list = []
#     allocatated_quantity = 0
#     kill_house_total_quantity = 0
#     for steward in stewards:
#         if steward.centers_allocation != None:
#             for center_allocation in steward.centers_allocation:
#                 if str(kill_house.key) == center_allocation['value']:
#                     kill_house_total_quantity += steward.allocation_limit
#                     stewards_list.append(steward)
#     if len(stewards_list) > 0:
#         for steward_list in stewards_list:
#             allocatated_quantity = (steward_list.allocation_limit / kill_house_total_quantity) * quantity
#             auto_allocation = StewardAllocation(
#                 kill_house=kill_house,
#                 steward=steward_list,
#                 number_of_carcasses=allocatated_quantity,
#                 real_number_of_carcasses=allocatated_quantity,
#                 weight_of_carcasses=int(allocatated_quantity * weight),
#                 real_weight_of_carcasses=int(allocatated_quantity * weight),
#                 type='auto',
#                 date=date
#             )
#             auto_allocation.save()


class ProvinceCheckDirectBuyingViewSet(viewsets.ModelViewSet):
    queryset = KillRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillRequestSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        role = None
        kill_request = KillRequest.objects.get(key=request.data['kill_request_key'])
        if kill_request.trash:
            return Response({"result": "به علت بدهی درخواست شما حذف گردید!"}, status=status.HTTP_403_FORBIDDEN)
        free_sale_in_province = False if kill_request.free_direct_buying == False else True

        request.data.pop('kill_request_key')
        state = request.data['state']
        request.data.pop('state')
        if 'role' in request.data.keys():
            role = request.data['role']
        if state == 'accepted':
            kill_request.kill_capacity = int(request.data['quantity'])
            kill_request.remain_quantity = int(request.data['quantity'])

            request.data.pop('quantity')
            poultry_requests = PoultryRequest.objects.filter(poultry__user=kill_request.poultry.user,
                                                             trash=False).order_by(
                'create_date')
            # hatching = PoultryHatching.objects.filter(poultry=kill_request.poultry, state='pending', archive=False,
            #                                           allow_hatching='pending', trash=False).order_by(
            #     'left_over').last()

            hatching = kill_request.poultry_hatching

            free_sale_with_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
            if free_sale_with_province.allow == True:
                if ('out' in request.data.keys() and request.data['out'] == True) or (
                        'free_sale_in_province' in request.data.keys() and request.data[
                    'free_sale_in_province'] == True):
                    poultry_requests_for_free_sale = PoultryRequest.objects.filter(
                        Q(direct_buying=True) | Q(out=True, wage_pay=True) | Q(free_sale_in_province=True),
                        state_process='accepted', province_state='accepted', trash=False, hatching=hatching)
                    poultry_requests_for_free_sale_sum = \
                        poultry_requests_for_free_sale.aggregate(total=Sum('quantity'))[
                            'total'] or 0
                    if poultry_requests_for_free_sale_sum + request.data[
                        'quantity'] > hatching.total_free_commitment_quantity:
                        return Response({"result": "مجموع  حجم کشتار آزاد از حجم کل تعهد  آزاد بیشتر است "},
                                        status=status.HTTP_403_FORBIDDEN)
            poultry = Poultry.objects.get(key=kill_request.poultry.key, trash=False)
            vet_farm = VetFarm.objects.filter(trash=False, poultry=poultry).first()
            last_poultry_request = PoultryRequest.objects.all()
            if last_poultry_request.count() > 0:
                general_order_code = last_poultry_request.last().general_order_code + 1
            else:
                general_order_code = 1

            if poultry_requests.count() > 0:
                order_code = poultry_requests.last().order_code + 1
            else:
                order_code = int(str(poultry.user.base_order) + '0001')
            city_operator = CityOperator.objects.filter(unit_name=poultry.city_operator, trash=False).last()
            if not city_operator:
                city_operator = CityOperator.objects.filter(unit_name='اتحادیه استان (فاقد تعاونی)', trash=False).last()
            if hatching.left_over < kill_request.kill_capacity:
                return Response({"result": "تعداد جوجه در سالن کمتر از تعداد درخواستی است"},
                                status=status.HTTP_403_FORBIDDEN)
            if kill_request.kill_house.max_kill_limit and kill_request.kill_house.total_kill_capacity > 0:

                if kill_request.kill_house.max_kill_limit and kill_request.kill_house.total_kill_capacity > 0:
                    total_province_kill_requests = ProvinceKillRequest.objects.filter(trash=False,
                                                                                      return_to_province=False,
                                                                                      archive_wage=False,
                                                                                      state__in=('pending', 'accepted'),
                                                                                      killhouse_user=kill_request.kill_house,
                                                                                      kill_request__recive_date__date=kill_request.recive_date.date())
                    total_province_kill_requests_quantity = \
                        total_province_kill_requests.aggregate(total=Sum('total_killed_quantity'))['total'] or 0
                    if kill_request.kill_house.total_kill_capacity < total_province_kill_requests_quantity + kill_request.kill_capacity:
                        return Response({"result": "تعداد وارد شده از مانده سهمیه کشتار روزانه کشتارگاه بیشتر است !"},
                                        status=status.HTTP_403_FORBIDDEN)
            kill_request.save()
            poultry_request = PoultryRequest(
                hatching=hatching,
                order_code=order_code,
                general_order_code=general_order_code,
                city_operator=city_operator,
                poultry=poultry,
                previous_quantity=kill_request.kill_capacity,
                remain_quantity=kill_request.kill_capacity,
                quantity=kill_request.kill_capacity,
                first_quantity=kill_request.kill_capacity,
                chicken_breed=hatching.chicken_breed,
                Index_weight=kill_request.Index_weight,
                state_process='accepted',
                province_state='accepted',
                direct_buying=True,
                amount=kill_request.amount,
                free_sale_in_province=free_sale_in_province,
                send_date=kill_request.recive_date
            )
            if kill_request.freezing:
                poultry_request.freezing = True
            poultry_request.save()
            kill_request.poultry_request = poultry_request
            poultry_prediction(poultry_request.poultry)

            if kill_request.export_status == True:
                poultry_request.export = True

            poultry_request.state = {
                "city_operator": city_operator.user.fullname,
                "city_state": poultry_request.state_process,
                "city_operator_mobile": city_operator.user.mobile,
                "province_operator": "",
                "province_state": ""
            }
            poultry_request.registrar = {
                "role": role,
                "fullname": user.fullname,
                "date": str(poultry_request.create_date)
            }
            poultry_request.killing_age = (poultry_request.send_date.date() - hatching.date.date()).days + 1

            poultry_request.save()

            city_operator_check_request = CityOperatorCheckRequest(
                city_operator_system=poultry_request.city_operator,
                poultry_request=poultry_request,
                state='accept',
                province_accept=True,
                province_state='accept',
                allow_hatching=True

            )
            city_operator_check_request.save()
            province_operator = ProvinceOperator.objects.filter(
                user=SystemUserProfile.objects.get(role__name='ProvinceOperator', province=user.province))

            if province_operator.count() > 0:
                province_operator = province_operator.last()

            check = ProvinceCheckOperatorRequest(
                province_operator_system=province_operator,
                poultry_request=poultry_request,
                city_request_Poultry=city_operator_check_request,
                quantity=poultry_request.quantity,

                state='accept',
            )
            check.save()
            wage_type = WageType.objects.filter(en_name='province-kill-request', trash=False).first()
            wage = wage_type.amount if wage_type.status == True else 0
            percentages_wage_type = PercentageOfWageType.objects.filter(wage_type=wage_type, percent__gt=0, trash=False)
            province_killrequest = ProvinceKillRequest(
                killhouse_user=kill_request.kill_house,
                kill_request=kill_request,
                province_request=check,
                quantity=kill_request.kill_capacity,
                total_killed_quantity=kill_request.kill_capacity,
                total_killed_weight=int(kill_request.kill_capacity * poultry_request.Index_weight),
                main_quantity=kill_request.kill_capacity,
                wage=wage,
                direct_buying=True,
                total_wage_amount=wage * int(kill_request.kill_capacity * poultry_request.Index_weight),
            )
            province_killrequest.save()
            # fine = FinePermission.objects.filter(trash=False).first()
            # time_for_fine = datetime.now().time().replace(second=0, microsecond=0)
            # if fine.direct_buying:
            #     if fine.direct_buying_start_time < time_for_fine < fine.direct_buying_end_time:
            #         province_killrequest.direct_buying_fine = True
            #         province_killrequest.direct_buying_fine_amount = (
            #                                                                  fine.direct_buying_fine_coefficient - 1) * province_killrequest.total_wage_amount if fine.direct_buying_fine_coefficient > 1 else province_killrequest.total_wage_amount
            #         province_killrequest.direct_buying_fine_coefficient = fine.direct_buying_fine_coefficient
            create_update_chicken_commission_prices()
            if wage_type and wage_type.status == True and percentages_wage_type:
                for percentage_wage_type in percentages_wage_type:
                    if percentage_wage_type.share_type.en_name == 'union':
                        province_killrequest.union_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.union_share_percent = percentage_wage_type.percent

                    elif percentage_wage_type.share_type.en_name == 'company':
                        province_killrequest.company_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.company_share_percent = percentage_wage_type.percent

                    elif percentage_wage_type.share_type.en_name == 'guilds':
                        province_killrequest.guilds_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.guilds_share_percent = percentage_wage_type.percent

                    elif percentage_wage_type.share_type.en_name == 'city':
                        province_killrequest.city_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.city_share_percent = percentage_wage_type.percent

                    elif percentage_wage_type.share_type.en_name == 'other':
                        province_killrequest.other_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.other_share_percent = percentage_wage_type.percent

                    elif percentage_wage_type.share_type.en_name == 'wallet':
                        province_killrequest.wallet_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.wallet_share_percent = percentage_wage_type.percent

                    else:
                        province_killrequest.other_share = int(
                            (percentage_wage_type.percent / 100) * province_killrequest.total_wage_amount)
                        province_killrequest.other_share_percent = percentage_wage_type.percent
                    province_killrequest.save()

            tomorrow = datetime.now().date() + timedelta(days=1)
            if not KillHouseWareHouse.objects.filter(kill_house=kill_request.kill_house, date__date=tomorrow).exists():
                ware_house_date = datetime(year=tomorrow.year, month=tomorrow.month, day=tomorrow.day, hour=1,
                                           minute=12, second=20)
                kill_house_ware_house = KillHouseWareHouse(
                    kill_house=kill_request.kill_house,
                    date=ware_house_date
                )
                kill_house_ware_house.save()
            kill_house_check = KillHouseCheckRequest(
                province_kill_request=province_killrequest,
                state='accepted'
            )

            kill_house_check.save()
            province_killrequest.state = 'accepted'
            if kill_request.payment_deadline:
                province_killrequest.payment_deadline = True
                province_killrequest.payment_deadline_date = kill_request.payment_deadline_date
            province_killrequest.save()
            check.quantity = 0
            check.save()

            if poultry_request.export == True:
                hatching.export_killed_weight += int(kill_request.kill_capacity * poultry_request.Index_weight)
                hatching.export_killed_quantity += kill_request.kill_capacity


            elif poultry_request.free_sale_in_province == True:
                hatching.free_killed_quantity += int(kill_request.kill_capacity * poultry_request.Index_weight)
                hatching.free_quantity += kill_request.kill_capacity

            else:
                hatching.governmental_killed_quantity += int(kill_request.kill_capacity * poultry_request.Index_weight)
                hatching.governmental_quantity += kill_request.kill_capacity
            hatching.killed_quantity += kill_request.kill_capacity
            hatching.save()
            poultry_request.remain_quantity = 0
            poultry_request.direct_buying_kill_place = kill_request.kill_house.name
            poultry_request.direct_buying_buyer_info = {
                "buyer_fullname": kill_request.kill_house.kill_house_operator.user.fullname,
                "buyer_mobile": kill_request.kill_house.kill_house_operator.user.mobile,
            }
            poultry_request.save()
            if kill_request.export_status == True:
                kill_request.export_state = 'accepted'
                kill_request.direct_buying_message = request.data['direct_buying_message']

            else:
                kill_request.direct_buying_state = 'accepted'

            kill_request.accept_reject_date = datetime.now()

            kill_request.save()
            # kill_house_key = kill_request.kill_house.key
            # quantity = province_killrequest.main_quantity
            # weight = poultry_request.Index_weight
            # date = province_killrequest.create_date
            # automatic_allocation = threading.Thread(target=auto_steward_allocation,
            #                                         args=(
            #                                             kill_house_key, quantity, weight, date))
            # automatic_allocation.start()
            bot_eitaa_for_each_province_kill_request(province_killrequest, vet_farm)
            poultry_fullname = poultry.unit_name
            poultry_mobile = poultry.user.mobile if not kill_request.direct_buying_intermediary_mobile else kill_request.direct_buying_intermediary_mobile
            quantity = kill_request.kill_capacity
            chicken_breed = kill_request.chicken_breed
            request_kill_house = kill_request.kill_house.name
            date_str = kill_request.recive_date
            # clean_date_str = date_str.split('T')[0] + ' ' + date_str.split('T')[1].split('.')[0]
            # send_date = datetime.strptime(str(clean_date_str), '%Y-%m-%d %H:%M:%S').date()
            if isinstance(date_str, str):
                clean_date_str = date_str.split('.')[0]
                clean_date_str = clean_date_str.replace('T', ' ')
                clean_date_str = clean_date_str.replace('Z', '')

                send_date = datetime.strptime(clean_date_str, '%Y-%m-%d %H:%M:%S').date()

            elif isinstance(date_str, datetime):
                send_date = date_str.date()
            send_date = jdatetime.datetime.fromgregorian(year=send_date.year, month=send_date.month,
                                                         day=send_date.day).strftime('%Y-%m-%d')
            date_list = reversed(send_date.split('-'))
            separate = "-"
            code = "-"
            send_date = separate.join(date_list)
            confirm_price_poultry_request = threading.Thread(
                target=confirm_price_poultry_request_direct_buying_sms,
                args=(
                    poultry_mobile, poultry_fullname,
                    quantity, chicken_breed,
                    send_date,
                    kill_request.free_direct_buying,
                    kill_request.amount, request_kill_house,
                    code))
            confirm_price_poultry_request.start()

        else:
            if kill_request.export_status == True:
                kill_request.export_state = 'rejected'
            else:
                kill_request.direct_buying_state = 'rejected'
            kill_request.direct_buying_message = request.data['direct_buying_message']
            kill_request.province_state = 'rejected'
            kill_request.accept_reject_date = datetime.now()
            kill_request.save()
        return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_200_OK)


# ویوست مربوط یه اپراتور استان
class ProvinceOperatorViewSet(viewsets.ModelViewSet):
    queryset = ProvinceOperator.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceOperatorSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            operator = user.province_operator_user.all()

            # send to serializer
            serializer = self.serializer_class(operator[0])
            return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        operator = ProvinceOperator.objects.get(key=request.data['operator_key'], trash=False)
        request.data.pop('operator_key')
        serializer = self.serializer_class(operator)
        serializer.update(instance=operator, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


# ویوست مربوط به جهاد
class JahadViewSet(viewsets.ModelViewSet):
    queryset = Jahad.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = JahadSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            jahad = user.jahad_user.all()

            # send to serializer
            serializer = self.serializer_class(jahad[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class POSIdViewSet(viewsets.ModelViewSet):
    queryset = POSId.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSIdSerializer


class PosCompanyViewSet(viewsets.ModelViewSet):
    queryset = PosCompany.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PosCompanySerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            pos_company = user.pos_company_user.all()

            # send to serializer
            serializer = self.serializer_class(pos_company[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CommerceViewSet(viewsets.ModelViewSet):
    queryset = Commerce.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CommerceSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            commerce = user.commerce_user.all()

            # send to serializer
            serializer = self.serializer_class(commerce[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class ProvinceSupervisorViewSet(viewsets.ModelViewSet):
    queryset = ProvinceSupervisor.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceSupervisorSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            province_supervisor = user.province_supervisor_user.all()

            # send to serializer
            serializer = self.serializer_class(province_supervisor[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CitySupervisorViewSet(viewsets.ModelViewSet):
    queryset = CitySupervisor.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CitySupervisorSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            city_supervisor = user.city_supervisor_user.all()

            # send to serializer
            serializer = self.serializer_class(city_supervisor[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class SuperAdminViewSet(viewsets.ModelViewSet):
    queryset = SuperAdmin.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SuperAdminSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            super_admin = user.super_admin_user.all()

            # send to serializer
            serializer = self.serializer_class(super_admin[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class JahadInspectorViewSet(viewsets.ModelViewSet):
    queryset = JahadInspector.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = JahadInspectorSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            jahad_inspector = user.jahad_inspector_user.all()

            # send to serializer
            serializer = self.serializer_class(jahad_inspector[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityCommerceViewSet(viewsets.ModelViewSet):
    queryset = CityCommerce.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityCommerceSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            city_commerce = user.city_commerce_user.all()

            # send to serializer
            serializer = self.serializer_class(city_commerce[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityJahadViewSet(viewsets.ModelViewSet):
    queryset = CityJahad.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityJahadForAllUserSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            jahad = user.city_jahad_user.all()

            # send to serializer
            serializer = self.serializer_class(jahad[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityPoultryViewSet(viewsets.ModelViewSet):
    queryset = CityPoultry.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityPoultrySerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            city_poultry = SystemUserProfile.objects.get(user=request.user, trash=False).city_poultry_user.first()

            serializer = self.serializer_class(city_poultry)
            return Response(serializer.data, status=status.HTTP_200_OK)


class DispenserDashboardViewSet(viewsets.ModelViewSet):
    queryset = Dispenser.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DispenserSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            dispensers = Dispenser.objects.filter(kill_house=kill_house, trash=False).order_by('id')
        elif request.GET['role'] in ['Guilds', 'Steward']:
            guild = Guilds.objects.get(user=user, trash=False)
            dispensers = Dispenser.objects.filter(guild=guild, trash=False).order_by('id')
        else:
            dispensers = Dispenser.objects.filter(trash=False).order_by('id')

        today = datetime.now().date()
        allocations = StewardAllocation.objects.filter(dispenser__in=dispensers, 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

        allocation_info = {
            "number_of_dispensers": len(dispensers),
            "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,
        }
        return Response(allocation_info, status=status.HTTP_200_OK)


class DispenserViewSet(viewsets.ModelViewSet):
    queryset = Dispenser.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = NewDispenserSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = DispenserFilterSet
    filterset_fields = [
        'user__first_name',
        'user__last_name',
        'user__fullname',
        'user__mobile',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'guild__user__mobile',
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'pelak',

    ]

    def retrieve(self, request, pk=None, *args, **kwargs):

        if 'profile' in request.GET:
            dispenser = SystemUserProfile.objects.get(user=request.user, trash=False).dispenser_user.first()

            serializer = self.serializer_class(dispenser)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        with transaction.atomic():
            kill_house = None
            steward = None
            birthday_str = None
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            group = Group.objects.get(name__exact="Dispenser")
            all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name'))
            first_name = request.data.get('firstName')
            last_name = request.data.get('lastName')
            father_name = request.data.get('fatherName')
            gender = request.data.get('gender')
            identity_no = request.data.get('identityNo')
            birth_date = request.data.get('birthDate')
            city_name = request.data.get('city')
            is_alive = request.data.get('isLive')
            mobile = request.data.get('mobile')
            national_code = request.data.get('nationalCode')
            role = request.data['role']
            city = City.objects.filter(name__icontains=city_name, trash=False).first()
            if not city:
                normalized_city = _normalize_fa_ar(city_name)
                city = City.objects.filter(name__icontains=normalized_city, trash=False).first()
            if not city:
                alt_city = str(city_name or '')
                alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي')
                city = City.objects.filter(name__icontains=alt_city, trash=False).first()
            if not city:
                try:
                    target = _normalize_fa_ar(city_name or '')
                    best_id = None
                    best_ratio = 0.0
                    for c in all_cities_cache:
                        cand = _normalize_fa_ar(c.get('name', '') or '')
                        ratio = difflib.SequenceMatcher(None, target, cand).ratio()
                        if ratio > best_ratio:
                            best_ratio = ratio
                            best_id = c['id']
                    if best_id is not None and best_ratio >= 0.72:
                        city = City.objects.filter(id=best_id, trash=False).first()
                except Exception:
                    city = None

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

            if not city:
                return Response({"result": "شهر مورد نظر یافت نشد!"}, status=status.HTTP_403_FORBIDDEN)

            province = Province.objects.get(key=city.province.key)

            if role == 'ProvinceOperator':
                if 'kill_house_key' in request.data.keys():
                    kill_house = KillHouse.objects.filter(trash=False, key=request.data['kill_house_key']).first()
                    request.data.pop('kill_house_key')
                else:
                    steward = Steward.objects.get(key=request.data['steward_key'], trash=False)
                    request.data.pop('steward_key')

            else:
                if role == "KillHouse":
                    kill_house = KillHouse.objects.filter(trash=False, kill_house_operator__user=user).first()
                else:
                    steward = Steward.objects.get(user=user, trash=False)

            password = "2025"
            data = {
                "username": mobile,
                "password": password,
                "api_key": PROJECT_API_KEY
            }
            req = requests.post(
                url=ARTA_URL_REGISTER,
                data=data,
                verify=False
            )

            if req.status_code == 200:
                system_user = User(username=mobile, first_name=first_name,
                                   last_name=last_name)
                system_user.save()
                base_id = SystemUserProfile.objects.all()
                if base_id.count() > 0:
                    base_id = int(base_id.last().base_order) + 1
                else:
                    base_id = 1000
                system_profile = SystemUserProfile(
                    mobile=mobile,
                    first_name=first_name,
                    last_name=last_name,
                    fullname=first_name + " " + last_name,
                    user=system_user,
                    base_order=base_id,
                    password=password,
                    national_code=identity_no,
                    national_id=national_code,
                    gender=national_code,
                    is_alive=is_alive,
                    father_name=father_name,
                    birthday=birthday_str,
                    city=city,
                    province=province
                )
                system_profile.save()
            else:
                return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است "}, status=status.HTTP_403_FORBIDDEN)
            system_profile.role.add(group)
            wallet = Wallet()
            wallet.save()
            request.data.pop('role')
            request.data.pop('firstName')
            request.data.pop('lastName')
            request.data.pop('fatherName')
            request.data.pop('gender')
            request.data.pop('identityNo')
            request.data.pop('birthDate')
            request.data.pop('city')
            request.data.pop('mobile')
            request.data.pop('nationalCode')
            request.data.pop('isLive')

            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                dispenser = serializer.create(validated_data=request.data)
                dispenser.user = system_profile
                dispenser.wallet = wallet
                dispenser.registrar = user.fullname
                dispenser_info = DispenserInformation(dispenser=dispenser)
                if kill_house is not None:
                    dispenser_info.kill_house = kill_house
                else:
                    dispenser_info.steward = steward

                dispenser_info.fullname = system_profile.fullname
                dispenser_info.national_id = system_profile.national_code
                dispenser_info.first_name = system_profile.first_name
                dispenser_info.last_name = system_profile.last_name
                dispenser_info.mobile = system_profile.mobile
                dispenser_info.city = system_profile.city.name
                dispenser_info.province = system_profile.province.name
                dispenser_info.save()
                dispenser.in_use = True
                dispenser.save()
                return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        with transaction.atomic():
            dispenser_key = request.data.pop('key')
            mobile = request.data.pop('mobile')
            dispenser = Dispenser.objects.get(key=dispenser_key, trash=False)
            dispenser_info = DispenserInformation.objects.filter(key=dispenser_key, active=True, trash=False).first()
            system_user_profile = SystemUserProfile.objects.get(key=dispenser.user.key, trash=False)
            if mobile:
                first_mobile_number = system_user_profile.mobile
                second_mobile_number = mobile
                if first_mobile_number != second_mobile_number:
                    if SystemUserProfile.objects.filter(mobile=second_mobile_number).exists():
                        return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
                                        status=status.HTTP_403_FORBIDDEN)
                    data = {
                        "first_mobile_number": first_mobile_number,
                        "second_mobile_number": second_mobile_number,
                    }
                    req = requests.post(
                        url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                        data=data,
                        verify=False
                    )
                    if req.status_code == 200:
                        second_mobile_number = second_mobile_number
                        user = User.objects.get(id=system_user_profile.user.id)
                        user.username = second_mobile_number
                        user.save()
                        system_user_profile.mobile = second_mobile_number
                        system_user_profile.save()
                        if dispenser_info:
                            dispenser_info.mobile = second_mobile_number
                            dispenser_info.save()
            serializer = self.serializer_class(dispenser)
            serializer.update(instance=dispenser, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        dispenser_list = []
        dispensers = Dispenser.objects.filter(trash=False).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(dispensers)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(dispensers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class DispenserInformationViewSet(viewsets.ModelViewSet):
    queryset = DispenserInformation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DispenserInformationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = DispenserInformationFilterSet
    filterset_fields = [
        'dispenser__user__first_name',
        'dispenser__user__last_name',
        'dispenser__user__fullname',
        'dispenser__user__mobile',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'steward__user__mobile',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'first_name',
        'last_name',
        'fullname',
        'mobile',
        'city',
        'province',
    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        role = request.GET.get('role')
        dispenser_type = request.GET.get('type')

        dispenser_filter = {
            'trash': False
        }
        role_filters = {
            'KillHouse': 'kill_house__kill_house_operator__user',
            'Steward': 'steward__user',
        }
        type_filter = {
            'KillHouse': 'kill_house__isnull',
            'Steward': 'steward__isnull',
        }
        filter_key = role_filters.get(role)
        type_key = type_filter.get(dispenser_type)
        if filter_key:
            dispenser_filter[filter_key] = user
        if type_key:
            dispenser_filter[type_key] = False
        dispenser_list = []

        dispensers = DispenserInformation.objects.filter(**dispenser_filter).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(dispensers)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(dispensers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        dispenser_info_key = request.data['key']
        dispenser_info = DispenserInformation.objects.get(key=dispenser_info_key, trash=False)
        serializer = self.serializer_class(dispenser_info)
        serializer.update(instance=dispenser_info, validated_data=request.data)
        if 'active' in request.data.keys():
            active = request.data['active']
            if not active:
                dispenser_info.dispenser.in_use = False
                dispenser_info.dispenser.save()
        return Response(serializer.data, status=status.HTTP_200_OK)

class RepresentativeViewSet(viewsets.ModelViewSet):
    queryset = Representative.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RepresentativeSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = RepresentativeFilterSet
    filterset_fields = [
        'first_name',
        'last_name',
        'mobile',
        'city',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'steward__user__mobile',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname'
    ]

    def create(self, request, *args, **kwargs):
        with transaction.atomic():
            kill_house = None
            steward = None
            owner_type = request.data.pop('owner_type', None)
            owner_key = request.data.pop('owner_key', None)
            role = request.data.pop('role', None)

            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            if role == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()

            elif role == 'Steward':
                steward = Steward.objects.get(user=user, trash=False)

            else:
                if owner_type == 'KillHouse':
                    kill_house = KillHouse.objects.get(key=owner_key, trash=False)
                else:
                    steward = Steward.objects.get(key=owner_key, trash=False)

            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                representative = serializer.create(validated_data=request.data)

                if kill_house is not None:
                    representative.kill_house = kill_house
                else:
                    representative.steward = steward
                representative.save()
                return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        representative = Representative.objects.get(key=request.data['key'], trash=False)
        serializer = self.serializer_class(representative)
        serializer.update(instance=representative, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

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

        user = SystemUserProfile.objects.get(user=request.user)
        role = request.GET.get('role')
        representative_type = request.GET.get('type')

        representative_filter = {
            'trash': False
        }
        role_filters = {
            'KillHouse': 'kill_house__kill_house_operator__user',
            'Steward': 'steward__user',
        }
        type_filter = {
            'KillHouse': 'kill_house__isnull',
            'Steward': 'steward__isnull',
        }
        filter_key = role_filters.get(role)
        type_key = type_filter.get(representative_type)
        if filter_key:
            representative_filter[filter_key] = user
        if type_key:
            representative_filter[type_key] = False

        representative_list = []
        representatives = Representative.objects.filter(**representative_filter).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(representatives)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(representatives, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class LiveStockSupportViewSet(viewsets.ModelViewSet):
    queryset = LiveStockSupport.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = LiveStockSupportSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            support = user.live_stock_support_user.all()

            # send to serializer
            serializer = self.serializer_class(support[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


# ویوست مربوط به استانداری
class ProvincialGovernmentViewSet(viewsets.ModelViewSet):
    queryset = ProvincialGovernment.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvincialGovernmentSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            government = user.government_user.all()

            # send to serializer
            serializer = self.serializer_class(government[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


def products_for_guild(guild):
    additional_products = AdditionalProducts.objects.filter(trash=False).exclude(name='سایر محصولات').order_by('id')
    if additional_products:
        for additional_product in additional_products:
            show = True if additional_product.name == 'مرغ گرم' else False
            product = Product(
                name=additional_product.name,
                image=additional_product.image,
                unit_of_measurement=additional_product.unit_of_measurement,
                priority=additional_product.priority,
                guild=guild,
                selling_free_price=additional_product.selling_free_price,
                selling_approved_price=additional_product.selling_approved_price,
                selling_more_than_inventory=additional_product.selling_more_than_inventory,
                selling_other_products=additional_product.selling_other_products,
                price=additional_product.price,
                show=show,
            )
            product.save()


class TotalGuildsForPosViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [AllowAny]
    serializer_class = TotalGuildsForPosSerializer

    def list(self, request, *args, **kwargs):
        if 'total' in request.GET:
            guilds = Guilds.objects.filter(trash=False).order_by('id')
            serializer = TotalGuildsForPosSerializer(guilds, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            guilds = Guilds.objects.get(key=request.GET['guild-key'])
            serializer = GuildInfoForPosSerializer(guilds)
            return Response(serializer.data, status=status.HTTP_200_OK)


class TypeActivityViewSet(viewsets.ModelViewSet):
    queryset = TypeActivity.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TypeActivitySerializer


class AreaActivityViewSet(viewsets.ModelViewSet):
    queryset = AreaActivity.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AreaActivitySerializer


def persian_to_gregorian_datetime(jdate_str):
    y, m, d = map(int, jdate_str.split('/'))
    g_date = jdatetime.date(y, m, d).togregorian()
    return datetime(
        g_date.year, g_date.month, g_date.day,
        15, 48, 8, 0,
        tzinfo=timezone(timedelta(hours=3, minutes=30))
    )


class GuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsSerializer

    # pagination_class = CustomPagination

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            guilds = user.guilds_user.all()

            serializer = self.serializer_class(guilds[0])
            return Response(serializer.data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        father_name = request.data['father_name']
        gender = request.data['gender']
        is_alive = request.data['is_alive']
        user_login = SystemUserProfile.objects.get(trash=False, user=request.user)
        allow_register_code = AllowRegisterCodeForGuilds.objects.filter(trash=False, active=True).first()
        # if request.data['role'] not in ('ProvinceOperator', 'SuperAdmin', 'AdminX'):
        #     return Response({"result": "مجاز به ثبت واحد صنفی نمی باشید!"}, status=status.HTTP_403_FORBIDDEN)

        group = Group.objects.get(name__exact="Guilds")
        steward_role = Group.objects.get(name__exact="Steward")
        city = City.objects.get(key=request.data['city'])
        request.data.pop('city')
        province = city.province
        system_profile = SystemUserProfile.objects.filter(mobile=request.data['mobile'], trash=False).last()
        if system_profile:
            if Guilds.objects.filter(user=system_profile, trash=False).exists():
                return Response({"result": "این صنف قبلا ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)

        else:
            password = "00100"
            data = {
                "username": request.data['mobile'],
                "password": password,
                "api_key": PROJECT_API_KEY
            }
            req = requests.post(
                url=ARTA_URL_REGISTER,
                data=data,
                verify=False
            )

            if req.status_code == 200:

                user = User(username=request.data['mobile'], first_name=request.data['first_name'],
                            last_name=request.data['last_name'])
                user.save()
                base_id = SystemUserProfile.objects.all()
                if base_id.count() > 0:
                    base_id = int(base_id.last().base_order) + 1
                else:
                    base_id = 1000
                system_profile = SystemUserProfile(
                    mobile=request.data['mobile'],
                    first_name=request.data['first_name'],
                    last_name=request.data['last_name'],
                    fullname=request.data['first_name'] + " " + request.data['last_name'],
                    user=user,
                    base_order=base_id,
                    password=password,
                    national_id=request.data['national_id'],
                    city=city,
                    province=province,
                    father_name=father_name,
                    gender=gender,
                    is_alive=is_alive

                )
                system_profile.save()
            else:
                return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است "}, status=status.HTTP_403_FORBIDDEN)
        address = SystemAddress(city=city, province=province, address=request.data['address'],
                                postal_code=request.data['postal_code'])
        address.save()
        system_profile.role.add(group)
        wallet = Wallet()
        wallet.save()
        role = request.data['role']
        type_activity_name = request.data['type_activity_name']
        type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first()
        if not type_activity:
            type_activity = TypeActivity.objects.filter(trash=False).first()

        area_activity = AreaActivity.objects.filter(trash=False).first()
        request.data.pop('role')
        request.data.pop('type_activity_name')
        request.data.pop('mobile')
        request.data.pop('first_name')
        request.data.pop('last_name')
        request.data.pop('address')
        request.data.pop('national_id')
        request.data.pop('postal_code')
        request.data.pop('type_activity')
        request.data.pop('area_activity')
        request.data.pop('father_name')
        request.data.pop('is_alive')
        request.data.pop('gender')

        # license_number = data.get("license_number"),
        # license_type = data.get("license_type"),
        # license_status = data.get("license_status"),
        # license_issue_date = license_issue_date,
        # license_expire_date = license_expire_date,
        # company_name = data.get("company_name"),
        # company_identifier = data.get("company_identifier"),
        # is_foreign_national = parse_bool(data.get("is_foreign_national")),
        # has_partner = parse_bool(data.get("has_partner")),
        # has_inquiry = parse_bool(data.get("has_inquiry")),

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            guilds = serializer.create(validated_data=request.data)
            guilds.user = system_profile
            guilds.registerar_fullname = user_login.fullname
            guilds.registerar_mobile = user_login.mobile
            guilds.registerar_role = role
            guilds.address = address
            guilds.wallet = wallet
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.province_accept_state = 'pending'
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.license_issue_date = persian_to_gregorian_datetime(request.data['license_issue_date'])
            guilds.license_expire_date = persian_to_gregorian_datetime(request.data['license_expire_date'])
            guilds.save()
            if allow_register_code:
                number = random.randint(10000, 99000)
                guilds.register_code = number
                guilds.active_register_code = True
                guilds.register_date_register_code = datetime.now()
                if allow_register_code.has_time:
                    guilds.expire_time_register_code = datetime.now() + timedelta(minutes=int(allow_register_code.time))
                guilds.save()
                try:
                    send_sms_for_guild(guilds)
                except:
                    pass

            parent_product = NewProduct.objects.all().first()
            # approved_type = True if parent_product.approved_price_status == True else False
            # approved_price = parent_product.approved_price

            price = BroadcastPrice.objects.filter(trash=False).first()

            approved_price = price.steward_price if guilds.steward else price.guild_price
            approved_type = price.active if approved_price > 0 else False

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

            # if guilds.steward == True:
            #     steward = Steward(
            #         guilds=guilds
            #     )
            #     steward.save()
            #     system_profile.role.add(steward_role)

            if role == 'KillHouse':
                user = SystemUserProfile.objects.get(user=request.user)
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).order_by(
                    'id').first()
                guilds.kill_house_centers_allocation = [
                    {"label": kill_house.name, "value": str(kill_house.key)}]
                guilds.province_accept_state = 'pending'
                guilds.kill_house_register = True

                guilds.save()

                if guilds.steward == True:
                    guilds.steward_kill_house.add(kill_house)

                else:
                    guilds.kill_house.add(kill_house)

                # if guilds.steward == True:
                #     steward.centers_allocation = [
                #         {"label": kill_house.name, "value": str(kill_house.key)}]
                #     steward.allocation_limit = guilds.allocation_limit
                #     steward.province_accept_state = 'pending'
                #     steward.kill_house_register = True
                #     steward.save()
            elif role == 'Guilds':
                user = SystemUserProfile.objects.get(user=request.user)
                steward = Steward.objects.get(guilds__user=user, trash=False)

                guilds.centers_allocation = [
                    {"label": steward.guilds.user.fullname, "value": str(steward.key)}]
                guilds.province_accept_state = 'pending'
                guilds.steward_register = True
                guilds.save()

            elif role == 'PosCompany':
                guilds.province_accept_state = 'pending'
                guilds.pos_company_register = True
                guilds.save()

            # guild_products = threading.Thread(target=products_for_guild,
            #                                   args=(guilds,))
            #
            # guild_products.start()

            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        guilds = Guilds.objects.get(key=request.data['guilds_key'], trash=False)
        system_user_profile = SystemUserProfile.objects.get(key=guilds.user.key, trash=False)
        address = SystemAddress.objects.get(key=guilds.address.key, trash=False)
        if 'KillHouseList' in request.data.keys():
            kill_houses = KillHouse.objects.filter(key__in=request.data['KillHouseList']).order_by('id')
            guilds.kill_house.set(kill_houses)
            KillHouseStewardGuildRelation.objects.filter(guild=guilds, kill_house__isnull=False).delete()

            relations = [
                KillHouseStewardGuildRelation(guild=guilds, kill_house=kill_house)
                for kill_house in kill_houses
            ]

            KillHouseStewardGuildRelation.objects.bulk_create(relations)
            # guilds.guild_kill_houses.clear()
            # guilds.guild_kill_houses.add(*kill_houses)
        if 'StewardList' in request.data.keys():
            stewards = Guilds.objects.filter(key__in=request.data['StewardList']).order_by('id')
            guilds.stewards.set(stewards)
            request.data.pop('StewardList')

        if 'StewardKillHouseList' in request.data.keys():
            kill_houses = KillHouse.objects.filter(key__in=request.data['StewardKillHouseList']).order_by('id')
            guilds.steward_kill_house.set(kill_houses)
            request.data.pop('StewardKillHouseList')

        if 'type_activity' in request.data.keys():
            type_activity = TypeActivity.objects.get(title=request.data['type_activity'])
            area_activity = AreaActivity.objects.get(title=request.data['area_activity'])
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.save()
            request.data.pop('type_activity')
            request.data.pop('area_activity')

        if 'first_name' in request.data.keys():
            system_user_profile.first_name = request.data['first_name']
            system_user_profile.last_name = request.data['last_name']
            system_user_profile.fullname = request.data['first_name'] + " " + request.data['last_name']
            system_user_profile.national_id = request.data['national_id']
            system_user_profile.save()
            first_mobile_number = system_user_profile.mobile
            second_mobile_number = request.data['mobile']
            request.data.pop('mobile')
            if first_mobile_number != second_mobile_number:
                if SystemUserProfile.objects.filter(mobile=second_mobile_number).exists():
                    return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
                                    status=status.HTTP_403_FORBIDDEN)
                data = {
                    "first_mobile_number": first_mobile_number,
                    "second_mobile_number": second_mobile_number,
                }
                req = requests.post(
                    url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                    data=data,
                    verify=False
                )
                if req.status_code == 200:
                    second_mobile_number = second_mobile_number
                    user = User.objects.get(id=system_user_profile.user.id)
                    user.username = second_mobile_number
                    user.save()
                    system_user_profile.mobile = second_mobile_number
                    system_user_profile.save()

            city = City.objects.get(name=request.data['city'])
            province = Province.objects.get(key=city.province.key)
            address.city = city
            address.province = province
            address.address = request.data['address']
            address.postal_code = request.data['postal_code']
            address.save()
            request.data.pop('guilds_key')
            request.data.pop('first_name')
            request.data.pop('last_name')
            request.data.pop('address')
            request.data.pop('national_id')
            request.data.pop('city')
        if 'active' in request.data:
            role = request.data['role']
            activation_role = guilds.role_activation
            if request.data['active']:
                if activation_role:
                    if (activation_role == 'AdminX' and role != 'AdminX') or \
                            (activation_role == 'SuperAdmin' and role not in ('AdminX', 'SuperAdmin')):
                        return Response(
                            {"result": "شما دسترسی ویرایش صنف را ندارید!"},
                            status=status.HTTP_403_FORBIDDEN
                        )
            guilds.role_activation = role
            guilds.save()

            request.data.pop('guilds_key')
            request.data.pop('role')
            serializer = self.serializer_class(guilds)
            serializer.update(instance=guilds, validated_data=request.data)
            return Response({"result": "با موفقیت ویرایش شد"}, status=status.HTTP_200_OK)

        guilds.is_registered = False
        guilds.logged_register_code = None
        guilds.register_code = None
        guilds.save()
        serializer = self.serializer_class(guilds)
        serializer.update(instance=guilds, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)

        if 'psp_pos' in request.GET:
            base_queryset = (
                Guilds.objects.filter(trash=False, active=True, has_inquiry=True)
                    .select_related('user', 'address__city')
                    .values(
                    'key',
                    'guilds_name',
                    'guilds_id',
                    'license_number',
                    'type_activity',
                    'area_activity',
                    'steward',
                    'user__fullname',
                    'user__mobile',
                    'address__city__name',
                )
            )

            raw_data = base_queryset.order_by('steward')
            guilds_data = [
                {
                    "key": g["key"],
                    "guilds_name": g["guilds_name"],
                    "steward": g["steward"],
                    "guilds_id": g["guilds_id"],
                    "license_number": g["license_number"],
                    "type_activity": g["type_activity"],
                    "area_activity": g["area_activity"],
                    "user": {
                        "fullname": g["user__fullname"],
                        "mobile": g["user__mobile"],
                        "city": g["address__city__name"],
                    }
                }
                for g in raw_data
            ]

            return Response(guilds_data, status=status.HTTP_200_OK)

        if 'commonly_used' in request.GET:
            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                commonly_used = CommonlyUsed.objects.filter(kill_house=kill_house, trash=False).values_list('guild',
                                                                                                            flat=True)
            else:
                steward = Guilds.objects.get(user=user, steward=True, active=True, trash=False)
                commonly_used = CommonlyUsed.objects.filter(steward=steward, trash=False).values_list('guild',
                                                                                                      flat=True)
            guilds = Guilds.objects.filter(trash=False, active=True).order_by('-steward').exclude(id__in=commonly_used)
            serializer = GuildsForBroadcastManagementSerializer(guilds, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        if 'dispenser' in request.GET:
            guilds = Guilds.objects.filter(steward=True, trash=False)
            serializer = GeneralGuildsSerializer(guilds, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

        if 'type' in request.GET:
            guilds = []
            kill_house_percentage = KillHousePercentage.objects.get(key=request.GET["percentage_key"],
                                                                    trash=False)
            guilds_list = Guilds.objects.filter(kill_house_centers_allocation__isnull=False, trash=False)
            if guilds_list:
                for guild in guilds_list:
                    if len(guild.kill_house_centers_allocation) == 0 or guild.kill_house_centers_allocation == None:
                        continue
                    if guild.kill_house_centers_allocation[0]['value'] == str(
                            kill_house_percentage.kill_house.key):
                        guilds.append(guild)
            serializer = GuildsForKillHousePercentageSerializer(guilds, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'steward_sub_guilds' in request.GET:
            guilds_list = []
            now = datetime.now().date()
            date = datetime.strptime(str(request.GET['date']),
                                     '%Y-%m-%d').date() if 'date' in request.GET else now
            steward = Steward.objects.get(guilds__user=user, active=True, trash=False)
            steward_ware_house = StewardWareHouse.objects.filter(steward=steward, date__date=date, trash=False).first()
            guilds = Guilds.objects.filter(trash=False, steward=False).order_by('id')
            for guild in guilds:
                if guild.centers_allocation != None:
                    for center_allocation in guild.centers_allocation:
                        if str(steward.key) == center_allocation['value']:
                            if not StewardAllocation.objects.filter(date__date=date,
                                                                    guilds=guild,
                                                                    steward_ware_house=steward_ware_house).exists():
                                guilds_list.append(guild)
            guilds = guilds_list
        elif 'other_guilds_for_steward' in request.GET:
            guilds_list = []
            now = datetime.now().date()
            date = datetime.strptime(str(request.GET['date']),
                                     '%Y-%m-%d').date() if 'date' in request.GET else now
            steward = Steward.objects.get(guilds__user=user, active=True, trash=False)
            steward_ware_house = StewardWareHouse.objects.filter(steward=steward, date__date=date, trash=False).first()
            guilds = Guilds.objects.filter(trash=False, steward=False).order_by('id')
            for guild in guilds:
                if guild.centers_allocation == None:
                    guilds_list.append(guild)
                else:

                    for center_allocation in guild.centers_allocation:
                        if str(steward.key) != center_allocation['value']:
                            if not StewardAllocation.objects.filter(date__date=date,
                                                                    guilds=guild,
                                                                    steward_ware_house=steward_ware_house).exists():
                                guilds_list.append(guild)
            guilds = guilds_list

        elif 'role' in request.GET:

            if request.GET['role'] == 'CityCommerce':
                guilds = Guilds.objects.filter(trash=False, address__city=user.city).order_by('id')


            elif request.GET['role'] == 'ProvinceOperator':
                guilds = Guilds.objects.filter(trash=False, steward=False, address__province=user.province).order_by(
                    'id')

            elif request.GET['role'] == 'Steward':
                is_free = request.GET.get('free') == 'true'
                all = request.GET.get('all') == 'true'
                steward = Guilds.objects.select_related('user').get(user=user, active=True, trash=False)
                base_queryset = (
                    Guilds.objects.filter(trash=False, active=True)
                        .select_related('user', 'address__city')
                        .values(
                        'key',
                        'guilds_name',
                        'steward',
                        'user__fullname',
                        'user__mobile',
                        'address__city__name',
                    )
                )
                if not all:
                    if is_free:
                        raw_data = base_queryset.filter(trash=False, active=True).exclude(id=steward.id).order_by(
                            'steward')
                    else:
                        raw_data = base_queryset.filter(
                            stewards=steward,
                            trash=False,
                            province_accept_state__in=('pending', 'accepted'),
                            steward=False,
                            active=True
                        ).order_by('id')
                else:
                    raw_data = base_queryset.order_by('steward')
                guilds_data = [
                    {
                        "key": g["key"],
                        "guilds_name": g["guilds_name"],
                        "steward": g["steward"],
                        "user": {
                            "fullname": g["user__fullname"],
                            "mobile": g["user__mobile"],
                            "city": g["address__city__name"],
                        }
                    }
                    for g in raw_data
                ]

                return Response(guilds_data, status=status.HTTP_200_OK)


            # elif request.GET['role'] == 'PosCompany':
            #
            #     # steward = Guilds.objects.select_related('user').get(user=user, trash=False)
            #     base_queryset = (
            #         Guilds.objects
            #             .select_related('user', 'address__city')
            #             .values(
            #             'key',
            #             'guilds_name',
            #             'guilds_id',
            #             'type_activity',
            #             'area_activity',
            #             'steward',
            #             'user__fullname',
            #             'user__mobile',
            #             'address__city__name',
            #         )
            #     )
            #
            #     raw_data = base_queryset.order_by('steward')
            #     guilds_data = [
            #         {
            #             "key": g["key"],
            #             "guilds_name": g["guilds_name"],
            #             "steward": g["steward"],
            #             "guilds_id": g["guilds_id"],
            #             "type_activity": g["type_activity"],
            #             "area_activity": g["area_activity"],
            #             "user": {
            #                 "fullname": g["user__fullname"],
            #                 "mobile": g["user__mobile"],
            #                 "city": g["address__city__name"],
            #             }
            #         }
            #         for g in raw_data
            #     ]
            #
            #     return Response(guilds_data, status=status.HTTP_200_OK)

            else:
                guilds_list = []
                guilds = Guilds.objects.filter(steward=False, active=True, trash=False).order_by('id')
                if 'kill_house_key' in request.GET:
                    kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)
                    now = datetime.now().date()
                    date = datetime.strptime(str(request.GET['date']),
                                             '%Y-%m-%d').date() if 'date' in request.GET else now
                    for guild in guilds:
                        if guild.kill_house_centers_allocation != None:
                            for kill_house_center_allocation in guild.kill_house_centers_allocation:
                                if request.GET['kill_house_key'] == kill_house_center_allocation['value']:
                                    if not StewardAllocation.objects.filter(date__year=date.year,
                                                                            date__month=date.month,
                                                                            date__day=date.day, guilds=guild,
                                                                            ware_house__kill_house=kill_house).exists():
                                        guilds_list.append(guild)
                else:
                    kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                    all = request.GET.get('all') == 'true'
                    if all:
                        base_queryset = (
                            Guilds.objects
                                .filter(trash=False, active=True).select_related('user', 'address__city')
                                .values(
                                'key',
                                'guilds_name',
                                'steward',
                                'user__fullname',
                                'user__mobile',
                                'address__city__name',
                            )
                        )
                        raw_data = base_queryset.order_by('steward')
                        guilds_data = [
                            {
                                "key": g["key"],
                                "guilds_name": g["guilds_name"],
                                "steward": g["steward"],
                                "user": {
                                    "fullname": g["user__fullname"],
                                    "mobile": g["user__mobile"],
                                    "city": g["address__city__name"],
                                }
                            }
                            for g in raw_data
                        ]

                        return Response(guilds_data, status=status.HTTP_200_OK)
                    # if 'free' in request.GET:
                    if request.GET['free'] == 'true':
                        guild_kill_ids = set(kill_house.guild_kill_houses.values_list('id', flat=True))
                        steward_kill_ids = set(kill_house.steward_kill_houses.values_list('id', flat=True))
                        all_exclude_ids = guild_kill_ids | steward_kill_ids

                        guilds = Guilds.objects.filter(
                            trash=False,
                            active=True
                        ).exclude(id__in=all_exclude_ids).select_related('user__city') \
                            .only('key', 'guilds_name', 'type_activity', 'area_activity', 'guilds_id', 'steward',
                                  'user') \
                            .order_by('steward')
                    else:
                        guilds = Guilds.objects.filter(
                            Q(id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True)) | Q(
                                id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True)),
                            active=True, trash=False).order_by(
                            'steward')
                    serializer = GuildsForBroadcastManagementSerializer(guilds, many=True)
                    return Response(serializer.data, status=status.HTTP_200_OK)
                    #
                    # counter = 0
                    # for guild in guilds:
                    #     if guild.kill_house_centers_allocation != None:
                    #         if len(guild.kill_house_centers_allocation) == 0:
                    #             continue
                    #         for kill_house_center_allocation in guild.kill_house_centers_allocation:
                    #             if str(kill_house.key) != kill_house_center_allocation['value']:
                    #                 counter += 1
                    #         if guild not in guilds_list and counter == len(guild.kill_house_centers_allocation):
                    #             guilds_list.append(guild)
                    #     else:
                    #         guilds_list.append(guild)

                guilds = guilds_list

        serializer = GuildsSerializer(guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class RealGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RealGuildsSerializer

    def create(self, request, *args, **kwargs):
        allocation_limit = None
        allocation_type = None
        owner_key = None
        role_type = None
        group = Group.objects.get(name__exact="Guilds")
        role = request.data['role']
        type_activity = TypeActivity.objects.get(title=request.data['type_activity'])
        area_activity = AreaActivity.objects.get(title=request.data['area_activity'])
        register = register_user(group, request.data['city'], request.data['mobile'], request.data['first_name'],
                                 request.data['last_name'], request.data['national_id'], request.data['postal_code'],
                                 request.data['address'])
        if 'allocation_limit' in request.data.keys():
            allocation_limit = request.data['allocation_limit']
            allocation_type = request.data['allocation_type']
            request.data.pop('allocation_limit')
            request.data.pop('allocation_type')

        if 'owner_key' in request.data.keys():
            owner_key = request.data['owner_key']
            request.data.pop('owner_key')

        if 'role_type' in request.data.keys():
            role_type = request.data['role_type']
            request.data.pop('role_type')

        if not register:
            return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است"}, status=status.HTTP_403_FORBIDDEN)
        request.data.pop('city')
        request.data.pop('role')
        request.data.pop('mobile')
        request.data.pop('first_name')
        request.data.pop('last_name')
        request.data.pop('address')
        request.data.pop('national_id')
        request.data.pop('postal_code')
        request.data.pop('type_activity')
        request.data.pop('area_activity')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            guilds = serializer.create(validated_data=request.data)
            guilds.user = register["system_profile"]
            guilds.address = register["address"]
            guilds.wallet = register["wallet"]
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.save()
            parent_product = NewProduct.objects.all().first()
            approved_type = True if parent_product.approved_price_status == True else False
            approved_price = parent_product.approved_price
            product = RolesProducts(
                parent_product=parent_product,
                guild=guilds,
                name='مرغ گرم',
                approved_price_status=approved_type,
                approved_price=approved_price,
            )
            product.save()
            if role == 'KillHouse':
                user = SystemUserProfile.objects.get(user=request.user)
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).order_by(
                    'id').first()
                guilds.province_accept_state = 'pending'
                guilds.kill_house_register = True

                guilds.save()

                if guilds.steward == True:
                    guilds.steward_kill_house.add(kill_house)
                    relation = KillHouseStewardGuildRelation(steward=guilds, kill_house=kill_house,
                                                             allocation_limit=allocation_limit,
                                                             allocation_type=allocation_type)
                    relation.save()




                else:
                    guilds.kill_house.add(kill_house)
                    relation = KillHouseStewardGuildRelation(guild=guilds, kill_house=kill_house,
                                                             allocation_limit=allocation_limit,
                                                             allocation_type=allocation_type)
                    relation.save()


            elif role == 'Steward':
                user = SystemUserProfile.objects.get(user=request.user)
                steward = Steward.objects.get(guilds__user=user, trash=False)
                guilds.stewards.add(steward)
                relation = KillHouseStewardGuildRelation(guild=guilds, steward=steward,
                                                         allocation_limit=allocation_limit,
                                                         allocation_type=allocation_type)
                relation.save()
                guilds.province_accept_state = 'pending'
                guilds.steward_register = True
                guilds.save()


            elif role == 'PosCompany':
                guilds.province_accept_state = 'pending'
                guilds.pos_company_register = True
                guilds.save()
            else:
                if role_type == 'KillHouse':
                    kill_house = KillHouse.objects.get(key=owner_key)

                    if guilds.steward == True:
                        guilds.steward_kill_house.add(kill_house)
                        relation = KillHouseStewardGuildRelation(steward=guilds, kill_house=kill_house,
                                                                 allocation_limit=allocation_limit,
                                                                 allocation_type=allocation_type)
                        relation.save()
                    else:
                        guilds.kill_house.add(kill_house)
                        relation = KillHouseStewardGuildRelation(guild=guilds, kill_house=kill_house,
                                                                 allocation_limit=allocation_limit,
                                                                 allocation_type=allocation_type)
                        relation.save()
                else:
                    steward = Steward.objects.get(key=owner_key, trash=False)
                    guilds.stewards.add(steward)
                    relation = KillHouseStewardGuildRelation(guild=guilds, steward=steward,
                                                             allocation_limit=allocation_limit,
                                                             allocation_type=allocation_type)
                    relation.save()

            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(trash=False, user=request.user)
        role = request.GET.get('role')
        role_type = request.GET.get('role_type')
        key = request.GET.get('key')
        guild_type = request.GET.get('type')
        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(trash=False, kill_house_operator__user=user).first()
            if guild_type == 'guild':
                guilds = Guilds.objects.filter(trash=False, province_accept_state__in=('pending', 'accepted'),
                                               steward=False).exclude(
                    id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True))
            else:
                guilds = Guilds.objects.filter(trash=False, province_accept_state__in=('pending', 'accepted'),
                                               steward=True).exclude(
                    id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True))

        elif role == 'Steward':
            steward = Guilds.objects.get(user=user, steward=True, trash=False)
            guilds = steward.guild_stewards.all().filter(trash=False, province_accept_state__in=(
                'pending', 'accepted')).order_by('id')

        else:
            if role_type == 'KillHouse':
                kill_house = KillHouse.objects.get(key=key)
                if guild_type == 'guild':
                    guilds = Guilds.objects.filter(trash=False, province_accept_state__in=('pending', 'accepted'),
                                                   steward=False).exclude(
                        id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True))
                else:
                    guilds = Guilds.objects.filter(trash=False, province_accept_state__in=('pending', 'accepted'),
                                                   steward=True).exclude(
                        id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True))

            else:
                steward = Guilds.objects.get(key=key)
                guilds = steward.guild_stewards.all().filter(trash=False, province_accept_state__in=(
                    'pending', 'accepted')).order_by('id')

        serializer = self.serializer_class(guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        guilds = Guilds.objects.get(key=request.data['guilds_key'], trash=False)
        system_user_profile = SystemUserProfile.objects.get(key=guilds.user.key, trash=False)
        address = SystemAddress.objects.get(key=guilds.address.key, trash=False)

        if 'choose' in request.data.keys():
            role_type = request.data['type']
            if role_type == 'KillHouse':
                kill_house = KillHouse.objects.get(key=request.data['owner_key'])
                if request.data['choose_type'] == 'guild':
                    guilds.kill_house.add(kill_house)
                    relation = KillHouseStewardGuildRelation(guild=guilds, kill_house=kill_house,
                                                             allocation_limit=request.data['allocation_limit'],
                                                             allocation_type=request.data['allocation_type'])
                else:
                    guilds.steward_kill_house.add(kill_house)
                    relation = KillHouseStewardGuildRelation(steward=guilds, kill_house=kill_house,
                                                             allocation_limit=request.data['allocation_limit'],
                                                             allocation_type=request.data['allocation_type'])

                relation.save()

            else:

                steward = Guilds.objects.get(key=request.data['owner_key'])
                guilds.stewards.add(steward)
                relation = KillHouseStewardGuildRelation(guild=guilds, steward=steward,
                                                         allocation_limit=request.data['allocation_limit'],
                                                         allocation_type=request.data['allocation_type'])
                relation.save()
            request.data.pop('choose')
            request.data.pop('type')
            request.data.pop('owner_key')
            request.data.pop('allocation_limit')
            request.data.pop('allocation_type')
            request.data.pop('choose_type')

        if 'KillHouseList' in request.data.keys():
            kill_houses = KillHouse.objects.filter(key__in=request.data['KillHouseList']).order_by('id')
            guilds.kill_house.set(kill_houses)
            KillHouseStewardGuildRelation.objects.filter(guild=guilds, kill_house__isnull=False).delete()

            relations = [
                KillHouseStewardGuildRelation(guild=guilds, kill_house=kill_house)
                for kill_house in kill_houses
            ]

            KillHouseStewardGuildRelation.objects.bulk_create(relations)
            # guilds.guild_kill_houses.clear()
            # guilds.guild_kill_houses.add(*kill_houses)
        if 'StewardList' in request.data.keys():
            stewards = Guilds.objects.filter(key__in=request.data['StewardList']).order_by('id')
            guilds.stewards.set(stewards)
            request.data.pop('StewardList')

        if 'StewardKillHouseList' in request.data.keys():
            kill_houses = KillHouse.objects.filter(key__in=request.data['StewardKillHouseList']).order_by('id')
            guilds.steward_kill_house.set(kill_houses)
            request.data.pop('StewardKillHouseList')

        if 'type_activity' in request.data.keys():
            type_activity = TypeActivity.objects.get(title=request.data['type_activity'])
            area_activity = AreaActivity.objects.get(title=request.data['area_activity'])
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.save()
            request.data.pop('type_activity')
            request.data.pop('area_activity')

        if 'first_name' in request.data.keys():
            system_user_profile.first_name = request.data['first_name']
            system_user_profile.last_name = request.data['last_name']
            system_user_profile.fullname = request.data['first_name'] + " " + request.data['last_name']
            system_user_profile.national_id = request.data['national_id']
            system_user_profile.save()
            first_mobile_number = system_user_profile.mobile
            second_mobile_number = request.data['mobile']
            request.data.pop('mobile')
            if first_mobile_number != second_mobile_number:
                if SystemUserProfile.objects.filter(mobile=second_mobile_number).exists():
                    return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
                                    status=status.HTTP_403_FORBIDDEN)
                data = {
                    "first_mobile_number": first_mobile_number,
                    "second_mobile_number": second_mobile_number,
                }
                req = requests.post(
                    url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                    data=data,
                    verify=False
                )
                if req.status_code == 200:
                    second_mobile_number = second_mobile_number
                    user = User.objects.get(id=system_user_profile.user.id)
                    user.username = second_mobile_number
                    user.save()
                    system_user_profile.mobile = second_mobile_number
                    system_user_profile.save()

            city = City.objects.get(name=request.data['city'])
            province = Province.objects.get(key=city.province.key)
            address.city = city
            address.province = province
            address.address = request.data['address']
            address.postal_code = request.data['postal_code']
            address.save()
            request.data.pop('guilds_key')
            request.data.pop('first_name')
            request.data.pop('last_name')
            request.data.pop('address')
            request.data.pop('national_id')
            request.data.pop('city')
        serializer = self.serializer_class(guilds)
        serializer.update(instance=guilds, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class RegisterGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RealGuildsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query

    def set_filter(self, role, status):
        filters = {'trash': False}
        if status == 'temporary_registration':
            filters['temporary_registration'] = True

        return filters

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        group = Group.objects.get(name__exact="Guilds")
        role = request.data.pop('role', None)
        city = request.data.pop('city', None)
        mobile = request.data.pop('mobile', None)
        first_name = request.data.pop('first_name', None)
        last_name = request.data.pop('last_name', None)
        address = request.data.pop('address', None)
        national_id = request.data.pop('national_id', None)
        postal_code = request.data.pop('postal_code', None)
        type_activity = request.data.pop('type_activity', None)
        area_activity = request.data.pop('area_activity', None)
        license_file = request.data.pop('license_file', None)
        type_activity = TypeActivity.objects.get(title=type_activity)
        area_activity = AreaActivity.objects.get(title=area_activity)
        register = register_user(group, city, mobile, first_name,
                                 last_name, national_id, postal_code,
                                 address)
        if not register:
            return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است"}, status=status.HTTP_403_FORBIDDEN)

        if register == 'exist':
            return Response({"result": "این صنف قبلا ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            guilds = serializer.create(validated_data=request.data)
            guilds.user = register["system_profile"]
            guilds.address = register["address"]
            guilds.wallet = register["wallet"]
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.registerar_role = role
            guilds.registerar_fullname = user.fullname
            guilds.registerar_mobile = user.mobile
            if license_file:
                guilds.license_file = send_image_to_server(license_file)
                guilds.license = True
                guilds.final_accept = True
            else:
                guilds.temporary_registration = True

            guilds.save()

            if guilds.license_file:
                parent_product = NewProduct.objects.all().first()
                approved_type = True if parent_product.approved_price_status == True else False
                approved_price = parent_product.approved_price
                product = RolesProducts(
                    parent_product=parent_product,
                    guild=guilds,
                    name='مرغ گرم',
                    approved_price_status=approved_type,
                    approved_price=approved_price,
                )
                product.save()
            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        status = request.GET.get('status')
        filters = self.set_filter(role, status) if role and status else {}
        guilds = Guilds.objects.filter(**filters).order_by('id')
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                guilds = guilds.filter(
                    self.build_query(value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds.distinct())
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class StewardForColdHouseViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PosGuildsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

    def list(self, request, *args, **kwargs):
        if 'total' in request.GET:
            guilds = Guilds.objects.filter(trash=False, steward=True,
                                           pk__in=ColdHouse.objects.filter(steward__isnull=False).values_list('steward',
                                                                                                              flat=True)).order_by(
                'id')
            value = request.GET.get('value')
            search = request.GET.get('search')
            if value and search == 'filter':
                if value != 'undefined' and value.strip():
                    guilds = guilds.filter(
                        self.build_query(value)
                    )

            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(guilds.distinct())
            if page is not None:
                serializer = GuildsForTotalColdHouseSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)

            serializer = GuildsForTotalColdHouseSerializer(guilds, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

        guilds = Guilds.objects.filter(trash=False, steward=True).exclude(
            pk__in=ColdHouse.objects.filter(steward__isnull=False).values_list('steward', flat=True)).order_by(
            'id').select_related('user', 'user__city', 'user__province').only('user', 'user__city', 'user__province')
        serializer = GuildsForColdHouseSerializer(guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query


class StewardColdHousesViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardColdHousesSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(user=user, trash=False)
        serializer = self.get_serializer(steward)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosGuildsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

    def list(self, request, *args, **kwargs):
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)
        rel_type = request.GET.get('rel_type')
        type = request.GET.get('type')

        if pos.kill_house:
            if rel_type and type:
                if rel_type == "free":
                    if type == 'guild':
                        guilds = Guilds.objects.filter(trash=False, steward=False, active=True).exclude(
                            id__in=pos.kill_house.guild_kill_houses.values_list('id', flat=True)
                        ).order_by('id').only(
                            'guilds_name', 'type_activity', 'area_activity', 'guilds_id', 'steward'
                        )
                    else:
                        guilds = Guilds.objects.filter(trash=False, steward=True, active=True).exclude(
                            id__in=pos.kill_house.steward_kill_houses.values_list('id', flat=True)).order_by('id').only(
                            'guilds_name', 'type_activity', 'area_activity', 'guilds_id', 'steward'
                        )

                else:
                    if type == 'guild':
                        guilds = Guilds.objects.filter(
                            id__in=pos.kill_house.guild_kill_houses.all().values_list('id', flat=True),
                            steward=False, active=True).order_by(
                            'id').only('guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward')

                    else:
                        guilds = Guilds.objects.filter(
                            id__in=pos.kill_house.steward_kill_houses.all().values_list('id', flat=True),
                            steward=True, active=True).order_by(
                            'steward').only('guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id',
                                            'steward')

            else:
                guilds = Guilds.objects.filter(trash=False)

        else:
            if rel_type and type:
                if rel_type == "free":
                    if type == 'guild':
                        guilds = Guilds.objects.filter(trash=False, steward=False, active=True).exclude(
                            id__in=Guilds.objects.filter(stewards=pos.guild, trash=False,
                                                         province_accept_state__in=('pending', 'accepted')).values_list(
                                'id',
                                flat=True)).only(
                            'guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward')

                    else:

                        guilds = Guilds.objects.filter(trash=False, steward=True, active=True).exclude(
                            id=pos.guild.id).only(
                            'guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward')

                else:
                    if type == 'guild':
                        guilds = Guilds.objects.filter(stewards=pos.guild, trash=False,
                                                       province_accept_state__in=('pending', 'accepted'),
                                                       steward=False, active=True).order_by('id').only(
                            'guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward')
                    else:
                        guilds = Guilds.objects.filter(stewards=pos.guild, trash=False,
                                                       province_accept_state__in=('pending', 'accepted'),
                                                       steward=True, active=True).order_by(
                            'id').only(
                            'guilds_name', 'user', 'type_activity', 'area_activity', 'guilds_id', 'steward')
            else:
                guilds = Guilds.objects.filter(trash=False).order_by('steward')

        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                guilds = guilds.filter(
                    self.build_query(value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds.distinct())
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = PosGuildsForBroadcastManagementSerializer(guilds.distinct(), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query


class ProvinceCheckKillHouseGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsSerializer

    def create(self, request, *args, **kwargs):
        guilds = Guilds.objects.get(key=request.data['guilds_key'])
        request.data.pop('guilds_key')
        role = request.data.pop('role')

        steward = Steward.objects.filter(guilds=guilds, trash=False).last()
        if request.data['state'] == 'accepted':
            guilds.province_accept_state = 'accepted'
            if guilds.active_register_code and guilds.logged_register_code is None:
                code = request.data.get('code')
                if code != guilds.register_code:
                    return Response({'result': "کد وارد شده معتبر نمیباشد!"}, status=status.HTTP_403_FORBIDDEN)
                if role not in ['AdminX', 'SuperAdmin', 'ProvinceOperator']:
                    guilds.province_accept_state = 'pending'
                guilds.logged_register_code = code
                guilds.active_register_code = True
                guilds.is_registered = True
            guilds.save()
            if steward:
                steward.province_accept_state = 'accepted'
                steward.save()

        else:
            guilds.province_accept_state = 'rejected'
            guilds.province_message = request.data['message']
            guilds.save()
            if steward:
                steward.province_accept_state = 'rejected'
                steward.save()

        return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_200_OK)


class TotalGuildsForCompaniesViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsForCompaniesSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet
    filterset_fields = [
        'user__mobile',
        'user__first_name',
        'user__last_name',
        'address__city__name',
        'guilds_name',
        'type_activity',
        'area_activity',

    ]

    def update(self, request, pk=None, *args, **kwargs):
        guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
        request.data.pop('guild_key')
        serializer = self.serializer_class(guild)
        serializer.update(instance=guild, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query

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

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        pos_company = PosCompany.objects.get(user=user, trash=False)
        # pos = POSMachine.objects.filter(pos_company=pos_company, trash=False).select_related('guild').only(
        #     'guild').values_list('guild', flat=True).distinct()

        guilds = Guilds.objects.filter(trash=False,
                                       address__province=user.province).order_by('-has_pos')
        # guilds = Guilds.objects.filter(Q(id__in=pos) | Q(has_pos=False), trash=False,
        #                                address__province=user.province).order_by('-has_pos')

        if 'value' in request.GET and request.GET['value'] == 'undefined':
            pass
        else:
            value = request.GET.get('value')
            search = request.GET.get('search')
            guilds_list = []
            if value and search == 'filter':
                if value != 'undefined' and value.strip():
                    guilds = guilds.filter(
                        self.build_query(value)
                    )
            # if request.GET['search'] == 'filter':
            #     if request.GET['value'] != "":
            #         for item in self.filterset_fields:
            #             query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
            #             if (self.filterset_class(
            #                     data=query,
            #                     queryset=guilds
            #             )
            #             ).filter():
            #                 ps = self.filterset_class(data=query, queryset=guilds)
            #                 guilds_list = ps.filter()
            #         guilds = [] if len(guilds_list) == 0 else guilds_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds)
        if page is not None:
            serializer = self.get_serializer(page, context={'company': pos_company.name}, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = GuildsForCompaniesSerializer(guilds, context={'company': pos_company.name}, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalGuildsForInspectionViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [AllowAny]
    serializer_class = GuildsForCompaniesSerializer

    def list(self, request, *args, **kwargs):
        guilds = Guilds.objects.filter(trash=False, province_accept_state='accepted')
        serializer = GuildsForInspectionSerializer(guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

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

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.GET['role'] in ['CityCommerce', 'CityOperator', 'CityJahad', 'CityPoultry']:
            guilds = Guilds.objects.filter(trash=False, province_accept_state='accepted',
                                           address__city=user.city).exclude(user__national_id='0').order_by('id')
        elif request.GET['role'] == 'Steward':

            steward = Guilds.objects.get(user=user, trash=False).exclude(user__national_id='0')
            guilds = Guilds.objects.filter(stewards=steward).exclude(user__national_id='0').order_by('id')


        elif request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            if 'steward' in request.GET and request.GET['steward'] == 'true':
                guilds = kill_house.steward_kill_houses.all().filter(trash=False, steward=True,
                                                                     province_accept_state__in=(
                                                                         'pending', 'accepted')).exclude(
                    user__national_id='0').order_by(
                    '-is_registered', '-id')
            else:
                # guilds = kill_house.guild_kill_houses.all().filter(trash=False,
                #                                                    province_accept_state__in=(
                #                                                        'pending', 'accepted')).order_by('id')
                guilds = Guilds.objects.filter(
                    Q(id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True)) | Q(
                        id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True))).exclude(
                    user__national_id='0').order_by(
                    '-is_registered', '-id')

        else:
            if 'check' in request.GET:
                if request.GET['state'] == 'pending':
                    guilds = Guilds.objects.filter(
                        # Q(kill_house_register=True) | Q(steward_register=True) | Q(pos_company_register=True),
                        province_accept_state='pending',
                        trash=False).exclude(user__national_id='0').order_by('-id')
                else:
                    guilds = Guilds.objects.filter(kill_house_register=True,
                                                   trash=False).exclude(user__national_id='0').order_by('id')
            else:
                is_real_person = request.GET.get('is_real_person')
                filters = {"province_accept_state": "accepted", "trash": False}
                active = request.GET.get('active_state')
                if active == 'active':
                    filters['active'] = True
                elif active == 'deactive':
                    filters['active'] = False
                if is_real_person:
                    if is_real_person == 'false':
                        filters["is_real_person"] = False
                    else:
                        filters["is_real_person"] = True
                if 'steward' in request.GET and request.GET['steward'] == 'true':
                    guilds = Guilds.objects.filter(**filters, steward=True).exclude(user__national_id='0').order_by(
                        'id')
                else:
                    guilds = Guilds.objects.filter(**filters).exclude(user__national_id='0').order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds.distinct())
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = GuildsSerializer(guilds.distinct(), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query


# class TotalGuildsDistributionManagementViewSet(viewsets.ModelViewSet):
#     queryset = Guilds.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = GuildsForDistributionManagementSerializer
#     pagination_class = CustomPagination
#     filter_backends = [DjangoFilterBackend]
#     filterset_class = GuildsFilterSet
#
#     def build_query(self, value):
#         from django.db.models import Q
#         query = Q()
#         for field in self.filterset_class.Meta.fields:
#             query |= Q(**{f"{field}__icontains": value})
#         return query
#
#     def list(self, request, *args, **kwargs):
#         user = SystemUserProfile.objects.get(user=request.user, trash=False)
#         management_type = request.GET.get('management_type')
#         role_type = request.GET.get('role_type')
#         type = request.GET.get('type')
#
#         if role_type == 'KillHouse':
#             kill_house = KillHouse.objects.get(key=request.GET.get('key'))
#             if management_type == 'subcategories':
#                 if type == 'guild':
#                     guilds = kill_house.guild_kill_houses.all().filter(trash=False, province_accept_state__in=(
#                         'pending', 'accepted')).order_by('id')
#                 elif type == 'steward':
#                     guilds = kill_house.steward_kill_houses.all().filter(trash=False, steward=True,
#                                                                          province_accept_state__in=(
#                                                                              'pending', 'accepted')).order_by('id')
#                 else:
#                     guilds = Guilds.objects.filter(
#                         Q(id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True)) | Q(
#                             id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True))).order_by(
#                         'steward')
#             else:
#                 if type == 'guild':
#                     guilds = Guilds.objects.filter(trash=False, steward=False,
#                                                    province_accept_state__in=('pending', 'accepted')).exclude(
#                         kill_house.guild_kill_houses.all()).order_by('id')
#                 elif type == 'steward':
#                     guilds = Guilds.objects.filter(trash=False, steward=True,
#                                                    province_accept_state__in=('pending', 'accepted')).exclude(
#                         kill_house.steward_kill_houses.all()).order_by('id')
#                 else:
#                     guilds = Guilds.objects.filter(trash=False, steward=True,
#                                                    province_accept_state__in=('pending', 'accepted')).exclude(
#                         Q(id__in=kill_house.guild_kill_houses.all().values_list('id', flat=True)) | Q(
#                             id__in=kill_house.steward_kill_houses.all().values_list('id', flat=True))).order_by(
#                         'steward')
#         else:
#             steward = Guilds.objects.get(key=request.GET.get('key'))
#             if management_type == 'subcategories':
#                 guilds = steward.guild_stewards.all().filter(trash=False, province_accept_state__in=(
#                     'pending', 'accepted')).order_by('id')
#
#             else:
#                 guilds = Guilds.objects.filter(trash=False, steward=True,
#                                                province_accept_state__in=('pending', 'accepted')).exclude(
#                     id__in=steward.guild_stewards.all().values_list('id', flat=True)).order_by('id')
#
#         value = request.GET.get('value')
#         search = request.GET.get('search')
#         if value and search == 'filter':
#             if value != 'undefined' and value.strip():
#                 guilds = guilds.filter(
#                     self.build_query(value)
#                 )
#
#         page_size = request.query_params.get('page_size', None)
#         if page_size:
#             self.pagination_class.page_size = int(page_size)
#
#         page = self.paginate_queryset(guilds.distinct())
#         if page is not None:
#             if management_type == 'subcategories' and role_type == 'KillHouse':
#                 serializer = self.get_serializer(page, many=True,
#                                                  context={'role_type': 'KillHouse', 'role_object': kill_house,
#                                                           'type': type})
#             elif management_type == 'subcategories' and role_type == 'Steward':
#                 serializer = self.get_serializer(page, many=True,
#                                                  context={'role_type': 'Steward', 'role_object': steward})
#             else:
#                 serializer = self.get_serializer(page, many=True, context={'role_type': None})
#             return self.get_paginated_response(serializer.data)
#         if management_type == 'subcategories' and role_type == 'KillHouse':
#             serializer = GuildsForDistributionManagementSerializer(guilds.distinct(), many=True,
#                                                                    context={'role_type': 'KillHouse',
#                                                                             'role_object': kill_house, 'type': type})
#         elif management_type == 'subcategories' and role_type == 'Steward':
#             serializer = GuildsForDistributionManagementSerializer(guilds.distinct(), many=True,
#                                                                    context={'role_type': 'Steward',
#                                                                             'role_object': steward})
#         else:
#
#             serializer = GuildsForDistributionManagementSerializer(guilds.distinct(), many=True,
#                                                                    context={'role_type': None})
#         return Response(serializer.data, status=status.HTTP_200_OK)


class TotalGuildsDistributionManagementViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsForDistributionManagementSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query

    def create(self, request, *args, **kwargs):
        group = Group.objects.get(name__exact="Guilds")
        role = request.data['role']
        type_activity = TypeActivity.objects.get(title=request.data['type_activity'])
        area_activity = AreaActivity.objects.get(title=request.data['area_activity'])
        register = register_user(group, request.data['city'], request.data['mobile'], request.data['first_name'],
                                 request.data['last_name'], request.data['national_id'], request.data['postal_code'],
                                 request.data['address'])
        if not register:
            return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است"}, status=status.HTTP_403_FORBIDDEN)
        request.data.pop('city')
        request.data.pop('role')
        request.data.pop('mobile')
        request.data.pop('first_name')
        request.data.pop('last_name')
        request.data.pop('address')
        request.data.pop('national_id')
        request.data.pop('postal_code')
        request.data.pop('type_activity')
        request.data.pop('area_activity')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            guilds = serializer.create(validated_data=request.data)
            guilds.user = register["system_profile"]
            guilds.address = register["address"]
            guilds.wallet = register["wallet"]
            guilds.type_activity = type_activity.title
            guilds.area_activity = area_activity.title
            guilds.guild_type_activity = type_activity
            guilds.guild_area_activity = area_activity
            guilds.save()
            parent_product = NewProduct.objects.all().first()
            approved_type = True if parent_product.approved_price_status == True else False
            approved_price = parent_product.approved_price
            product = RolesProducts(
                parent_product=parent_product,
                guild=guilds,
                name='مرغ گرم',
                approved_price_status=approved_type,
                approved_price=approved_price,
            )
            product.save()
            if role == 'KillHouse':
                user = SystemUserProfile.objects.get(user=request.user)
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).order_by(
                    'id').first()
                guilds.kill_house_centers_allocation = [
                    {"label": kill_house.name, "value": str(kill_house.key)}]
                guilds.province_accept_state = 'pending'
                guilds.kill_house_register = True

                guilds.save()

                if guilds.steward == True:
                    guilds.steward_kill_house.add(kill_house)

                else:
                    guilds.kill_house.add(kill_house)

            elif role == 'Guilds':
                user = SystemUserProfile.objects.get(user=request.user)
                steward = Steward.objects.get(guilds__user=user, trash=False)

                guilds.centers_allocation = [
                    {"label": steward.guilds.user.fullname, "value": str(steward.key)}]
                guilds.province_accept_state = 'pending'
                guilds.steward_register = True
                guilds.save()

            elif role == 'PosCompany':
                guilds.province_accept_state = 'pending'
                guilds.pos_company_register = True
                guilds.save()
            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        type = request.GET.get('type')
        role = request.GET.get('role')
        role_type = request.GET.get('role_type')
        key = request.GET.get('key')
        city_name = request.GET.get('city_name')
        type_activity = request.GET.get('type_activity')
        user_level = request.GET.get('user_level')
        role_object = None
        type_object = None

        if role == 'KillHouse':

            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            if type == 'guild':
                guilds = kill_house.guild_kill_houses.all().filter(trash=False, province_accept_state__in=(
                    'pending', 'accepted')).order_by('id')

            else:
                guilds = kill_house.steward_kill_houses.all().filter(trash=False, steward=True,
                                                                     province_accept_state__in=(
                                                                         'pending', 'accepted')).order_by('id')
            role_object = kill_house
            type_object = 'KillHouse'


        elif role == 'Steward':
            steward = Guilds.objects.get(user=user, trash=False)
            guilds = steward.guild_stewards.all().filter(trash=False, province_accept_state__in=(
                'pending', 'accepted')).order_by('id')
            role_object = steward
            type_object = 'Steward'


        else:
            if key:
                if role_type == 'KillHouse':
                    kill_house = KillHouse.objects.get(key=key, trash=False)
                    if type == 'guild':
                        guilds = kill_house.guild_kill_houses.all().filter(trash=False, province_accept_state__in=(
                            'pending', 'accepted')).order_by('id')

                    else:
                        guilds = kill_house.steward_kill_houses.all().filter(trash=False, steward=True,
                                                                             province_accept_state__in=(
                                                                                 'pending', 'accepted')).order_by('id')
                    role_object = kill_house
                    type_object = 'KillHouse'
                else:
                    steward = Guilds.objects.get(key=key, trash=False)
                    guilds = steward.guild_stewards.all().filter(trash=False, province_accept_state__in=(
                        'pending', 'accepted')).order_by('id')

                    role_object = steward
                    type_object = 'Steward'
            else:
                if type == 'guild':

                    guilds = Guilds.objects.filter(trash=False, steward=False,
                                                   province_accept_state__in=(
                                                       'pending', 'accepted')).order_by('id')

                else:
                    guilds = Guilds.objects.filter(trash=False, steward=True,
                                                   province_accept_state__in=(
                                                       'pending', 'accepted')).order_by('id')

        if city_name:
            guilds = guilds.filter(user__city__name__icontains=city_name)

        if type_activity:
            guilds = guilds.filter(type_activity__icontains=type_activity)
        if user_level:
            guilds = guilds.filter(user_level__fa_title__icontains=user_level)
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                guilds = guilds.filter(
                    self.build_query(value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds.distinct())
        if page is not None:
            serializer = self.get_serializer(page, many=True,
                                             context={'role_object': role_object, 'type_object': type_object,
                                                      'type': type})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(guilds.distinct(), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TestTotalGuildsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TestGuildsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = TestGuildsFilterSet

    def list(self, request, *args, **kwargs):
        guilds = Guilds.objects.filter(province_accept_state='accepted', trash=False).order_by('id')
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                filtered_guilds = guilds.filter(
                    self.build_query(value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(filtered_guilds)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = GuildsSerializer(filtered_guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query


# class StewardViewSet(viewsets.ModelViewSet):
#     # queryset = Steward.objects.all()
#     # permission_classes = [TokenHasReadWriteScope]
#     # serializer_class = StewardSerializer
#     queryset = Guilds.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = GuildsSerializer
#     pagination_class = CustomPagination
#     filter_backends = [DjangoFilterBackend]
#     filterset_class = GuildsFilterSet
#     filterset_fields = [
#         'user__mobile',
#         'user__first_name',
#         'user__last_name',
#         'user__city__name',
#         'user__province__name',
#         'address__city__name',
#         'guilds_name',
#         'type_activity',
#         'area_activity',
#
#     ]
#
#     def create(self, request, *args, **kwargs):
#         guilds = Guilds.objects.get(key=request.data['guilds_key'])
#         request.data.pop('guilds_key')
#         if Steward.objects.filter(guilds=guilds, trash=False).exists():
#             return Response({"result": "این صنف قبلا به عنوان مباشر ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)
#         serializer = self.serializer_class(data=request.data)
#         if serializer.is_valid():
#             steward = serializer.create(validated_data=request.data)
#             steward.guilds = guilds
#             steward.save()
#             guilds.steward = True
#             guilds.save()
#             return Response(serializer.data, status=status.HTTP_201_CREATED)
#         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#
#     def update(self, request, pk=None, *args, **kwargs):
#         steward = Steward.objects.get(key=request.data['steward_key'], trash=False)
#         guild = Guilds.objects.get(key=steward.guilds.key, trash=False)
#         if 'allocation_limit' in request.data.keys():
#             if request.data['allocation_limit'] == "":
#                 steward.allocation_limit = None
#                 steward.save()
#                 request.data.pop('allocation_limit')
#         request.data.pop('steward_key')
#         if 'centers_allocation' in request.data.keys() and request.data['centers_allocation'] != None:
#             guild.kill_house_centers_allocation = request.data['centers_allocation']
#             guild.save()
#         serializer = self.serializer_class(steward)
#         serializer.update(instance=steward, validated_data=request.data)
#         return Response(serializer.data, status=status.HTTP_200_OK)
#
#     def list(self, request, *args, **kwargs):
#         user = SystemUserProfile.objects.get(user=request.user, trash=False)
#
#         if request.GET['role'] in ['CityCommerce', 'CityJahad', 'CityPoultry']:
#             stewards = Guilds.objects.filter(trash=False, address__city=user.city).order_by('id')
#
#         elif request.GET['role'] in ['ProvinceOperator', 'Commerce', 'ProvinceSupervisor''GuildRoom', 'SuperAdmin',
#                                      'ImprovingLivestock', 'AdminX', 'Supporter']:
#             stewards = Guilds.objects.filter(trash=False, address__province=user.province,
#                                              steward=True).order_by('id')
#
#         else:
#             stewards = Guilds.objects.filter(steward=True, trash=False).order_by('id')
#             if 'kill_house_key' in request.GET:
#                 kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)
#             else:
#                 kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
#             # now = datetime.now().date()
#             # date = datetime.strptime(str(request.GET['date']),
#             #                          '%Y-%m-%d').date() if 'date' in request.GET else now
#             # stewards_list = []
#             # if 'kill_house_key' in request.GET:
#             #     # if 'allocation' in request.GET:
#             #     for steward in stewards:
#             #         if steward.centers_allocation != None:
#             #             for center_allocation in steward.centers_allocation:
#             #                 if request.GET['kill_house_key'] == center_allocation['value']:
#             #                     if not StewardAllocation.objects.filter(
#             #                             Q(type='manual') | Q(type='auto',
#             #                                                  system_registration_code=True), date__date=date,
#             #                             steward=steward,
#             #                             ware_house__kill_house=kill_house, trash=False).exists():
#             #                         stewards_list.append(steward)
#             # else:
#             #     for steward in stewards:
#             #         if steward.centers_allocation == None:
#             #             stewards_list.append(steward)
#             #         else:
#             #             counter = 0
#             #             if len(steward.centers_allocation) == 0:
#             #                 continue
#             #             for center_allocation in steward.centers_allocation:
#             #
#             #                 if str(kill_house.key) != center_allocation['value']:
#             #                     counter += 1
#             #             if steward not in stewards_list and counter == len(steward.centers_allocation):
#             #                 stewards_list.append(steward)
#             #
#             # stewards = stewards_list
#
#         if 'search' in request.GET:
#             if 'value' in request.GET and request.GET['value'] == 'undefined':
#                 pass
#             else:
#                 # if 'search' in request.GET:
#                 steward_list = []
#                 if request.GET['search'] == 'filter':
#                     if request.GET['value'] != "":
#                         for item in self.filterset_fields:
#                             query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
#                             if (self.filterset_class(
#                                     data=query,
#                                     queryset=stewards
#                             )
#                             ).filter():
#                                 ps = self.filterset_class(data=query, queryset=stewards)
#                                 steward_list = ps.filter()
#                         stewards = [] if len(steward_list) == 0 else steward_list
#         if 'page_size' in request.GET:
#             page_size = request.query_params.get('page_size', None)
#             if page_size:
#                 self.pagination_class.page_size = int(page_size)
#
#             page = self.paginate_queryset(stewards)
#             if page is not None:
#                 serializer = self.get_serializer(page, many=True)
#                 return self.get_paginated_response(serializer.data)
#
#         serializer = GuildsForStewardMenueSerializer(stewards, many=True)
#         return Response(serializer.data, status=status.HTTP_200_OK)


class StewardViewSet(viewsets.ModelViewSet):
    queryset = Steward.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardSerializer

    def create(self, request, *args, **kwargs):
        guilds = Guilds.objects.get(key=request.data['guilds_key'])
        request.data.pop('guilds_key')
        if Steward.objects.filter(guilds=guilds, trash=False).exists():
            return Response({"result": "این صنف قبلا به عنوان مباشر ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            steward = serializer.create(validated_data=request.data)
            steward.guilds = guilds
            steward.save()
            guilds.steward = True
            guilds.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        steward = Steward.objects.get(key=request.data['steward_key'], trash=False)
        guild = Guilds.objects.get(key=steward.guilds.key, trash=False)
        if 'allocation_limit' in request.data.keys():
            if request.data['allocation_limit'] == "":
                steward.allocation_limit = None
                steward.save()
                request.data.pop('allocation_limit')
        request.data.pop('steward_key')
        if 'centers_allocation' in request.data.keys() and request.data['centers_allocation'] != None:
            guild.kill_house_centers_allocation = request.data['centers_allocation']
            guild.save()
        serializer = self.serializer_class(steward)
        serializer.update(instance=steward, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.GET['role'] in ['ProvinceOperator', 'Commerce', 'ProvinceSupervisor''GuildRoom', 'SuperAdmin',
                                   'ImprovingLivestock', 'AdminX', 'Supporter']:
            stewards = Steward.objects.filter(trash=False, guilds__address__province=user.province,
                                              guilds__steward=True).exclude(
                guilds__user__national_id='0').select_related('guilds').order_by('id')
        elif request.GET['role'] == 'CityCommerce':
            stewards = Steward.objects.filter(trash=False, guilds__address__city=user.city).exclude(
                guilds__user__national_id='0').order_by('id')


        else:
            stewards = Steward.objects.filter(guilds__steward=True, trash=False).exclude(
                guilds__user__national_id='0').order_by('id')
            if 'kill_house_key' in request.GET:
                kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)
            else:
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            now = datetime.now().date()
            date = datetime.strptime(str(request.GET['date']),
                                     '%Y-%m-%d').date() if 'date' in request.GET else now
            stewards_list = []
            if 'kill_house_key' in request.GET:
                # if 'allocation' in request.GET:
                for steward in stewards:
                    if steward.centers_allocation != None:
                        for center_allocation in steward.centers_allocation:
                            if request.GET['kill_house_key'] == center_allocation['value']:
                                if not StewardAllocation.objects.filter(
                                        Q(type='manual') | Q(type='auto',
                                                             system_registration_code=True), date__date=date,
                                        steward=steward,
                                        ware_house__kill_house=kill_house, trash=False).exists():
                                    stewards_list.append(steward)
            else:
                for steward in stewards:
                    if steward.centers_allocation == None:
                        stewards_list.append(steward)
                    else:
                        counter = 0
                        if len(steward.centers_allocation) == 0:
                            continue
                        for center_allocation in steward.centers_allocation:

                            if str(kill_house.key) != center_allocation['value']:
                                counter += 1
                        if steward not in stewards_list and counter == len(steward.centers_allocation):
                            stewards_list.append(steward)

            stewards = stewards_list

        serializer = StewardSerializer(stewards, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


def steward_allocations_sms(allocations_list):
    steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list,
                                                           trash=False)
    for steward_allocation in steward_allocations:
        buyer = None
        if steward_allocation.to_steward:
            buyer = steward_allocation.to_steward.guilds_name
        if steward_allocation.to_guilds:
            buyer = steward_allocation.to_guilds.guilds_name

        date_str = str(steward_allocation.date.date())
        date = datetime.strptime(date_str, '%Y-%m-%d')
        date = jdatetime.datetime.fromgregorian(year=date.year, month=date.month, day=date.day).strftime(
            '%Y-%m-%d')
        date_list = reversed(date.split('-'))
        separate = "-"
        date = separate.join(date_list)
        number = str(steward_allocation.registration_code)
        quantity = str(steward_allocation.number_of_carcasses)
        weight = str(int(steward_allocation.weight_of_carcasses))
        # kill_house = str(steward_allocation.ware_house.kill_house.name)
        if steward_allocation.kill_house:
            seller = steward_allocation.kill_house.name

        elif steward_allocation.to_cold_house:
            seller = steward_allocation.to_cold_house.kill_house.name

        elif steward_allocation.steward:
            seller = steward_allocation.steward.user.fullname
        else:
            seller = steward_allocation.guilds.user.fullname
        if steward_allocation.interface_number:
            mobile = steward_allocation.interface_number
        else:
            if steward_allocation.to_steward:
                mobile = steward_allocation.to_steward.user.mobile

            elif steward_allocation.to_guilds:
                mobile = steward_allocation.to_guilds.user.mobile
            elif steward_allocation.to_cold_house:
                if steward_allocation.to_cold_house.kill_house:
                    mobile = steward_allocation.to_cold_house.kill_house.kill_house_operator.user.mobile
                else:
                    mobile = steward_allocation.to_cold_house.live_stock_support.user.mobile

                mobile = steward_allocation.to_guilds.user.mobile
            else:
                mobile = steward_allocation.to_kill_house.kill_house_operator.user.mobile

        steward_allocation_sms(mobile, date, weight, seller, number, buyer, steward_allocation.amount)


def automatic_steward_allocations_sms(allocations_list):
    steward_allocations = AutomaticStewardAllocation.objects.filter(key__in=allocations_list,
                                                                    trash=False)
    for steward_allocation in steward_allocations:
        buyer = None
        if steward_allocation.to_steward:
            buyer = steward_allocation.to_steward.guilds_name
        if steward_allocation.to_guilds:
            buyer = steward_allocation.to_guilds.guilds_name

        date_str = str(steward_allocation.date.date())
        date = datetime.strptime(date_str, '%Y-%m-%d')
        date = jdatetime.datetime.fromgregorian(year=date.year, month=date.month, day=date.day).strftime(
            '%Y-%m-%d')
        date_list = reversed(date.split('-'))
        separate = "-"
        date = separate.join(date_list)
        number = str(steward_allocation.registration_code)
        quantity = str(steward_allocation.number_of_carcasses)
        weight = str(int(steward_allocation.weight_of_carcasses))
        # kill_house = str(steward_allocation.ware_house.kill_house.name)
        if steward_allocation.kill_house:
            seller = steward_allocation.kill_house.name

        elif steward_allocation.to_cold_house:
            seller = steward_allocation.to_cold_house.kill_house.name

        elif steward_allocation.steward:
            seller = steward_allocation.steward.user.fullname
        else:
            seller = steward_allocation.guilds.user.fullname
        if steward_allocation.interface_number:
            mobile = steward_allocation.interface_number
        else:
            if steward_allocation.to_steward:
                mobile = steward_allocation.to_steward.user.mobile

            elif steward_allocation.to_guilds:
                mobile = steward_allocation.to_guilds.user.mobile
            elif steward_allocation.to_cold_house:
                if steward_allocation.to_cold_house.kill_house:
                    mobile = steward_allocation.to_cold_house.kill_house.kill_house_operator.user.mobile
                else:
                    mobile = steward_allocation.to_cold_house.live_stock_support.user.mobile

                mobile = steward_allocation.to_guilds.user.mobile
            else:
                mobile = steward_allocation.to_kill_house.kill_house_operator.user.mobile

        steward_allocation_sms(mobile, date, weight, seller, number, buyer, steward_allocation.amount)


def first_auto_steward_allocation(kill_house_key, quantity, weight, date):
    kill_house = KillHouse.objects.get(key=kill_house_key, trash=False)
    ware_house = KillHouseWareHouse.objects.get(kill_house=kill_house, date__date=date.date())
    stewards = Steward.objects.filter(guilds__steward=True, trash=False).order_by('id')
    stewards_list = []
    allocatated_quantity = 0
    kill_house_total_quantity = 0
    for steward in stewards:
        if steward.centers_allocation != None:
            for center_allocation in steward.centers_allocation:
                if str(kill_house.key) == center_allocation['value']:
                    kill_house_total_quantity += steward.allocation_limit
                    stewards_list.append(steward)
    if len(stewards_list) > 0:
        for steward_list in stewards_list:
            allocatated_quantity = (steward_list.allocation_limit / kill_house_total_quantity) * quantity
            auto_allocation = StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                               kill_house=kill_house, type='auto', trash=False,
                                                               date__date=date.date()).first()

            if auto_allocation:
                if StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                    kill_house=kill_house, type='manual', trash=False,
                                                    date__date=date.date()).exists():

                    # auto_allocation.delete()
                    auto_allocation.trash = True
                    auto_allocation.save()
                else:
                    auto_allocation.number_of_carcasses = allocatated_quantity
                    auto_allocation.real_number_of_carcasses = allocatated_quantity
                    auto_allocation.weight_of_carcasses = int(allocatated_quantity * (weight / quantity))
                    auto_allocation.real_weight_of_carcasses = int(allocatated_quantity * (weight / quantity))
                    auto_allocation.save()
            else:
                if not StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                        kill_house=kill_house, type='manual', trash=False,
                                                        date__date=date.date()).exists():
                    auto_allocation = StewardAllocation(
                        kill_house=kill_house,
                        ware_house=ware_house,
                        steward=steward_list,
                        number_of_carcasses=allocatated_quantity,
                        real_number_of_carcasses=allocatated_quantity,
                        weight_of_carcasses=int(allocatated_quantity * (weight / quantity)),
                        real_weight_of_carcasses=int(allocatated_quantity * (weight / quantity)),
                        type='auto',
                        date=date
                    )
                    auto_allocation.save()


class StewardFreeBarInformationViewSet(viewsets.ModelViewSet):
    queryset = StewardFreeBarInformation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardFreeBarInformationSerializer
    pagination_class = CustomPagination
    filterset_class = StewardFreeBarInformationFilterSet
    filterset_fields = [
        'kill_house_name',
        'kill_house_mobile',
        'province',
        'city',
        'driver_name',
        'driver_mobile',
        'pelak',
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'steward__guilds_name',

    ]

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(user=user, active=True, trash=False)
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        request.data.pop('product_key')
        dispenser = request.data.pop('dispenser',None)
        representative = request.data.pop('representative',None)
        try:
            image = request.data['bar_image']
            request.data.pop('bar_image')
        except:
            image = None
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            steward_free_bar_info = serializer.create(validated_data=request.data)
            if image != None:
                steward_free_bar_info.bar_image = send_image_to_server(image)
            steward_free_bar_info.steward = steward
            steward_free_bar_info.product = product
            steward_free_bar_info.dispenser = dispenser if dispenser else None
            steward_free_bar_info.representative = representative if representative else None
            steward_free_bar_info.save()
            guild_steward_free_buying_product_warehousing(product)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        guild = Guilds.objects.get(user=user, active=True, trash=False)
        if date1:
            bars = StewardFreeBarInformation.objects.filter(Q(steward=guild) | Q(guild=guild),
                                                            date__date__gte=date1,
                                                            date__date__lte=date2,
                                                            trash=False).order_by('-date')
        else:
            bars = StewardFreeBarInformation.objects.filter(Q(steward=guild) | Q(guild=guild),
                                                            trash=False).order_by('-date')

        if 'search' in request.GET and 'value' in request.GET:
            bars_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=bars
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=bars)
                            bars_list = ps.filter()
                    bars = [] if len(bars_list) == 0 else bars_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(bars)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(bars, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        free_bar = StewardFreeBarInformation.objects.get(key=request.data['key'])
        if 'bar_image' in request.data.keys():
            if request.data['bar_image'] != "" or request.data['bar_image'] != " ":
                image = request.data['bar_image']
                free_bar.bar_image = send_image_to_server(image)
                free_bar.save()
            request.data.pop('bar_image')

        serializer = self.serializer_class(free_bar)
        serializer.update(instance=free_bar, validated_data=request.data)
        guild_steward_free_buying_product_warehousing(free_bar.product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        free_bar = StewardFreeBarInformation.objects.get(key=request.GET['key'])
        free_bar.trash = True
        free_bar.save()
        guild_steward_free_buying_product_warehousing(free_bar.product)

        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class StewardFreeBarInformationDashboardViewSet(viewsets.ModelViewSet):
    queryset = StewardFreeBarInformation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardFreeBarInformationSerializer
    filterset_class = StewardFreeBarInformationFilterSet
    filterset_fields = [
        'kill_house_name',
        'kill_house_mobile',
        'province',
        'city',
        'driver_name',
        'driver_mobile',
        'pelak',
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'steward__guilds_name',

    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        guild = Guilds.objects.get(user=user, active=True, trash=False)
        product = RolesProducts.objects.get(guild=guild, trash=False)
        if date1:
            bars = StewardFreeBarInformation.objects.filter(Q(steward=guild) | Q(guild=guild),
                                                            date__date__gte=date1,
                                                            date__date__lte=date2,
                                                            trash=False).order_by('-date')
        else:
            bars = StewardFreeBarInformation.objects.filter(Q(steward=guild) | Q(guild=guild),
                                                            trash=False).order_by('-date')

        if 'search' in request.GET and 'value' in request.GET:
            bars_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=bars
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=bars)
                            bars_list = ps.filter()
                    bars = [] if len(bars_list) == 0 else bars_list
        total_quantity = bars.aggregate(total=Sum('number_of_carcasses'))['total']
        total_weight = bars.aggregate(total=Sum('weight_of_carcasses'))['total']
        result = {
            "product": product.key,
            "total_bars": len(bars),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
        }

        return Response(result, status=status.HTTP_200_OK)


class PosStewardFreeBarInformationViewSet(viewsets.ModelViewSet):
    queryset = StewardFreeBarInformation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosStewardFreeBarInformationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = StewardFreeBarInformationFilterSet
    filterset_fields = [
        'kill_house_name',
        'kill_house_mobile',
        'province',
        'city',
        'driver_name',
        'driver_mobile',
        'pelak',
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'steward__guilds_name',

    ]

    def create(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        steward = Guilds.objects.get(id=pos.guild.id, trash=False)
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        request.data.pop('product_key')
        try:
            image = request.data['bar_image']
            request.data.pop('bar_image')
        except:
            image = None
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            steward_free_bar_info = serializer.create(validated_data=request.data)
            if image != None:
                steward_free_bar_info.bar_image = send_image_to_server(image)
            steward_free_bar_info.steward = steward
            steward_free_bar_info.product = product
            steward_free_bar_info.date = datetime.now()
            steward_free_bar_info.save()
            guild_steward_free_buying_product_warehousing(product)
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        bars = StewardFreeBarInformation.objects.filter(Q(steward=pos.guild) | Q(guild=pos.guild),
                                                        date__date__gte=date1,
                                                        date__date__lte=date2,
                                                        trash=False)

        if 'search' in request.GET and 'value' in request.GET:
            bars_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=bars
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=bars)
                            bars_list = ps.filter()
                    bars = [] if len(bars_list) == 0 else bars_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(bars)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(bars, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        bar = StewardFreeBarInformation.objects.get(key=request.data['key'])
        if 'bar_image' in request.data.keys():
            if request.data['bar_image'] != "" or request.data['bar_image'] != " ":
                image = request.data['bar_image']
                bar.bar_image = send_image_to_server(image)
                bar.save()
            request.data.pop('bar_image')

        serializer = self.serializer_class(bar)
        serializer.update(instance=bar, validated_data=request.data)
        guild_steward_free_buying_product_warehousing(bar.product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        free_bar = StewardFreeBarInformation.objects.get(key=request.GET['key'])
        free_bar.trash = True
        free_bar.save()
        guild_steward_free_buying_product_warehousing(free_bar.product)

        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class StewardFreeSaleBarInformationViewSet(viewsets.ModelViewSet):
    queryset = StewardFreeSaleBarInformation.objects.all()
    serializer_class = StewardFreeSaleBarInformationSerializer
    permission_classes = [TokenHasReadWriteScope]
    pagination_class = CustomPagination
    filterset_class = StewardFreeSaleBarInformationFilterSet
    filterset_fields = [
        'steward__user__fullname',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__mobile',
        'buyer__user__fullname',
        'buyer__user__first_name',
        'buyer__user__last_name',
        'buyer__user__mobile',
        'province',
        'city',
        'province'
        'buyer_name'
        'buyer_mobile'

    ]

    def create(self, request, *args, **kwargs):
        now_time = datetime.now().time()
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(user=user, active=True, trash=False)
        product = RolesProducts.objects.get(key=request.data.pop('product_key', None), trash=False)
        buyer = OutProvinceCarcassesBuyer.objects.get(key=request.data.pop('buyer_key', None), trash=False)
        date = datetime.strptime(str(request.data['date']), '%Y-%m-%d').date()
        production_date = datetime.strptime(str(request.data['production_date']), '%Y-%m-%d').date()
        dispenser = request.data.pop('dispenser',None)
        representative = request.data.pop('representative',None)
        date = datetime(year=date.year, month=date.month, day=date.day, hour=now_time.hour,
                        minute=now_time.minute,
                        second=now_time.second)
        production_date = datetime(year=production_date.year, month=production_date.month, day=production_date.day,
                                   hour=now_time.hour,
                                   minute=now_time.minute,
                                   second=now_time.second)
        carcass_distribution = RestrictionCarcassDistribution.objects.filter(trash=False,
                                                                             distribution_type='Steward',
                                                                             allow=True,
                                                                             out=True).first()
        if carcass_distribution and datetime.now().time() > carcass_distribution.time:
            return Response({"result": "لطفا در ساعات مجاز اقدام نمایید!"},
                            status=status.HTTP_403_FORBIDDEN)
        request.data.pop('date')
        request.data.pop('production_date')
        quota = request.data['quota']
        if request.data['sale_type'] == 'free':
            quota = request.data['quota']
            if quota == 'governmental':
                if not steward.free_sale_form_governmental_quota:
                    return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        if quota == 'governmental':
            if steward.total_input_warehouse_governmental_weight < (
                    steward.total_selling_warehouse_governmental_weight + request.data['weight_of_carcasses']):
                return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                status=status.HTTP_403_FORBIDDEN)
        else:
            if steward.total_input_warehouse_free_weight < (
                    steward.total_selling_warehouse_free_weight + request.data['weight_of_carcasses']):
                return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                status=status.HTTP_403_FORBIDDEN)

        if quota == 'governmental':
            free_sale_type = request.data['sale_type']
            if steward.governmental_selling_permission:
                if free_sale_type == 'free':
                    if not steward.free_sale_form_governmental_quota:
                        if steward.total_commitment_selling_in_province_governmental_weight > steward.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                else:
                    if steward.total_commitment_selling_in_province_governmental_weight > steward.total_selling_in_province_governmental_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
            else:
                return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
            if steward.total_commitment_selling_out_province_governmental_weight > 0:
                if steward.total_selling_out_province_governmental_weight + request.data[
                    'weight_of_carcasses'] > steward.total_commitment_selling_out_province_governmental_weight:
                    return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        else:
            if steward.free_selling_permission:
                if steward.total_commitment_selling_in_province_free_weight > steward.total_selling_in_province_free_weight:
                    return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

            if steward.total_commitment_selling_out_province_free_weight > 0:
                if steward.total_selling_out_province_free_weight + request.data[
                    'weight_of_carcasses'] > steward.total_commitment_selling_out_province_free_weight:
                    return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
        if product.total_remain_weight < request.data['weight_of_carcasses']:
            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار است!"}, status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            steward_free_sale_bar_info = serializer.create(validated_data=request.data)
            steward_free_sale_bar_info.steward = steward
            steward_free_sale_bar_info.buyer = buyer
            steward_free_sale_bar_info.buyer_name = buyer.fullname
            steward_free_sale_bar_info.buyer_mobile = buyer.mobile
            steward_free_sale_bar_info.city = buyer.city
            steward_free_sale_bar_info.province = buyer.province
            steward_free_sale_bar_info.date = date
            steward_free_sale_bar_info.production_date = production_date
            steward_free_sale_bar_info.product = product
            steward_free_sale_bar_info.dispenser = dispenser if dispenser else None
            steward_free_sale_bar_info.representative = representative if representative else None
            steward_free_sale_bar_info.save()
            allow_register_code = AllowRegisterCodeForStewardFreeSaleBarInformation.objects.filter(trash=False,
                                                                                                   active=True).first()
            if allow_register_code:
                number = random.randint(10000, 99000)
                steward_free_sale_bar_info.registration_code = number
                steward_free_sale_bar_info.system_registration_code = True
                if int(allow_register_code.time) > 0:
                    steward_free_sale_bar_info.active_expire_date_time = True
                    steward_free_sale_bar_info.expire_date_time_registration_code = datetime.now() + timedelta(
                        minutes=int(allow_register_code.time))
                steward_free_sale_bar_info.save()
                send_sms_for_sale_bar_for_steward(steward_free_sale_bar_info)
            guild_steward_free_sale_product_warehousing(product)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        filters = {'trash': False}
        role = request.GET.get('role')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        steward_key = request.GET.get('steward_key')

        if role == 'Steward':
            steward = Guilds.objects.get(user=user, active=True, trash=False)
            filters['steward'] = steward
        elif role in ['CityJahad']:
            filters['steward__user__city'] = user.city

        if date1:
            date1 = datetime.strptime(str(date1), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(date2), '%Y-%m-%d').date()
            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2

        if steward_key and steward_key != 'all':
            filters['steward__key'] = steward_key

        bars = StewardFreeSaleBarInformation.objects.filter(**filters).order_by('-date')

        if 'search' in request.GET and 'value' in request.GET:
            bars_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=bars
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=bars)
                            bars_list = ps.filter()
                    bars = [] if len(bars_list) == 0 else bars_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(bars)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(bars, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        free_sale_bar = StewardFreeSaleBarInformation.objects.get(key=request.data['key'])
        allow_register_code = AllowRegisterCodeForStewardFreeSaleBarInformation.objects.filter(trash=False,
                                                                                               active=True).first()
        if allow_register_code:
            if 'register_code' in request.data.keys():
                code = request.data['register_code']
                if code != free_sale_bar.registration_code:
                    return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                free_sale_bar.logged_registration_code = code
            free_sale_bar.save()
            request.data.pop('register_code')
        if free_sale_bar.quota == 'governmental':
            if free_sale_bar.steward.total_input_warehouse_governmental_weight < (
                    (
                            free_sale_bar.steward.total_selling_warehouse_governmental_weight - free_sale_bar.weight_of_carcasses) +
                    request.data[
                        'weight_of_carcasses']):
                return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                status=status.HTTP_403_FORBIDDEN)
        else:
            if free_sale_bar.steward.total_input_warehouse_free_weight < (
                    (free_sale_bar.steward.total_selling_warehouse_free_weight - free_sale_bar.weight_of_carcasses) +
                    request.data[
                        'weight_of_carcasses']):
                return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                status=status.HTTP_403_FORBIDDEN)

        if free_sale_bar.product.total_remain_weight + free_sale_bar.weight_of_carcasses < request.data[
            'weight_of_carcasses']:
            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار است!"}, status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(free_sale_bar)
        serializer.update(instance=free_sale_bar, validated_data=request.data)

        guild_steward_free_sale_product_warehousing(free_sale_bar.product)

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

    def destroy(self, request, pk=None, *args, **kwargs):
        free_sale_bar = StewardFreeSaleBarInformation.objects.get(key=request.GET['key'])
        free_sale_bar.trash = True
        free_sale_bar.save()
        guild_steward_free_sale_product_warehousing(free_sale_bar.product)
        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class StewardFreeSaleBarInformationDashboardViewSet(viewsets.ModelViewSet):
    queryset = StewardFreeSaleBarInformation.objects.all()
    serializer_class = StewardFreeSaleBarInformationSerializer
    permission_classes = [TokenHasReadWriteScope]
    pagination_class = CustomPagination
    filterset_class = StewardFreeSaleBarInformationFilterSet
    filterset_fields = [
        'steward__user__fullname',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__mobile',
        'buyer__user__fullname',
        'buyer__user__first_name',
        'buyer__user__last_name',
        'buyer__user__mobile',
        'province',
        'city',
        'province'
        'buyer_name'
        'buyer_mobile'

    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        filters = {'trash': False}
        role = request.GET.get('role')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        steward_key = request.GET.get('steward_key')

        if role == 'Steward':
            steward = Guilds.objects.get(user=user, active=True, trash=False)
            filters['steward'] = steward

        elif role in ['CityJahad']:
            filters['steward__user__city'] = user.city

        if date1:
            date1 = datetime.strptime(str(date1), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(date2), '%Y-%m-%d').date()
            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2
        if steward_key and steward_key != 'all':
            filters['steward__key'] = steward_key

        bars = StewardFreeSaleBarInformation.objects.filter(**filters)
        if 'search' in request.GET and 'value' in request.GET:
            bars_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=bars
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=bars)
                            bars_list = ps.filter()
                    bars = [] if len(bars_list) == 0 else bars_list
        buyers = len(bars.values_list('buyer', flat=True).distinct())

        result = {
            "number_of_bars": len(bars),
            "number_of_buyers": buyers,
            "bars_quantity":
                bars.aggregate(total=Sum('number_of_carcasses'))['total'] or 0,
            "bars_weight":
                bars.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0,

        }

        return Response(result, status=status.HTTP_200_OK)


class FirstAutomaticStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AutomaticStewardAllocationSerializer

    def create(self, request, *args, **kwargs):
        input_date = datetime.strptime(str(request.data['date']), '%Y-%m-%d').date()
        one_day_ago = input_date - timedelta(days=1)
        # if date_of_now == now:
        kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
        kill_house_requests = KillHouseRequest.objects.filter(killhouse_user=kill_house,
                                                              province_kill_request__kill_request__recive_date__date=one_day_ago,
                                                              trash=False).annotate(
            total_quantity=Sum('accepted_real_quantity'),
            total_weight=Sum('accepted_real_weight'))

        total_requests_quantity = kill_house_requests.aggregate(total=Sum('total_quantity'))['total']
        total_requests_weight = kill_house_requests.aggregate(total=Sum('total_weight'))['total']

        if len(kill_house_requests) == 0:
            return Response({"result": "به تاریخ امروز برای شما باری وجود ندارد!"},
                            status=status.HTTP_400_BAD_REQUEST)

        date = datetime.now().date()
        # date = kill_house_requests.last().create_date + timedelta(days=1)

        ware_house = KillHouseWareHouse.objects.get(kill_house=kill_house, date__date=input_date)
        stewards = Steward.objects.filter(guilds__steward=True, trash=False).order_by('id')
        stewards_list = []
        allocatated_weight = 0
        kill_house_total_weight = 0
        for steward in stewards:
            if steward.centers_allocation != None:
                for center_allocation in steward.centers_allocation:
                    if str(kill_house.key) == center_allocation['value']:
                        kill_house_total_weight += steward.allocation_limit
                        stewards_list.append(steward)
        if len(stewards_list) > 0:
            for steward_list in stewards_list:
                allocatated_weight = int(
                    (steward_list.allocation_limit / kill_house_total_weight) * total_requests_weight)

                auto_allocation = StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                                   kill_house=kill_house, type='auto', trash=False,
                                                                   date__date=input_date).first()

                if auto_allocation:
                    if StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                        kill_house=kill_house, type='manual', trash=False,
                                                        date__date=input_date).exists():

                        # auto_allocation.delete()
                        auto_allocation.trash = True
                        auto_allocation.save()
                    else:

                        auto_allocation.number_of_carcasses = int(allocatated_weight / (
                                ware_house.final_total_weight_of_carcasses / ware_house.final_total_number_of_carcasses))
                        auto_allocation.real_number_of_carcasses = int(allocatated_weight / (
                                ware_house.final_total_weight_of_carcasses / ware_house.final_total_number_of_carcasses))
                        auto_allocation.weight_of_carcasses = allocatated_weight
                        auto_allocation.real_weight_of_carcasses = allocatated_weight
                        auto_allocation.save()
                else:
                    if not StewardAllocation.objects.filter(steward=steward_list, allocation_state='pending',
                                                            kill_house=kill_house, type='manual', trash=False,
                                                            date__date=input_date).exists():
                        steward_date = datetime(year=date.year, month=date.month, day=date.day, hour=10,
                                                minute=1, second=1)
                        auto_allocation = StewardAllocation(
                            kill_house=kill_house,
                            ware_house=ware_house,
                            steward=steward_list,
                            number_of_carcasses=int(allocatated_weight / (
                                    ware_house.final_total_weight_of_carcasses / ware_house.final_total_number_of_carcasses)),
                            real_number_of_carcasses=0,
                            weight_of_carcasses=allocatated_weight,
                            real_weight_of_carcasses=0,
                            type='auto',
                            sell_type='exclusive',
                            allocation_type='kill_house_broadcast',
                            seller_type='steward',
                            date=steward_date
                        )
                        auto_allocation.save()
                        steward_ware_house = StewardWareHouse.objects.filter(steward=steward_list,
                                                                             date__date=date).first()
                        if not steward_ware_house:
                            steward_ware_house = StewardWareHouse(steward=steward_list, date=steward_date)
                            steward_ware_house.save()

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


class AutomaticStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AutomaticStewardAllocationSerializer

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

        kill_house = KillHouse.objects.filter(key=request.GET['kill_house_key'])
        date = datetime.strptime(str(request.GET['date']), '%Y-%m-%d').date()

        auto_allocations = StewardAllocation.objects.filter(date__date=date, kill_house__in=kill_house,
                                                            type='auto', trash=False).order_by(
            '-real_number_of_carcasses')
        serializer = self.serializer_class(auto_allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)

        if 'confirm_information' in request.data.keys():
            auto_allocation = StewardAllocation.objects.get(key=request.data['steward_allocation_key'])
            request.data.pop('steward_allocation_key')
            request.data.pop('confirm_information')
            auto_allocation.state = 'accepted'
            auto_allocation.save()
            serializer = self.serializer_class(auto_allocation)
            serializer.update(instance=auto_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)


        elif 'send_registration_code' in request.data.keys():
            allocations_list = request.data['steward_allocation_list']
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list,
                                                                   trash=False)
            request.data.pop('steward_allocation_list')
            for steward_allocation in steward_allocations:
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.state = 'accepted'
                steward_allocation.system_registration_code = True
                # steward_allocation.final_registration = True
                steward_allocation.save()
                steward_ware_house = StewardWareHouse.objects.filter(steward=steward_allocation.steward,
                                                                     date__date=steward_allocation.date.date()).first()
                if not steward_ware_house:
                    steward_ware_house = StewardWareHouse(steward=steward_allocation.steward,
                                                          date=steward_allocation.date)
                    steward_ware_house.save()
                steward_ware_house.bar_quantity += 1
                steward_ware_house.number_of_carcasses += steward_allocation.real_number_of_carcasses
                steward_ware_house.weight_of_carcasses += steward_allocation.real_weight_of_carcasses
                steward_ware_house.save()

                ware_house = KillHouseWareHouse.objects.get(key=steward_allocation.ware_house.key)
                ware_house.allocated_total_number_of_carcasses += steward_allocation.real_number_of_carcasses
                ware_house.allocated_total_weight_of_carcasses += steward_allocation.real_weight_of_carcasses
                ware_house.save()

            sms_steward_allocations = threading.Thread(target=automatic_steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            auto_allocation = StewardAllocation.objects.get(key=request.data['steward_allocation_key'])

            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != auto_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            auto_allocation.role = {
                "role": request.data['role'],
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date_register": str(datetime.now())
            }
            request.data.pop('role')
            auto_allocation.final_registration = True
            auto_allocation.save()
            serializer = self.serializer_class(auto_allocation)
            serializer.update(instance=auto_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)


class StewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = StewardAllocationFilterSet
    filterset_fields = [
        'guilds__user__first_name',
        'guilds__user__last_name',
        'guilds__user__fullname',
        'guilds__user__mobile',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
        'to_guilds__user__first_name',
        'to_guilds__user__last_name',
        'to_guilds__user__fullname',
        'to_guilds__user__mobile',
        'to_steward__user__first_name',
        'to_steward__user__last_name',
        'to_steward__user__fullname',
        'to_steward__user__mobile',
        'to_kill_house__kill_house_operator__user__first_name',
        'to_kill_house__kill_house_operator__user__last_name',
        'to_kill_house__kill_house_operator__user__fullname',
        'to_kill_house__kill_house_operator__user__mobile',
        'to_kill_house__name',
    ]

    def create(self, request, *args, **kwargs):
        now = datetime.now()
        now_time = now.time()
        production_date = None
        dispenser = request.data.pop('dispenser',None)
        representative = request.data.pop('representative',None)
        date = datetime.strptime(str(request.data['date']), '%Y-%m-%d').date()

        date = datetime(year=date.year, month=date.month, day=date.day, hour=now_time.hour,
                        minute=now_time.minute,
                        second=now_time.second)
        if 'production_date' in request.data.keys():
            production_date = datetime.strptime(str(request.data['production_date']), '%Y-%m-%d').date()
            production_date = datetime(year=production_date.year, month=production_date.month, day=production_date.day,
                                       hour=now_time.hour,
                                       minute=now_time.minute,
                                       second=now_time.second)
            request.data.pop('production_date')
        request.data.pop('date')
        # if OperationLimitation.objects.all().first().kill_house_steward_guild_allocation_limitation == True:
        #     if now.date() != date:
        #         return Response({"result": "به علت مغایرت تاریخ امکان تخصیص وجود ندارد!"},
        #                         status=status.HTTP_403_FORBIDDEN)
        product = None
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        seller_type = request.data['seller_type']
        buyer_type = request.data['buyer_type']
        request.data.pop('buyer_type')
        if seller_type != 'ColdHouse':
            product = RolesProducts.objects.get(key=request.data['product_key'])
            request.data.pop('product_key')

        if seller_type == 'KillHouse':
            carcass_distribution = RestrictionCarcassDistribution.objects.filter(trash=False,
                                                                                 distribution_type='KillHouse',
                                                                                 allow=True, out=False).first()
            if carcass_distribution and datetime.now().time() > carcass_distribution.time:
                return Response({"result": "لطفا در ساعات مجاز اقدام نمایید!"},
                                status=status.HTTP_403_FORBIDDEN)

            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            quota = request.data['quota']
            if not quota:
                return Response({"result": "بدون انتخاب سهمیه مجاز به فروش نمیباشید!"},
                                status=status.HTTP_403_FORBIDDEN)

            if request.data['approved_price_status'] == False:
                if quota == 'governmental':
                    if not kill_house.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                if kill_house.total_input_warehouse_governmental_weight < (
                        kill_house.total_selling_warehouse_governmental_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if kill_house.total_commitment_selling_in_province_free_weight == 0 and not kill_house.free_sale_from_free_quota_in_province:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_input_warehouse_free_weight < (
                        kill_house.total_selling_warehouse_free_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        elif seller_type == 'Steward':
            carcass_distribution = RestrictionCarcassDistribution.objects.filter(trash=False,
                                                                                 distribution_type='Steward',
                                                                                 allow=True,
                                                                                 out=False).first()
            if carcass_distribution and datetime.now().time() > carcass_distribution.time:
                return Response({"result": "لطفا در ساعات مجاز اقدام نمایید!"},
                                status=status.HTTP_403_FORBIDDEN)

            steward = Guilds.objects.filter(user=user, steward=True, trash=False, active=True).first()
            quota = request.data['quota']
            if not quota:
                return Response({"result": "بدون انتخاب سهمیه مجاز به فروش نمیباشید!"},
                                status=status.HTTP_403_FORBIDDEN)

            if request.data['approved_price_status'] == False:
                if quota == 'governmental':
                    if not steward.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                if steward.total_input_warehouse_governmental_weight < (
                        steward.total_selling_warehouse_governmental_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if steward.total_commitment_selling_in_province_free_weight == 0 and not steward.free_sale_from_free_quota_in_province:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if steward.total_input_warehouse_free_weight < (
                        steward.total_selling_warehouse_free_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        elif seller_type == 'ColdHouse':
            to_cold_house = ColdHouse.objects.get(key=request.data['cold_house_key'], trash=False)
            request.data.pop('cold_house_key')
        else:
            guild = Guilds.objects.filter(user=user, trash=False).first()

        if buyer_type == 'Steward':
            to_steward = Guilds.objects.get(key=request.data['steward_key'], trash=False)
            request.data.pop('steward_key')
        elif buyer_type == 'Guild':
            to_guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')

        elif buyer_type == 'ColdHouse':
            if seller_type == 'ColdHouse':
                other_cold_house = ColdHouse.objects.get(key=request.data['other_cold_house_key'], trash=False)
                request.data.pop('other_cold_house_key')
            else:
                to_cold_house = ColdHouse.objects.get(key=request.data['cold_house_key'], trash=False)
                request.data.pop('cold_house_key')
        else:
            to_kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
            request.data.pop('kill_house_key')
        image = None
        if 'image' in request.data.keys():
            image = request.data['image']
            request.data.pop('image')

        if seller_type == 'KillHouse' and buyer_type == 'ColdHouse':
            quota = request.data['quota']
            kill_house_total_input_warehouse_governmental_weight = kill_house.total_input_warehouse_governmental_weight
            kill_house_total_input_warehouse_free_weight = kill_house.total_input_warehouse_free_weight
            if quota == 'governmental':
                kill_house_sale_type = request.data['approved_price_status']
                if kill_house.governmental_selling_permission:
                    if kill_house_sale_type:
                        if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if not kill_house.free_sale_form_governmental_quota:
                            if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if kill_house.total_commitment_cold_house_governmental_weight > 0:
                    if kill_house.total_cold_house_governmental_weight + request.data[
                        'weight_of_carcasses'] > kill_house.total_commitment_cold_house_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if kill_house.free_selling_permission:
                    if kill_house.total_commitment_selling_in_province_free_weight > kill_house.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_commitment_cold_house_free_weight > 0:
                    if kill_house.total_cold_house_free_weight + request.data[
                        'weight_of_carcasses'] > kill_house.total_commitment_cold_house_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            allocation = serializer.create(validated_data=request.data)
            allow = AllowRegisterCodeForStewardAllocation.objects.filter(trash=False, active=True).first()
            if allow:
                allocation.active_expire_date_time = True
            if image and image != "":
                allocation.image = send_image_to_server(image)
            allocation.date = date
            allocation.dispenser = dispenser if dispenser else None
            allocation.representative = representative if representative else None
            allocation.production_date = production_date if production_date else date
            allocation.real_number_of_carcasses = allocation.number_of_carcasses
            allocation.real_weight_of_carcasses = int(allocation.weight_of_carcasses)
            allocation.weight_of_carcasses = int(request.data['weight_of_carcasses'])
            allocation.product = product
            if seller_type == 'KillHouse':
                allocation.kill_house = kill_house

            elif seller_type == 'Steward':
                allocation.steward = steward

            elif seller_type == 'ColdHouse':
                allocation.to_cold_house = to_cold_house


            else:
                allocation.guilds = guild

            if buyer_type == 'Steward':
                allocation.to_steward = to_steward
            elif buyer_type == 'Guild':
                allocation.to_guilds = to_guild

            elif buyer_type == 'ColdHouse':
                if seller_type == 'ColdHouse':
                    allocation.other_cold_house = other_cold_house
                else:
                    allocation.to_cold_house = to_cold_house

            else:
                allocation.to_kill_house = to_kill_house

            allocation.save()

            if seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(product)
                if buyer_type == 'ColdHouse' and to_cold_house.kill_house:
                    allocation.receiver_state = 'accepted'
                    allocation.system_registration_code = True
                    allocation.registration_code = 0
                    allocation.save()
                    kill_house_cold_house_allocations(to_cold_house)

            elif seller_type == 'ColdHouse':
                cold_house_warehousing(to_cold_house)
                if buyer_type == 'ColdHouse':
                    allocation.receiver_state = 'accepted'
                    allocation.system_registration_code = True
                    allocation.registration_code = 0
                    allocation.save()
                    cold_house_warehousing(other_cold_house)


            else:
                guild_steward_allocations_product_warehousing(product)
            return Response({"result": "با موفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if 'steward' in request.data.keys() or 'guild' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
            steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']

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

        elif 'check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                receiver_real_weight_of_carcasses = int(request.data['receiver_real_weight_of_carcasses'])
                weight_loss_of_carcasses = 0
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                if 'weight_loss_of_carcasses' in request.data.keys():
                    weight_loss_of_carcasses = request.data['weight_loss_of_carcasses']
                    maximum_weight_limit = int(request.data['receiver_real_weight_of_carcasses']) * 0.07
                    if weight_loss_of_carcasses > maximum_weight_limit:
                        return Response({"result": "افت وزن وارد شده بیشتر از حد مجاز است!"},
                                        status=status.HTTP_403_FORBIDDEN)

                    receiver_real_weight_of_carcasses -= weight_loss_of_carcasses
                    steward_allocation.weight_loss_of_carcasses = weight_loss_of_carcasses

                steward_allocation.receiver_real_number_of_carcasses = receiver_real_number_of_carcasses
                steward_allocation.receiver_real_weight_of_carcasses = receiver_real_weight_of_carcasses
                steward_allocation.real_number_of_carcasses = receiver_real_number_of_carcasses
                steward_allocation.real_weight_of_carcasses = receiver_real_weight_of_carcasses
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()

                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'steward_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'guild_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'allocation_key' in request.data.keys() and 'logged_registration_code' not in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'], trash=False)
            if steward_allocation.receiver_state == 'accepted':
                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guildso, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)
                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)


                elif steward_allocation.to_kill_house:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)
                else:
                    buyer_product = None

                if buyer_product:
                    if buyer_product.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                            request.data[
                                'weight_of_carcasses']:
                        return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                        status=status.HTTP_403_FORBIDDEN)

                else:
                    if steward_allocation.to_cold_house:
                        if steward_allocation.other_cold_house:
                            if steward_allocation.other_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                                    request.data[
                                        'weight_of_carcasses']:
                                return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                                status=status.HTTP_403_FORBIDDEN)
                        else:
                            if steward_allocation.to_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                                    request.data[
                                        'weight_of_carcasses']:
                                return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                                status=status.HTTP_403_FORBIDDEN)
            if steward_allocation.product:
                if steward_allocation.product.kill_house:
                    if steward_allocation.quota == 'governmental':
                        if steward_allocation.product.kill_house.total_input_warehouse_governmental_weight < (
                                (
                                        steward_allocation.product.kill_house.total_selling_warehouse_governmental_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data[
                                    'weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if steward_allocation.product.kill_house.total_input_warehouse_free_weight < (
                                (
                                        steward_allocation.product.kill_house.total_selling_warehouse_free_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data['weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)

                else:
                    if steward_allocation.quota == 'governmental':
                        if steward_allocation.product.guild.total_input_warehouse_governmental_weight < (
                                (
                                        steward_allocation.product.guild.total_selling_warehouse_governmental_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data[
                                    'weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if steward_allocation.product.guild.total_input_warehouse_free_weight < (
                                (
                                        steward_allocation.product.guild.total_selling_warehouse_free_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data['weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)

                if steward_allocation.product.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                        request.data[
                            'weight_of_carcasses']:
                    return Response({"result": "وزن وارد شده بیشتر از موجودی انبار است!"},
                                    status=status.HTTP_403_FORBIDDEN)

            else:
                if steward_allocation.to_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                        request.data[
                            'weight_of_carcasses']:
                    return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                    status=status.HTTP_403_FORBIDDEN)

            if steward_allocation.to_cold_house:
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            else:

                steward_allocation.real_number_of_carcasses = request.data['number_of_carcasses']
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            steward_allocation.save()
            seller_product = steward_allocation.product
            if steward_allocation.seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(seller_product)
                if steward_allocation.to_cold_house and steward_allocation.to_cold_house.kill_house == steward_allocation.kill_house:
                    kill_house_cold_house_allocations(steward_allocation.to_cold_house)

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

            else:
                guild_steward_allocations_product_warehousing(seller_product)
            if 'image' in request.data.keys():
                image = request.data['image']
                request.data.pop('image')
                if image:
                    steward_allocation.image = send_image_to_server(image)
                    steward_allocation.save()
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'steward_allocation_list' in request.data.keys():
            allocations_list_temp = request.data['steward_allocation_list']
            allocations_list = []
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list_temp,
                                                                   trash=False)
            request.data.pop('steward_allocation_list')
            for steward_allocation in steward_allocations:
                if steward_allocation.system_registration_code == True:
                    continue
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.system_registration_code = True
                allocations_list.append(str(steward_allocation.key))
                steward_allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).select_related('ware_house__kill_house',
                                                                                              'ware_house__kill_house__kill_house_operator__user').last()
            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != steward_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            steward_allocation.role = {
                "role": request.data['role'],
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date_register": str(datetime.now())
            }
            if 'logged_registration_code' in request.data.keys():
                steward_allocation.state = 'accepted'
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.receiver_real_weight_of_carcasses = steward_allocation.real_weight_of_carcasses
                steward_allocation.receiver_real_number_of_carcasses = steward_allocation.real_number_of_carcasses
                steward_allocation.save()
                steward_guild = steward_allocation.to_guilds if steward_allocation.to_guilds else steward_allocation.to_steward
                if steward_guild:
                    buyer_product = RolesProducts.objects.get(guild=steward_guild, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)
                    guild_steward_allocations_product_warehousing(buyer_product)

            request.data.pop('role')
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allocations = []
        allocations_list = []
        now = datetime.now().date()
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        allocations_type = request.GET.get('type')
        if 'role' in request.GET:

            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                # cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)

                if 'date1' in request.GET:
                    date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                    date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
                    if 'cold_house' in request.GET:
                        cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)

                        if 'type' in request.GET:
                            if request.GET['type'] == 'input':
                                allocations = StewardAllocation.objects.filter(
                                    Q(to_cold_house=cold_house, kill_house__isnull=False) | Q(
                                        other_cold_house=cold_house,
                                        kill_house__isnull=True),
                                    trash=False, date__date__gte=date1,
                                    date__date__lte=date2).order_by('-id',
                                                                    '-date')
                            else:
                                allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                               kill_house__isnull=True,
                                                                               trash=False, date__date__gte=date1,
                                                                               date__date__lte=date2).order_by('-id',
                                                                                                               '-date')
                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(to_cold_house=cold_house) | Q(other_cold_house=cold_house),
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-id', '-date')

                    else:
                        allocations = StewardAllocation.objects.filter(
                            Q(kill_house=kill_house) | Q(to_kill_house=kill_house),
                            trash=False, date__date__gte=date1,
                            date__date__lte=date2).order_by('-id', '-date')
                else:
                    if 'cold_house' in request.GET:
                        cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)
                        if 'type' in request.GET:
                            if request.GET['type'] == 'input':
                                allocations = StewardAllocation.objects.filter(
                                    Q(to_cold_house=cold_house, kill_house__isnull=False) | Q(
                                        other_cold_house=cold_house,
                                        kill_house__isnull=True),
                                    trash=False).order_by('-id', '-date')

                            else:
                                allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                               kill_house__isnull=True,
                                                                               trash=False).order_by('-id', '-date')
                        else:

                            allocations = StewardAllocation.objects.filter(
                                Q(to_cold_house=cold_house) | Q(other_cold_house=cold_house),
                                trash=False).order_by('-id', '-date')

                    else:
                        allocations = StewardAllocation.objects.filter(
                            Q(kill_house=kill_house) | Q(to_kill_house=kill_house),
                            trash=False).order_by('id')

                # kill_house_ware_house = KillHouseWareHouse.objects.filter(kill_house=kill_house, date__date=date).last()
                # allocations = StewardAllocation.objects.filter(
                #     Q(type='manual') | Q(type='auto',
                #                          system_registration_code=True),
                #     kill_house=kill_house, trash=False,
                #     date__date=date).order_by('id')
            elif request.GET['role'] == 'Steward':
                guild = Guilds.objects.get(user=user, active=True, trash=False)
                if allocations_type:
                    if allocations_type == 'not_entered':
                        receiver_state = 'pending'
                    elif allocations_type == 'all':
                        receiver_state = ('pending', 'accepted')
                    else:
                        receiver_state = 'accepted'
                    if 'date1' in request.GET:
                        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

                        if allocations_type == 'all':
                            allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                           date__date__gte=date1, date__date__lte=date2,
                                                                           trash=False, system_registration_code=True,
                                                                           receiver_state__in=receiver_state
                                                                           ).order_by('-id', '-date')
                        else:

                            allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                           date__date__gte=date1, date__date__lte=date2,
                                                                           trash=False, system_registration_code=True,
                                                                           receiver_state=receiver_state
                                                                           ).order_by('-id', '-date')
                    else:

                        if allocations_type == 'all':
                            allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                           trash=False,
                                                                           system_registration_code=True,
                                                                           receiver_state__in=receiver_state
                                                                           ).order_by('-id', '-date')
                        else:
                            allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                           trash=False,
                                                                           system_registration_code=True,
                                                                           receiver_state=receiver_state
                                                                           ).order_by('-id', '-date')

                else:
                    if 'date1' in request.GET:
                        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

                        allocations = StewardAllocation.objects.filter(Q(steward=guild) | Q(guilds=guild),
                                                                       date__date__gte=date1, date__date__lte=date2,
                                                                       trash=False,
                                                                       ).order_by('-id', '-date')
                    else:

                        allocations = StewardAllocation.objects.filter(Q(steward=guild) | Q(guilds=guild),
                                                                       trash=False,
                                                                       ).order_by('-id', '-date')

        elif 'guild' in request.GET:
            guild = Guilds.objects.get(user=user, active=True, trash=False)
            allocations = StewardAllocation.objects.filter(
                Q(allocation_type='steward_broadcast') | Q(allocation_type='kill_house_broadcast'), guilds=guild,
                trash=False, system_registration_code=True).order_by('-date')

        elif 'steward_guilds_allocations' in request.GET:
            steward = Steward.objects.get(guilds__user=user, active=True, trash=False)
            steward_ware_house = StewardWareHouse.objects.get(date__date=date, steward=steward, trash=False)

            allocations = StewardAllocation.objects.filter(steward_ware_house__steward=steward, trash=False,
                                                           steward_ware_house=steward_ware_house,
                                                           date__date=date).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = StewardAllocationSerializer(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = StewardAllocation.objects.get(key=request.GET["steward_allocation_key"])
        if allocation.receiver_state == 'accepted':
            if allocation.to_steward:
                buyer_product = RolesProducts.objects.get(guild=allocation.to_steward, trash=False,
                                                          parent_product=allocation.product.parent_product)
            elif allocation.to_guilds:
                buyer_product = RolesProducts.objects.get(guild=allocation.to_guilds, trash=False,
                                                          parent_product=allocation.product.parent_product)


            elif allocation.to_kill_house:
                buyer_product = RolesProducts.objects.get(kill_house=allocation.to_kill_house, trash=False,
                                                          parent_product=allocation.product.parent_product)

            else:
                buyer_product = None

            if buyer_product:
                if buyer_product.total_remain_weight < allocation.real_weight_of_carcasses:
                    return Response({"result": "وزن حذف شده بیشتر از موجودی انبار خریدار است!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if allocation.to_cold_house:
                    if allocation.other_cold_house:
                        if allocation.other_cold_house.total_remain_weight < allocation.real_weight_of_carcasses:
                            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if allocation.to_cold_house.total_remain_weight < allocation.real_weight_of_carcasses:
                            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                            status=status.HTTP_403_FORBIDDEN)

        product = allocation.product
        seller_type = allocation.seller_type
        to_cold_house = allocation.to_cold_house
        other_cold_house = allocation.other_cold_house if allocation.other_cold_house else None
        allocation.delete()
        if seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(product)
            if to_cold_house and to_cold_house.kill_house == product.kill_house:
                kill_house_cold_house_allocations(to_cold_house)

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


        else:
            guild_steward_allocations_product_warehousing(product)
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class InProvinceAllocationDashboardViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = StewardAllocationDashboardFilterSet

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        role = request.GET.get('role')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        value = request.GET.get('value')
        search = request.GET.get('search')
        trash = request.GET.get('trash')
        return_trash = request.GET.get('return_trash')
        kill_house_key = request.GET.get('kill_house_key')
        steward_key = request.GET.get('steward_key')

        allocations_type = request.GET.get('type')
        filters = {
            'to_cold_house__isnull': True,
            'calculate_status': True,
        }
        if trash == 'true':
            filters['trash'] = True
            filters['active_expire_date_time'] = True
        else:
            filters['trash'] = False

        if return_trash == 'true':
            filters['return_trash'] = True

        if allocations_type == 'KillHouse':
            filters['kill_house__isnull'] = False
        # elif allocations_type == 'Steward':
        #     filters['steward__isnull'] = False

        if kill_house_key and kill_house_key != 'all':
            filters['kill_house__key'] = kill_house_key
        if steward_key and steward_key != 'all':
            filters['steward__key'] = steward_key

        if date1:
            filters['date__date__gte'] = datetime.strptime(str(date1), '%Y-%m-%d').date()
            filters['date__date__lte'] = datetime.strptime(str(date2), '%Y-%m-%d').date()

        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            filters['kill_house'] = kill_house
        elif role == 'Steward':
            steward = Guilds.objects.get(user=user, trash=False)
            filters['steward'] = steward
        elif role in ['CityJahad']:
            if allocations_type == 'KillHouse':
                filters['kill_house__kill_house_operator__user__city'] = user.city
            else:
                filters['steward__user__city'] = user.city
        if allocations_type == 'Steward':
                allocations = StewardAllocation.objects.filter(Q(steward__isnull=False)|Q(guilds__isnull=False),**filters)
        else:

                allocations = StewardAllocation.objects.filter(**filters)
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                allocations = allocations.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )
        allocations_aggregates = allocations.aggregate(
            total_count=Count('id', receiver_state__in=('pending', 'accepted')),
            total_weight=Sum('real_weight_of_carcasses', filter=Q(receiver_state__in=('pending', 'accepted'))),
            total_steward_weight=Sum('real_weight_of_carcasses',
                                     filter=Q(to_steward__isnull=False, receiver_state__in=('pending', 'accepted'))),
            total_guild_weight=Sum('real_weight_of_carcasses',
                                   filter=Q(to_guilds__isnull=False, receiver_state__in=('pending', 'accepted'))),
        )

        result = {
            "number_of_allocations": allocations_aggregates['total_count'] or 0,
            "total_weight": int(allocations_aggregates['total_weight'] or 0),
            "total_steward_weight": int(allocations_aggregates['total_steward_weight'] or 0),
            "total_guild_weight": int(allocations_aggregates['total_guild_weight'] or 0),
        }

        return Response(result, status=status.HTTP_200_OK)


class TotalStewardDashboardViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = StewardAllocationDashboardFilterSet

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        stewards_filter = {'trash': False, 'steward': True, 'active': True}
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if role in ['CityJahad']:
            stewards_filter['user__city'] = user.city
        stewards = Guilds.objects.filter(**stewards_filter).select_related('user').only('user', 'guilds_name',
                                                                                        'steward').order_by(
            'id')

        products = RolesProducts.objects.filter(guild__in=stewards, trash=False, name='مرغ گرم').first()

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

            allocation_stewards = stewards.annotate(
                allocation_count=Count(
                    'allocation_to_steward',
                    filter=Q(allocation_to_steward__receiver_state__in=['pending', 'accepted'],
                             allocation_to_steward__date__date__gte=date1, allocation_to_steward__date__date__lte=date2,
                             allocation_to_steward__warehouse=True, allocation_to_steward__steward_warehouse=True)
                )
            ).filter(allocation_count__gt=0).order_by('-allocation_count')

            free_bar_stewards = stewards.annotate(
                free_bar_count=Count(
                    'free_bar_info_steward'
                )
            ).filter(free_bar_count__gt=0).order_by('-free_bar_count')

            stewards = (list(chain(allocation_stewards, free_bar_stewards)))

            allocations = StewardAllocation.objects.filter(
                Q(steward__in=stewards) | Q(to_steward__in=stewards),
                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(steward__in=stewards, trash=False,
                                                                 date__date__gte=date1,
                                                                 date__date__lte=date2, warehouse=True)
            free_sale_bars = StewardFreeSaleBarInformation.objects.filter(steward__in=stewards, trash=False,
                                                                          date__date__gte=date1,
                                                                          date__date__lte=date2, warehouse=True)
            segmentations = PosSegmentation.objects.filter(guild__in=stewards, trash=False, warehouse=True,
                                                           date__date__gte=date1, date__date__lte=date2)
            transactions = ProductsTransactions.objects.filter(product=products, transaction__paid=True,
                                                               transaction__date__date__gte=date1,
                                                               transaction__date__date__lte=date2, trash=False,
                                                               warehouse=True)
            archives = WarehouseArchive.objects.filter(Q(steward__in=stewards) | Q(guild__in=stewards), trash=False,
                                                       date__date__gte=date1, date__lte=date2,
                                                       warehouse=True)


        else:
            allocation_stewards = stewards.annotate(
                allocation_count=Count(
                    'allocation_to_steward',
                    filter=Q(allocation_to_steward__receiver_state__in=['pending', 'accepted'],
                             allocation_to_steward__warehouse=True, allocation_to_steward__steward_warehouse=True)
                )
            ).filter(allocation_count__gt=0).order_by('-allocation_count').values_list('id', flat=True)

            free_bar_stewards = stewards.annotate(
                free_bar_count=Count(
                    'free_bar_info_steward'
                )
            ).filter(free_bar_count__gt=0).order_by('-free_bar_count').values_list('id', flat=True)

            stewards = (list(chain(allocation_stewards, free_bar_stewards)))

            allocations = StewardAllocation.objects.filter(
                Q(steward__in=stewards) | Q(to_steward__in=stewards),
                trash=False, calculate_status=True, to_cold_house__isnull=True, warehouse=True, steward_warehouse=True)

            free_bars = StewardFreeBarInformation.objects.filter(steward__in=stewards, trash=False, warehouse=True)
            free_sale_bars = StewardFreeSaleBarInformation.objects.filter(steward__in=stewards, trash=False,
                                                                          warehouse=True)
            segmentations = PosSegmentation.objects.filter(guild__in=stewards, trash=False, warehouse=True)
            transactions = ProductsTransactions.objects.filter(product=products, transaction__paid=True, trash=False,
                                                               warehouse=True)
            archives = WarehouseArchive.objects.filter(Q(steward__in=stewards) | Q(guild__in=stewards), trash=False,
                                                       warehouse=True)

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

            total_input_entered_governmental_bars_weight=Sum('real_weight_of_carcasses',
                                                             filter=Q(to_steward__isnull=False,
                                                                      receiver_state='accepted', quota='governmental')),

            total_input_entered_free_bars_weight=Sum('real_weight_of_carcasses',
                                                     filter=Q(to_steward__isnull=False, receiver_state='accepted',
                                                              quota='free')),

        )

        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', quota='governmental'),
            total_free_weight=Sum('weight_of_carcasses', 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

        total_in_province_governmental_input_weight = allocations_aggregates[
                                                          'total_input_entered_governmental_bars_weight'] or 0
        total_in_province_free_input_weight = allocations_aggregates['total_input_entered_free_bars_weight'] or 0
        total_free_buying_input_weight = free_bars_aggregates['total_weight'] or 0

        total_in_province_governmental_output_weight = allocations_aggregates[
                                                           'total_output_governmental_bars_weight'] or 0
        total_in_province_free_output_weight = allocations_aggregates['total_output_free_bars_weight'] or 0
        total_governmental_free_sale_weight = free_sale_bars_aggregates['total_governmental_weight'] or 0
        total_free_free_sale_weight = free_sale_bars_aggregates['total_free_weight'] 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

        total_governmental_input_weight = total_in_province_governmental_input_weight
        total_free_input_weight = total_in_province_free_input_weight + total_free_buying_input_weight
        total_input_weight = total_governmental_input_weight + total_free_input_weight

        total_governmental_output_weight = total_in_province_governmental_output_weight + total_governmental_free_sale_weight + segmentations_governmental_weight + int(
            pos_governmental_allocated_weight / 1000)
        total_free_output_weight = total_in_province_free_output_weight + total_free_free_sale_weight + segmentations_free_weight + int(
            pos_free_allocated_weight / 1000)
        total_output_weight = total_governmental_output_weight + total_free_output_weight

        total_governmental_remain_weight = (
                                                   total_governmental_input_weight - total_governmental_output_weight) - archives_governmental_weight if (
                                                                                                                                                                 (
                                                                                                                                                                         total_governmental_input_weight - total_governmental_output_weight) - archives_governmental_weight) > 0 else 0
        total_free_remain_weight = (total_free_input_weight - total_free_output_weight) - archives_free_weight if (
                                                                                                                          (
                                                                                                                                  total_free_input_weight - total_free_output_weight) - archives_free_weight) > 0 else 0
        total_remain_weight = total_governmental_remain_weight + total_free_remain_weight

        input_allocations_weight = allocations_aggregates['total_input_bars_weight'] or 0
        input_entered_allocations_weight = allocations_aggregates['total_input_entered_bars_weight'] or 0
        output_allocations_weight = allocations_aggregates['total_output_bars_weight'] or 0
        free_bars_weight = free_bars_aggregates['total_weight'] or 0
        free_sale_bars_weight = free_sale_bars_aggregates['total_weight'] or 0
        remain_weight = int(
            (input_entered_allocations_weight + free_bars_weight) - (
                    free_sale_bars_weight + output_allocations_weight + archives_weight))

        result = {
            "total_bars_weight": int(input_allocations_weight + free_bars_weight),
            "total_entered_bars_weight": int(input_entered_allocations_weight + free_bars_weight),
            "in_province_bars_weight": int(output_allocations_weight),
            "out_province_bars_weight": int(free_sale_bars_weight),
            "remain_weight": remain_weight,
            "total_governmental_input_weight": total_governmental_input_weight,
            "total_free_input_weight": total_free_input_weight,
            "total_input_weight": total_input_weight,
            "total_governmental_output_weight": total_governmental_output_weight,
            "total_free_output_weight": total_free_output_weight,
            "total_output_weight": total_output_weight,
            "total_governmental_remain_weight": total_governmental_remain_weight,
            "total_free_remain_weight": total_free_remain_weight,
            "total_remain_weight": total_remain_weight,
            "segmentations_weight": segmentations_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 Response(result, status=status.HTTP_200_OK)


class TotalStewardDashboarDetailViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RealGuildsForDashboardSerializer
    pagination_class = CustomPagination

    def list(self, request, *args, **kwargs):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        stewards_filter = {'trash': False, 'steward': True, 'active': True}
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if role in ['CityJahad']:
            stewards_filter['user__city'] = user.city

        stewards = Guilds.objects.filter(**stewards_filter).select_related('user').only('user', 'guilds_name',
                                                                                        'steward').order_by(
            'id')

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

            allocation_stewards = stewards.annotate(
                allocation_count=Count(
                    'allocation_to_steward',
                    filter=Q(allocation_to_steward__receiver_state__in=['pending', 'accepted'],
                             allocation_to_steward__date__date__gte=date1, allocation_to_steward__date__date__lte=date2,
                             allocation_to_steward__warehouse=True, allocation_to_steward__steward_warehouse=True)
                )
            ).filter(allocation_count__gt=0).order_by('-allocation_count')

            free_bar_stewards = stewards.annotate(
                free_bar_count=Count(
                    'free_bar_info_steward'
                )
            ).filter(free_bar_count__gt=0).order_by('-free_bar_count')

            stewards = list(set(chain(allocation_stewards, free_bar_stewards)))

        else:
            allocation_stewards = stewards.annotate(
                allocation_count=Count(
                    'allocation_to_steward',
                    filter=Q(allocation_to_steward__receiver_state__in=['pending', 'accepted'],
                             allocation_to_steward__warehouse=True, allocation_to_steward__steward_warehouse=True)
                )
            ).filter(allocation_count__gt=0).order_by('-allocation_count')

            free_bar_stewards = stewards.annotate(
                free_bar_count=Count(
                    'free_bar_info_steward'
                )
            ).filter(free_bar_count__gt=0).order_by('-free_bar_count')

            stewards = list(set(chain(allocation_stewards, free_bar_stewards)))
        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(stewards)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)


class InProvinceAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = InProvinceAllocationSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = StewardAllocationDashboardFilterSet

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        role = request.GET.get('role')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        value = request.GET.get('value')
        search = request.GET.get('search')
        kill_house_key = request.GET.get('kill_house_key')
        steward_key = request.GET.get('steward_key')
        allocations_type = request.GET.get('type')
        trash = request.GET.get('trash')
        return_trash = request.GET.get('return_trash')
        filters = {
            'to_cold_house__isnull': True,
            'calculate_status': True,
        }
        if trash == 'true':
            filters['trash'] = True
            filters['active_expire_date_time'] = True
        else:
            filters['trash'] = False

        if return_trash == 'true':
            filters['return_trash'] = True

        if allocations_type == 'KillHouse':
            filters['kill_house__isnull'] = False
        # elif allocations_type == 'Steward':
        #     filters['steward__isnull'] = False

        if kill_house_key and kill_house_key != 'all':
            filters['kill_house__key'] = kill_house_key
        if steward_key and steward_key != 'all':
            filters['steward__key'] = steward_key

        if date1:
            filters['date__date__gte'] = datetime.strptime(str(date1), '%Y-%m-%d').date()
            filters['date__date__lte'] = datetime.strptime(str(date2), '%Y-%m-%d').date()

        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            filters['kill_house'] = kill_house
        elif role == 'Steward':
            steward = Guilds.objects.get(user=user, trash=False)
            filters['steward'] = steward

        elif role in ['CityJahad']:
            if allocations_type == 'KillHouse':
                filters['kill_house__kill_house_operator__user__city'] = user.city
            else:
                filters['steward__user__city'] = user.city


        if allocations_type == 'Steward':
            allocations = StewardAllocation.objects.filter(Q(steward__isnull=False)|Q(guilds__isnull=False),**filters).order_by('-date')
        else:
            allocations = StewardAllocation.objects.filter(**filters).order_by('-date')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                allocations = allocations.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
            # return self.get_paginated_response(serializer.data)


class BatchStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = StewardAllocationFilterSet
    filterset_fields = [
        'guilds__user__first_name',
        'guilds__user__last_name',
        'guilds__user__fullname',
        'guilds__user__mobile',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
        'to_guilds__user__first_name',
        'to_guilds__user__last_name',
        'to_guilds__user__fullname',
        'to_guilds__user__mobile',
        'to_steward__user__first_name',
        'to_steward__user__last_name',
        'to_steward__user__fullname',
        'to_steward__user__mobile',
        'to_kill_house__kill_house_operator__user__first_name',
        'to_kill_house__kill_house_operator__user__last_name',
        'to_kill_house__kill_house_operator__user__fullname',
        'to_kill_house__kill_house_operator__user__mobile',
        'to_kill_house__name',
    ]

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

        # houre = datetime.now().time()
        # allocations_list = request.data['allocations_list']
        #
        # user = SystemUserProfile.objects.get(user=request.user, trash=False)
        #
        # main_seller_type = allocations_list[0]['seller_type']
        # product = RolesProducts.objects.get(key=allocations_list[0]['product_key'])
        #
        # if main_seller_type == 'KillHouse':
        #     kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
        # elif main_seller_type == 'Steward':
        #     steward = Guilds.objects.filter(user=user, steward=True, trash=False).first()
        # elif main_seller_type == 'ColdHouse':
        #     to_cold_house = ColdHouse.objects.get(key=allocations_list[0]['cold_house_key'], trash=False)
        # else:
        #     guild = Guilds.objects.filter(user=user, trash=False).first()
        #
        # allocation_instances = []
        #
        # for allocation_obj in allocations_list:
        #     date = datetime.strptime(str(allocation_obj['date']), '%Y-%m-%d').date()
        #     full_date = datetime(year=date.year, month=date.month, day=date.day,
        #                          hour=houre.hour, minute=houre.minute, second=houre.second)
        #     seller_type = allocation_obj['seller_type']
        #     buyer_type = allocation_obj['buyer_type']
        #
        #     if seller_type == 'KillHouse':
        #         kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
        #     elif seller_type == 'Steward':
        #         steward = Guilds.objects.filter(user=user, steward=True, trash=False).first()
        #     elif seller_type == 'ColdHouse':
        #         to_cold_house = ColdHouse.objects.get(key=allocation_obj['cold_house_key'], trash=False)
        #     else:
        #         guild = Guilds.objects.filter(user=user, trash=False).first()
        #
        #     if buyer_type == 'Steward':
        #         to_steward = Guilds.objects.get(key=allocation_obj['steward_key'], trash=False)
        #     elif buyer_type == 'Guild':
        #         to_guild = Guilds.objects.get(key=allocation_obj['guild_key'], trash=False)
        #     elif buyer_type == 'ColdHouse':
        #         to_cold_house = ColdHouse.objects.get(key=allocation_obj['cold_house_key'], trash=False)
        #     else:
        #         to_kill_house = KillHouse.objects.get(key=allocation_obj['kill_house_key'], trash=False)
        #
        #     allocation_obj.pop('date', None)
        #     allocation_obj.pop('product_key', None)
        #     allocation_obj.pop('steward_key', None)
        #     allocation_obj.pop('guild_key', None)
        #     allocation_obj.pop('kill_house_key', None)
        #     allocation_obj.pop('cold_house_key', None)
        #     image = None
        #     if 'image' in allocation_obj.keys() and allocation_obj['image']:
        #         image = allocation_obj['image']
        #         allocation_obj.pop('image', None)
        #     serializer = self.serializer_class(data=allocation_obj)
        #     serializer.is_valid(raise_exception=True)
        #     allocation = StewardAllocation(**serializer.validated_data)
        #     if image:
        #         ran = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
        #         upload_object_resize(image_data=image, bucket_name="profileimagedefault",
        #                              object_name="{0}.jpg".format(str(ran)))
        #
        #         allocation.image = ARVAN_Kill_house_URL + "{0}.jpg".format(str(ran))
        #
        #     allocation.date = full_date
        #     allocation.real_number_of_carcasses = allocation.number_of_carcasses
        #     allocation.real_weight_of_carcasses = int(allocation.weight_of_carcasses)
        #
        #     if seller_type == 'KillHouse':
        #         allocation.kill_house = kill_house
        #     elif seller_type == 'Steward':
        #         allocation.steward = steward
        #     elif seller_type == 'ColdHouse':
        #         allocation.to_cold_house = to_cold_house
        #     else:
        #         allocation.guilds = guild
        #
        #     if buyer_type == 'Steward':
        #         allocation.to_steward = to_steward
        #     elif buyer_type == 'Guild':
        #         allocation.to_guilds = to_guild
        #     elif buyer_type == 'ColdHouse':
        #         allocation.to_cold_house = to_cold_house
        #     else:
        #         allocation.to_kill_house = to_kill_house
        #
        #     if product:
        #         allocation.product = product
        #
        #     allocation_instances.append(allocation)
        #
        # StewardAllocation.objects.bulk_create(allocation_instances)
        #
        # if main_seller_type == 'KillHouse':
        #     kill_house_allocations_product_warehousing(product)
        # elif main_seller_type == 'ColdHouse':
        #     cold_house_warehousing(to_cold_house)
        # else:
        #     guild_steward_allocations_product_warehousing(product)

        # return Response({"result": "با موفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)
        return Response({"result": "امکان ثبت  بصورت موقت غیر فعال می باشد!"}, status=status.HTTP_201_CREATED)

        # houre = datetime.now().time()
        # allocations_list=request.data['allocations_list']
        # for allocation_obj in allocations_list:
        #     date = datetime.strptime(str(allocation_obj['date']), '%Y-%m-%d').date()
        #     date = datetime(year=date.year, month=date.month, day=date.day, hour=houre.hour,
        #                     minute=houre.minute,
        #                     second=houre.second)
        #     allocation_obj.pop('date')
        #     # if OperationLimitation.objects.all().first().kill_house_steward_guild_allocation_limitation == True:
        #     #     if now.date() != date:
        #     #         return Response({"result": "به علت مغایرت تاریخ امکان تخصیص وجود ندارد!"},
        #     #                         status=status.HTTP_403_FORBIDDEN)
        #     product = None
        #     user = SystemUserProfile.objects.get(user=request.user, trash=False)
        #     seller_type = allocation_obj['seller_type']
        #     buyer_type = allocation_obj['buyer_type']
        #     allocation_obj.pop('buyer_type')
        #     if seller_type != 'ColdHouse':
        #         product = RolesProducts.objects.get(key=allocation_obj['product_key'])
        #         allocation_obj.pop('product_key')
        #
        #     if seller_type == 'KillHouse':
        #         kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
        #
        #     elif seller_type == 'Steward':
        #         steward = Guilds.objects.filter(user=user, steward=True, trash=False).first()
        #
        #     elif seller_type == 'ColdHouse':
        #         to_cold_house = ColdHouse.objects.get(key=allocation_obj['cold_house_key'], trash=False)
        #         allocation_obj.pop('cold_house_key')
        #     else:
        #         guild = Guilds.objects.filter(user=user, trash=False).first()
        #
        #     if buyer_type == 'Steward':
        #         to_steward = Guilds.objects.get(key=allocation_obj['steward_key'], trash=False)
        #         allocation_obj.pop('steward_key')
        #     elif buyer_type == 'Guild':
        #         to_guild = Guilds.objects.get(key=allocation_obj['guild_key'], trash=False)
        #         allocation_obj.pop('guild_key')
        #
        #     elif buyer_type == 'ColdHouse':
        #         to_cold_house = ColdHouse.objects.get(key=allocation_obj['cold_house_key'], trash=False)
        #         allocation_obj.pop('cold_house_key')
        #     else:
        #         to_kill_house = KillHouse.objects.get(key=allocation_obj['kill_house_key'], trash=False)
        #         allocation_obj.pop('kill_house_key')
        #
        #     serializer = self.serializer_class(data=allocation_obj)
        #     if serializer.is_valid():
        #         allocation = serializer.create(validated_data=serializer.validated_data)
        #         allocation.date = date
        #         allocation.real_number_of_carcasses = allocation.number_of_carcasses
        #         allocation.real_weight_of_carcasses = int(allocation.weight_of_carcasses)
        #         allocation.weight_of_carcasses = int(allocation_obj['weight_of_carcasses'])
        #         allocation.product = product
        #         if seller_type == 'KillHouse':
        #             allocation.kill_house = kill_house
        #
        #         elif seller_type == 'Steward':
        #             allocation.steward = steward
        #
        #         elif seller_type == 'ColdHouse':
        #             allocation.to_cold_house = to_cold_house
        #
        #
        #         else:
        #             allocation.guilds = guild
        #
        #         if buyer_type == 'Steward':
        #             allocation.to_steward = to_steward
        #         elif buyer_type == 'Guild':
        #             allocation.to_guilds = to_guild
        #
        #         elif buyer_type == 'ColdHouse':
        #             allocation.to_cold_house = to_cold_house
        #
        #         else:
        #             allocation.to_kill_house = to_kill_house
        #
        #         allocation.save()
        #
        #         if seller_type == 'KillHouse':
        #             kill_house_allocations_product_warehousing(product)
        #             if buyer_type == 'ColdHouse' and to_cold_house.kill_house:
        #                 allocation.receiver_state = 'accepted'
        #                 allocation.system_registration_code = True
        #                 allocation.registration_code = 0
        #                 allocation.save()
        #                 kill_house_cold_house_allocations(to_cold_house)
        #
        #         elif seller_type == 'ColdHouse':
        #             cold_house_warehousing(to_cold_house)
        #
        #         else:
        #             guild_steward_allocations_product_warehousing(product)
        # return Response({"result": "با موفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)
        # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if 'steward' in request.data.keys() or 'guild' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
            steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']

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

        elif 'check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                receiver_real_weight_of_carcasses = int(request.data['receiver_real_weight_of_carcasses'])
                weight_loss_of_carcasses = 0
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                if 'weight_loss_of_carcasses' in request.data.keys():
                    weight_loss_of_carcasses = request.data['weight_loss_of_carcasses']
                    maximum_weight_limit = int(request.data['receiver_real_weight_of_carcasses']) * 0.07
                    if weight_loss_of_carcasses > maximum_weight_limit:
                        return Response({"result": "افت وزن وارد شده بیشتر از حد مجاز است!"},
                                        status=status.HTTP_403_FORBIDDEN)

                    receiver_real_weight_of_carcasses -= weight_loss_of_carcasses
                    steward_allocation.weight_loss_of_carcasses = weight_loss_of_carcasses

                steward_allocation.receiver_real_number_of_carcasses = receiver_real_number_of_carcasses
                steward_allocation.receiver_real_weight_of_carcasses = receiver_real_weight_of_carcasses
                steward_allocation.real_number_of_carcasses = receiver_real_number_of_carcasses
                steward_allocation.real_weight_of_carcasses = receiver_real_weight_of_carcasses
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()

                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'steward_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'guild_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'allocation_key' in request.data.keys() and 'logged_registration_code' not in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'], trash=False)
            if steward_allocation.to_cold_house:
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            else:

                steward_allocation.real_number_of_carcasses = request.data['number_of_carcasses']
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            steward_allocation.save()
            seller_product = steward_allocation.product
            if steward_allocation.seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(seller_product)
                if steward_allocation.to_cold_house and steward_allocation.to_cold_house.kill_house == steward_allocation.kill_house:
                    kill_house_cold_house_allocations(steward_allocation.to_cold_house)

            elif steward_allocation.seller_type == 'ColdHouse':
                cold_house_warehousing(steward_allocation.to_cold_house)

            else:
                guild_steward_allocations_product_warehousing(seller_product)
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'steward_allocation_list' in request.data.keys():
            allocations_list_temp = request.data['steward_allocation_list']
            allocations_list = []
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list_temp,
                                                                   trash=False)
            request.data.pop('steward_allocation_list')
            for steward_allocation in steward_allocations:
                if steward_allocation.system_registration_code == True:
                    continue
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.system_registration_code = True
                allocations_list.append(str(steward_allocation.key))
                steward_allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).select_related('ware_house__kill_house',
                                                                                              'ware_house__kill_house__kill_house_operator__user').last()
            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != steward_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            steward_allocation.role = {
                "role": request.data['role'],
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date_register": str(datetime.now())
            }
            if 'logged_registration_code' in request.data.keys():
                steward_allocation.state = 'accepted'
                steward_allocation.save()
            request.data.pop('role')
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allocations = []
        allocations_list = []
        now = datetime.now().date()
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        allocations_type = request.GET.get('type')

        if request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            # cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)

            if 'date1' in request.GET:
                date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
                if 'cold_house' in request.GET:
                    cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)

                    if 'type' in request.GET:
                        if request.GET['type'] == 'input':
                            allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                           kill_house__isnull=False,
                                                                           trash=False, date__date__gte=date1,
                                                                           date__date__lte=date2).order_by('-date')
                        else:
                            allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                           kill_house__isnull=True,
                                                                           trash=False, date__date__gte=date1,
                                                                           date__date__lte=date2).order_by('-date')
                    else:
                        allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                       trash=False, date__date__gte=date1,
                                                                       date__date__lte=date2).order_by('-date')

                else:
                    allocations = StewardAllocation.objects.filter(
                        Q(kill_house=kill_house) | Q(to_kill_house=kill_house),
                        trash=False, date__date__gte=date1,
                        date__date__lte=date2).order_by('id')
            else:
                if 'cold_house' in request.GET:
                    cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)
                    if 'type' in request.GET:
                        if request.GET['type'] == 'input':
                            allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                           kill_house__isnull=False,
                                                                           trash=False).order_by('-date')
                        else:
                            allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                           kill_house__isnull=True,
                                                                           trash=False).order_by('-date')
                    else:

                        allocations = StewardAllocation.objects.filter(to_cold_house=cold_house,
                                                                       trash=False).order_by('-date')

                else:
                    allocations = StewardAllocation.objects.filter(
                        Q(kill_house=kill_house) | Q(to_kill_house=kill_house),
                        trash=False).order_by('id')

            # kill_house_ware_house = KillHouseWareHouse.objects.filter(kill_house=kill_house, date__date=date).last()
            # allocations = StewardAllocation.objects.filter(
            #     Q(type='manual') | Q(type='auto',
            #                          system_registration_code=True),
            #     kill_house=kill_house, trash=False,
            #     date__date=date).order_by('id')
        elif request.GET['role'] == 'Steward':
            guild = Guilds.objects.get(user=user, trash=False)
            if allocations_type:
                receiver_state = 'pending' if allocations_type == 'not_entered' else 'accepted'
                if 'date1' in request.GET:
                    date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                    date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

                    allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                   date__date__gte=date1, date__date__lte=date2,
                                                                   trash=False, system_registration_code=True,
                                                                   receiver_state=receiver_state
                                                                   ).order_by('-date')
                else:

                    allocations = StewardAllocation.objects.filter(Q(to_steward=guild) | Q(to_guilds=guild),
                                                                   trash=False,
                                                                   system_registration_code=True,
                                                                   receiver_state=receiver_state
                                                                   ).order_by('-date')

            else:
                if 'date1' in request.GET:
                    date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

                    date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

                    allocations = StewardAllocation.objects.filter(Q(steward=guild) | Q(guilds=guild),
                                                                   date__date__gte=date1, date__date__lte=date2,
                                                                   trash=False,
                                                                   ).order_by('-date')
                else:

                    allocations = StewardAllocation.objects.filter(Q(steward=guild) | Q(guilds=guild),
                                                                   trash=False,
                                                                   ).order_by('-date')

        elif 'guild' in request.GET:
            guild = Guilds.objects.get(user=user, trash=False)
            allocations = StewardAllocation.objects.filter(
                Q(allocation_type='steward_broadcast') | Q(allocation_type='kill_house_broadcast'), guilds=guild,
                trash=False, system_registration_code=True).order_by('-date')

        elif 'steward_guilds_allocations' in request.GET:
            steward = Steward.objects.get(guilds__user=user, trash=False)
            steward_ware_house = StewardWareHouse.objects.get(date__date=date, steward=steward, trash=False)

            allocations = StewardAllocation.objects.filter(steward_ware_house__steward=steward, trash=False,
                                                           steward_ware_house=steward_ware_house,
                                                           date__date=date).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = StewardAllocationSerializer(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = StewardAllocation.objects.get(key=request.GET["steward_allocation_key"])
        product = allocation.product
        seller_type = allocation.seller_type
        to_cold_house = allocation.to_cold_house
        allocation.delete()
        if seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(product)
            if to_cold_house and to_cold_house.kill_house == product.kill_house:
                kill_house_cold_house_allocations(to_cold_house)

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


        else:
            guild_steward_allocations_product_warehousing(product)
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class PosStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosStewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = StewardAllocationFilterSet
    filterset_fields = [
        'guilds__user__first_name',
        'guilds__user__last_name',
        'guilds__user__fullname',
        'guilds__user__mobile',
        'guilds__guilds_name',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'steward__guilds_name',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
        'to_guilds__user__first_name',
        'to_guilds__user__last_name',
        'to_guilds__user__fullname',
        'to_guilds__user__mobile',
        'to_guilds__guilds_name',
        'to_steward__user__first_name',
        'to_steward__user__last_name',
        'to_steward__user__fullname',
        'to_steward__user__mobile',
        'to_steward__guilds_name',
        'to_kill_house__kill_house_operator__user__first_name',
        'to_kill_house__kill_house_operator__user__last_name',
        'to_kill_house__kill_house_operator__user__fullname',
        'to_kill_house__kill_house_operator__user__mobile',
        'to_kill_house__name',
    ]

    def create(self, request, *args, **kwargs):
        # validation_response = validate_headers(request)
        # if validation_response:
        #     return validation_response
        now = datetime.now()
        pos = POSMachine.objects.get(pos_id=request.data['pos-id'], trash=False)
        product = RolesProducts.objects.get(key=request.data['product_key'])
        seller_type = request.data['seller_type']
        buyer_type = request.data['buyer_type']
        request.data.pop('buyer_type')
        request.data.pop('product_key')
        request.data.pop('pos-id')

        if seller_type == 'KillHouse':
            kill_house = pos.kill_house

        elif seller_type == 'Steward':
            steward = pos.guild

        else:
            guild = pos.guild

        if buyer_type == 'Steward':
            to_steward = Guilds.objects.get(key=request.data['steward_key'], trash=False)
            request.data.pop('steward_key')
        elif buyer_type == 'Guild':
            to_guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')
        else:
            to_kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
            request.data.pop('kill_house_key')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            allocation = serializer.create(validated_data=request.data)
            allocation.date = now
            allocation.allocation_type = allocation.allocation_type.lower()
            allocation.real_number_of_carcasses = allocation.number_of_carcasses
            allocation.real_weight_of_carcasses = int(allocation.weight_of_carcasses)
            allocation.weight_of_carcasses = int(request.data['weight_of_carcasses'])
            # allocation.real_weight_of_carcasses = allocation.weight_of_carcasses
            allocation.product = product
            if seller_type == 'KillHouse':
                allocation.kill_house = kill_house

            elif seller_type == 'Steward':
                allocation.steward = steward

            else:
                allocation.guilds = guild

            if buyer_type == 'Steward':
                allocation.to_steward = to_steward
            elif buyer_type == 'Guild':
                allocation.to_guilds = to_guild
            else:
                allocation.to_kill_house = to_kill_house

            allocation.save()

            if seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(product)

            else:
                guild_steward_allocations_product_warehousing(product)

            allocations_list = []
            number = random.randint(10000, 99000)
            allocation.registration_code = number
            allocation.system_registration_code = True
            allocations_list.append(str(allocation.key))
            allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

            return Response({"result": "با موفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        if 'steward' in request.data.keys() or 'guild' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
            steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']

            steward_allocation.save()

            return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)
        elif 'check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = int(
                    request.data['receiver_real_weight_of_carcasses'])
                steward_allocation.real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.real_weight_of_carcasses = int(request.data['receiver_real_weight_of_carcasses'])
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()

                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'guild_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'allocation_key' in request.data.keys() and 'logged_registration_code' not in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'], trash=False)
            steward_allocation.real_number_of_carcasses = request.data['number_of_carcasses']
            steward_allocation.real_weight_of_carcasses = request.data['weight_of_carcasses']
            seller_product = steward_allocation.product
            if steward_allocation.seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(seller_product)
            else:
                guild_steward_allocations_product_warehousing(seller_product)
            steward_allocation.save()
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'allocation_list' in request.data.keys():
            allocations_list_temp = request.data['allocation_list']
            allocations_list = []
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list_temp,
                                                                   trash=False)
            request.data.pop('allocation_list')
            for steward_allocation in steward_allocations:
                if steward_allocation.system_registration_code == True:
                    continue
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.system_registration_code = True
                allocations_list.append(str(steward_allocation.key))
                steward_allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).select_related('ware_house__kill_house',
                                                                                              'ware_house__kill_house__kill_house_operator__user').last()
            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != steward_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            if 'logged_registration_code' in request.data.keys():
                steward_allocation.state = 'accepted'
                steward_allocation.save()
            request.data.pop('role')
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allocations = []
        allocations_list = []
        state = request.GET.get('state')
        type = request.GET.get('type')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)

        if pos.kill_house:
            if state and type:
                if type == 'output':
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                receiver_state=state,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                receiver_state=state,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                else:
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           trash=False, date__date__gte=date1,
                                                                           system_registration_code=True,
                                                                           date__date__lte=date2).order_by('-date',
                                                                                                           'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           receiver_state=state,
                                                                           trash=False, date__date__gte=date1,
                                                                           system_registration_code=True,
                                                                           date__date__lte=date2).order_by('-date',
                                                                                                           'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           trash=False,
                                                                           system_registration_code=True).order_by(
                                '-date', 'system_registration_code').exclude(to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           receiver_state=state,
                                                                           trash=False,
                                                                           system_registration_code=True).order_by(
                                '-date', 'system_registration_code').exclude(to_cold_house__isnull=False)

            else:
                allocations = StewardAllocation.objects.filter(
                    Q(to_kill_house=pos.kill_house) | Q(kill_house=pos.kill_house),
                    trash=False).order_by('-date', 'system_registration_code').exclude(to_cold_house__isnull=False)




        else:
            if state and type:

                if type == 'output':
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                receiver_state=state,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                receiver_state=state,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                else:
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                receiver_state=state,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False,
                                system_registration_code=True).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False,
                                receiver_state=state,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)


            else:
                allocations = StewardAllocation.objects.filter(
                    Q(to_steward=pos.guild) | Q(to_guilds=pos.guild) | Q(steward=pos.guild) | Q(guilds=pos.guild),
                    trash=False).order_by('-date', 'system_registration_code').exclude(to_cold_house__isnull=False)

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = PosStewardAllocationSerializer(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = StewardAllocation.objects.get(key=request.GET["allocation_key"])
        product = allocation.product
        seller_type = allocation.seller_type
        allocation.delete()
        if seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(product)

        else:
            guild_steward_allocations_product_warehousing(product)
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class NewPosStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosStewardAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = StewardAllocationFilterSet
    filterset_fields = [
        'guilds__user__first_name',
        'guilds__user__last_name',
        'guilds__user__fullname',
        'guilds__user__mobile',
        'guilds__guilds_name',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'steward__guilds_name',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
        'to_guilds__user__first_name',
        'to_guilds__user__last_name',
        'to_guilds__user__fullname',
        'to_guilds__user__mobile',
        'to_guilds__guilds_name',
        'to_steward__user__first_name',
        'to_steward__user__last_name',
        'to_steward__user__fullname',
        'to_steward__user__mobile',
        'to_steward__guilds_name',
        'to_kill_house__kill_house_operator__user__first_name',
        'to_kill_house__kill_house_operator__user__last_name',
        'to_kill_house__kill_house_operator__user__fullname',
        'to_kill_house__kill_house_operator__user__mobile',
        'to_kill_house__name',
    ]

    def create(self, request, *args, **kwargs):
        now = datetime.now()
        now_time = now.time()
        production_date = datetime.strptime(str(request.data['production_date']), '%Y-%m-%d').date()
        production_date = datetime(year=production_date.year, month=production_date.month, day=production_date.day,
                                   hour=now_time.hour,
                                   minute=now_time.minute,
                                   second=now_time.second)

        pos = POSMachine.objects.get(pos_id=request.data['pos-id'], trash=False)
        product = RolesProducts.objects.get(key=request.data['product_key'])
        seller_type = request.data['seller_type']
        buyer_type = request.data['buyer_type']
        request.data.pop('buyer_type')
        request.data.pop('product_key')
        request.data.pop('pos-id')
        request.data.pop('production_date')

        if seller_type == 'KillHouse':
            kill_house = pos.kill_house
            quota = request.data['quota']
            if request.data['approved_price_status'] == False:
                if quota == 'governmental':
                    if not kill_house.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                if kill_house.total_input_warehouse_governmental_weight < (
                        kill_house.total_selling_warehouse_governmental_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if kill_house.total_commitment_selling_in_province_free_weight == 0 and not kill_house.free_sale_from_free_quota_in_province:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_input_warehouse_free_weight < (
                        kill_house.total_selling_warehouse_free_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        elif seller_type == 'Steward':
            steward = pos.guild
            quota = request.data['quota']
            if request.data['approved_price_status'] == False:
                if quota == 'governmental':
                    if not steward.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                if steward.total_input_warehouse_governmental_weight < (
                        steward.total_selling_warehouse_governmental_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if steward.total_commitment_selling_in_province_free_weight == 0 and not steward.free_sale_from_free_quota_in_province:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if steward.total_input_warehouse_free_weight < (
                        steward.total_selling_warehouse_free_weight + request.data['weight_of_carcasses']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)

        else:
            guild = pos.guild

        if buyer_type == 'Steward':
            to_steward = Guilds.objects.get(key=request.data['steward_key'], trash=False)
            request.data.pop('steward_key')
        elif buyer_type == 'Guild':
            to_guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')
        else:
            to_kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
            request.data.pop('kill_house_key')

        if seller_type == 'KillHouse' and buyer_type == 'ColdHouse':
            kill_house = pos.kill_house
            quota = request.data['quota']
            if quota == 'governmental':
                kill_house_sale_type = request.data['approved_price_status']
                if kill_house.governmental_selling_permission:
                    if kill_house_sale_type:
                        if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if not kill_house.free_sale_form_governmental_quota:
                            if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if kill_house.total_commitment_cold_house_governmental_weight > 0:
                    if kill_house.total_cold_house_governmental_weight + request.data[
                        'weight_of_carcasses'] > kill_house.total_commitment_cold_house_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if kill_house.free_selling_permission:
                    if kill_house.total_commitment_selling_in_province_free_weight > kill_house.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_commitment_cold_house_free_weight > 0:
                    if kill_house.total_cold_house_free_weight + request.data[
                        'weight_of_carcasses'] > kill_house.total_commitment_cold_house_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            allocation = serializer.create(validated_data=request.data)
            allow = AllowRegisterCodeForStewardAllocation.objects.filter(trash=False, active=True).first()
            if allow:
                allocation.active_expire_date_time = True
            allocation.date = now
            allocation.production_date = production_date
            allocation.allocation_type = allocation.allocation_type.lower()
            allocation.real_number_of_carcasses = allocation.number_of_carcasses
            allocation.real_weight_of_carcasses = int(allocation.weight_of_carcasses)
            allocation.weight_of_carcasses = int(request.data['weight_of_carcasses'])
            # allocation.real_weight_of_carcasses = allocation.weight_of_carcasses
            allocation.product = product
            if seller_type == 'KillHouse':
                allocation.kill_house = kill_house

            elif seller_type == 'Steward':
                allocation.steward = steward

            else:
                allocation.guilds = guild

            if buyer_type == 'Steward':
                allocation.to_steward = to_steward
            elif buyer_type == 'Guild':
                allocation.to_guilds = to_guild
            else:
                allocation.to_kill_house = to_kill_house

            allocation.save()

            if seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(product)

            else:
                guild_steward_allocations_product_warehousing(product)

            allocations_list = []
            number = random.randint(10000, 99000)
            allocation.registration_code = number
            allocation.system_registration_code = True
            allocations_list.append(str(allocation.key))
            allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

            return Response({"result": "با موفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def update(self, request, pk=None, *args, **kwargs):
        if 'steward' in request.data.keys() or 'guild' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
            steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']

            steward_allocation.save()

            return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)
        elif 'check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            seller_product = steward_allocation.product

            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = int(
                    request.data['receiver_real_weight_of_carcasses'])
                steward_allocation.real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.real_weight_of_carcasses = int(request.data['receiver_real_weight_of_carcasses'])
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()

                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)

                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guilds,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        guild_steward_allocations_product_warehousing(buyer_product)
                else:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house,
                                                              parent_product=seller_product.parent_product)
                    if steward_allocation.seller_type == 'KillHouse':
                        kill_house_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
                    else:
                        guild_steward_allocations_product_warehousing(seller_product)
                        kill_house_allocations_product_warehousing(buyer_product)
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
                if steward_allocation.seller_type == 'KillHouse':
                    kill_house_allocations_product_warehousing(seller_product)
                else:
                    guild_steward_allocations_product_warehousing(seller_product)
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'guild_check_allocation' in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'],
                                                               trash=False)
            if request.data['state'] == 'accepted':
                if 'registration_code' in request.data.keys():
                    if request.data['registration_code'] != steward_allocation.registration_code:
                        return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)
                    steward_allocation.logged_registration_code = request.data['registration_code']
                steward_allocation.receiver_real_number_of_carcasses = request.data['receiver_real_number_of_carcasses']
                steward_allocation.receiver_real_weight_of_carcasses = request.data['receiver_real_weight_of_carcasses']
                steward_allocation.save()
                steward_allocation.receiver_state = 'accepted'
                steward_allocation.save()
            else:
                steward_allocation.receiver_state = 'rejected'
                steward_allocation.save()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

        elif 'allocation_key' in request.data.keys() and 'logged_registration_code' not in request.data.keys():
            steward_allocation = StewardAllocation.objects.get(key=request.data['allocation_key'], trash=False)
            if steward_allocation.receiver_state == 'accepted':
                if steward_allocation.to_steward:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_guildso, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)
                elif steward_allocation.to_guilds:
                    buyer_product = RolesProducts.objects.get(guild=steward_allocation.to_steward, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)


                elif steward_allocation.to_kill_house:
                    buyer_product = RolesProducts.objects.get(kill_house=steward_allocation.to_kill_house, trash=False,
                                                              parent_product=steward_allocation.product.parent_product)
                else:
                    buyer_product = None

                if buyer_product:
                    if buyer_product.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                            request.data[
                                'weight_of_carcasses']:
                        return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                        status=status.HTTP_403_FORBIDDEN)

                else:
                    if steward_allocation.to_cold_house:
                        if steward_allocation.other_cold_house:
                            if steward_allocation.other_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                                    request.data[
                                        'weight_of_carcasses']:
                                return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                                status=status.HTTP_403_FORBIDDEN)
                        else:
                            if steward_allocation.to_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                                    request.data[
                                        'weight_of_carcasses']:
                                return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                                status=status.HTTP_403_FORBIDDEN)
            if steward_allocation.product:
                if steward_allocation.product.kill_house:
                    if steward_allocation.quota == 'governmental':
                        if steward_allocation.product.kill_house.total_input_warehouse_governmental_weight < (
                                (
                                        steward_allocation.product.kill_house.total_selling_warehouse_governmental_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data[
                                    'weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if steward_allocation.product.kill_house.total_input_warehouse_free_weight < (
                                (
                                        steward_allocation.product.kill_house.total_selling_warehouse_free_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data['weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)

                else:
                    if steward_allocation.quota == 'governmental':
                        if steward_allocation.product.guild.total_input_warehouse_governmental_weight < (
                                (
                                        steward_allocation.product.guild.total_selling_warehouse_governmental_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data[
                                    'weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if steward_allocation.product.guild.total_input_warehouse_free_weight < (
                                (
                                        steward_allocation.product.guild.total_selling_warehouse_free_weight - steward_allocation.real_weight_of_carcasses) +
                                request.data['weight_of_carcasses']):
                            return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                            status=status.HTTP_403_FORBIDDEN)

                if steward_allocation.product.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                        request.data[
                            'weight_of_carcasses']:
                    return Response({"result": "وزن وارد شده بیشتر از موجودی انبار است!"},
                                    status=status.HTTP_403_FORBIDDEN)

            else:
                if steward_allocation.to_cold_house.total_remain_weight + steward_allocation.real_weight_of_carcasses < \
                        request.data[
                            'weight_of_carcasses']:
                    return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                    status=status.HTTP_403_FORBIDDEN)

            if steward_allocation.to_cold_house:
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            else:

                steward_allocation.real_number_of_carcasses = request.data['number_of_carcasses']
                steward_allocation.real_weight_of_carcasses = int(request.data['weight_of_carcasses'])
            steward_allocation.save()
            seller_product = steward_allocation.product
            if steward_allocation.seller_type == 'KillHouse':
                kill_house_allocations_product_warehousing(seller_product)
                if steward_allocation.to_cold_house and steward_allocation.to_cold_house.kill_house == steward_allocation.kill_house:
                    kill_house_cold_house_allocations(steward_allocation.to_cold_house)

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

            else:
                guild_steward_allocations_product_warehousing(seller_product)
            # steward_allocation.real_number_of_carcasses = request.data['number_of_carcasses']
            # steward_allocation.real_weight_of_carcasses = request.data['weight_of_carcasses']
            # seller_product = steward_allocation.product
            # if steward_allocation.seller_type == 'KillHouse':
            #     kill_house_allocations_product_warehousing(seller_product)
            # else:
            #     guild_steward_allocations_product_warehousing(seller_product)
            # steward_allocation.save()
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'allocation_list' in request.data.keys():
            allocations_list_temp = request.data['allocation_list']
            allocations_list = []
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list_temp,
                                                                   trash=False)
            request.data.pop('allocation_list')
            for steward_allocation in steward_allocations:
                if steward_allocation.system_registration_code == True:
                    continue
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.system_registration_code = True
                allocations_list.append(str(steward_allocation.key))
                steward_allocation.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).select_related('ware_house__kill_house',
                                                                                              'ware_house__kill_house__kill_house_operator__user').last()
            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != steward_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            if 'logged_registration_code' in request.data.keys():
                steward_allocation.state = 'accepted'
                steward_allocation.save()
            request.data.pop('role')
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allocations = []
        allocations_list = []
        state = request.GET.get('state')
        type = request.GET.get('type')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)

        if pos.kill_house:
            if state and type:
                if type == 'output':
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                receiver_state=state,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                kill_house=pos.kill_house,
                                receiver_state=state,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                else:
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           trash=False, date__date__gte=date1,
                                                                           system_registration_code=True,
                                                                           date__date__lte=date2).order_by('-date',
                                                                                                           'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           receiver_state=state,
                                                                           trash=False, date__date__gte=date1,
                                                                           system_registration_code=True,
                                                                           date__date__lte=date2).order_by('-date',
                                                                                                           'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           trash=False,
                                                                           system_registration_code=True).order_by(
                                '-date', 'system_registration_code').exclude(to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(to_kill_house=pos.kill_house,
                                                                           receiver_state=state,
                                                                           trash=False,
                                                                           system_registration_code=True).order_by(
                                '-date', 'system_registration_code').exclude(to_cold_house__isnull=False)

            else:
                allocations = StewardAllocation.objects.filter(
                    Q(to_kill_house=pos.kill_house) | Q(kill_house=pos.kill_house),
                    trash=False).order_by('-date', 'system_registration_code').exclude(to_cold_house__isnull=False)




        else:
            if state and type:

                if type == 'output':
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                receiver_state=state,
                                trash=False, date__date__gte=date1,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(steward=pos.guild) | Q(guilds=pos.guild),
                                receiver_state=state,
                                trash=False).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                else:
                    if date1 and date2:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False, date__date__gte=date1,
                                receiver_state=state,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)

                    else:
                        if state == 'all':
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False,
                                system_registration_code=True).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)
                        else:
                            allocations = StewardAllocation.objects.filter(
                                Q(to_steward=pos.guild) | Q(to_guilds=pos.guild),
                                trash=False,
                                receiver_state=state,
                                system_registration_code=True,
                                date__date__lte=date2).order_by('-date', 'system_registration_code').exclude(
                                to_cold_house__isnull=False)


            else:
                allocations = StewardAllocation.objects.filter(
                    Q(to_steward=pos.guild) | Q(to_guilds=pos.guild) | Q(steward=pos.guild) | Q(guilds=pos.guild),
                    trash=False).order_by('-date', 'system_registration_code').exclude(to_cold_house__isnull=False)

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = PosStewardAllocationSerializer(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # def destroy(self, request, pk=None, *args, **kwargs):
    #     allocation = StewardAllocation.objects.get(key=request.GET["allocation_key"])
    #     product = allocation.product
    #     seller_type = allocation.seller_type
    #     allocation.delete()
    #     if seller_type == 'KillHouse':
    #         kill_house_allocations_product_warehousing(product)
    #
    #     else:
    #         guild_steward_allocations_product_warehousing(product)
    #     return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)
    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = StewardAllocation.objects.get(key=request.GET["steward_allocation_key"])
        if allocation.receiver_state == 'accepted':
            if allocation.to_steward:
                buyer_product = RolesProducts.objects.get(guild=allocation.to_guildso, trash=False,
                                                          parent_product=allocation.product.parent_product)
            elif allocation.to_guilds:
                buyer_product = RolesProducts.objects.get(guild=allocation.to_steward, trash=False,
                                                          parent_product=allocation.product.parent_product)


            elif allocation.to_kill_house:
                buyer_product = RolesProducts.objects.get(kill_house=allocation.to_kill_house, trash=False,
                                                          parent_product=allocation.product.parent_product)

            else:
                buyer_product = None

            if buyer_product:
                if buyer_product.total_remain_weight < allocation.real_weight_of_carcasses:
                    return Response({"result": "وزن حذف شده بیشتر از موجودی انبار خریدار است!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if allocation.to_cold_house:
                    if allocation.other_cold_house:
                        if allocation.other_cold_house.total_remain_weight < allocation.real_weight_of_carcasses:
                            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                            status=status.HTTP_403_FORBIDDEN)
                    else:
                        if allocation.to_cold_house.total_remain_weight < allocation.real_weight_of_carcasses:
                            return Response({"result": "وزن وارد شده بیشتر از موجودی انبار خریدار است!"},
                                            status=status.HTTP_403_FORBIDDEN)

        product = allocation.product
        seller_type = allocation.seller_type
        to_cold_house = allocation.to_cold_house
        other_cold_house = allocation.other_cold_house if allocation.other_cold_house else None
        allocation.trash = True
        allocation.save()
        if seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(product)
            if to_cold_house and to_cold_house.kill_house == product.kill_house:
                kill_house_cold_house_allocations(to_cold_house)

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


        else:
            guild_steward_allocations_product_warehousing(product)
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class DispenserAllocationDashboardViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DispenserAllocationSerializer

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        allocations = StewardAllocation.objects.filter(dispenser__key=request.GET['dispenser_key'], trash=False,
                                                       date__date__gte=date1,
                                                       date__date__lte=date2,
                                                       ).order_by('id')
        total_quantity = allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
        total_weight = allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
        stewards_allocations = allocations.filter(steward__isnull=False)
        steward_total_quantity = allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
        steward_total_weight = allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
        guilds_allocations = allocations.filter(guilds__isnull=False)
        guild_total_quantity = allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
        guild_total_weight = allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0

        allocation_info = {
            "number_of_allocations": len(allocations),
            "total_quantity": total_quantity,
            "total_weight": total_weight,
            "number_of_stewards_allocations": len(stewards_allocations),
            "steward_total_quantity": steward_total_quantity,
            "steward_total_weight": steward_total_weight,
            "number_of_guilds_allocations": len(guilds_allocations),
            "guild_total_quantity": guild_total_quantity,
            "guild_total_weight": guild_total_weight,
        }
        return Response(allocation_info, status=status.HTTP_200_OK)


class DispenserAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DispenserAllocationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = DispenserAllocationFilterSet
    filterset_fields = [
        'dispenser__user__first_name',
        'dispenser__user__last_name',
        'dispenser__user__fullname',
        'dispenser__user__mobile',
        'guilds__user__first_name',
        'guilds__user__last_name',
        'guilds__user__fullname',
        'guilds__user__mobile',
        'steward__guilds__user__first_name',
        'steward__guilds__user__last_name',
        'steward__guilds__user__fullname',
        'steward__guilds__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name'
    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        allocations_list = []
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            if request.GET['role'] == 'Dispenser':
                allocations = StewardAllocation.objects.filter(dispenser__user=user, trash=False,
                                                               date__date__gte=date1,
                                                               date__date__lte=date2,
                                                               ).order_by('-date')
            else:
                allocations = StewardAllocation.objects.filter(dispenser__key=request.GET['dispenser_key'], trash=False,
                                                               date__date__gte=date1,
                                                               date__date__lte=date2,
                                                               ).order_by('-date')
        else:
            if request.GET['role'] == 'Dispenser':
                allocations = StewardAllocation.objects.filter(dispenser__user=user, trash=False
                                                               ).order_by('-date')
            else:
                allocations = StewardAllocation.objects.filter(dispenser__key=request.GET['dispenser_key'],
                                                               trash=False).order_by('-date')
        if 'search' in request.GET:
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=allocations
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=allocations)
                            allocations_list = ps.filter()
                    allocations = [] if len(allocations_list) == 0 else allocations_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class StewardGuildAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if 'steward_allocation_key' in request.data.keys() and 'logged_registration_code' not in request.data.keys():
            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).select_related('steward_ware_house',
                                                                                              'steward_ware_house__steward').first()
            request.data.pop('steward_allocation_key')
            increase_number_of_carcasses = int(
                request.data['number_of_carcasses']) - steward_allocation.number_of_carcasses
            decrease_number_of_carcasses = steward_allocation.number_of_carcasses - int(
                request.data['number_of_carcasses'])
            increase_weight_of_carcasses = float(
                request.data['weight_of_carcasses']) - steward_allocation.weight_of_carcasses
            decrease_weight_of_carcasses = steward_allocation.weight_of_carcasses - float(
                request.data['weight_of_carcasses'])
            steward_ware_house = StewardWareHouse.objects.get(key=steward_allocation.steward_ware_house.key)

            if int(request.data['number_of_carcasses']) > steward_allocation.number_of_carcasses:
                if increase_number_of_carcasses > steward_ware_house.remain_total_number_of_carcasses:
                    return Response({"result": "تعداد وارد شده از موجودی انبار بیشتر است"},
                                    status=status.HTTP_403_FORBIDDEN)
                steward_ware_house.allocated_total_number_of_carcasses += increase_number_of_carcasses

            else:
                steward_ware_house.allocated_total_number_of_carcasses -= decrease_number_of_carcasses

            if float(request.data['weight_of_carcasses']) > steward_allocation.weight_of_carcasses:
                if increase_weight_of_carcasses > steward_ware_house.remain_total_weight_of_carcasses:
                    return Response({"result": "مقدار وارد شده از موجودی انبار بیشتر است"},
                                    status=status.HTTP_403_FORBIDDEN)
                steward_ware_house.allocated_total_weight_of_carcasses += increase_weight_of_carcasses

            else:
                steward_ware_house.allocated_total_weight_of_carcasses -= decrease_weight_of_carcasses

            steward_ware_house.save()

            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        elif 'steward_guild_allocation_list' in request.data.keys():
            allocations_list_temp = request.data['steward_guild_allocation_list']
            allocations_list = []
            steward_allocations = StewardAllocation.objects.filter(key__in=allocations_list_temp,
                                                                   trash=False)
            request.data.pop('steward_guild_allocation_list')
            for steward_allocation in steward_allocations:
                if steward_allocation.system_registration_code == True:
                    continue
                number = random.randint(10000, 99000)
                steward_allocation.registration_code = number
                steward_allocation.system_registration_code = True
                allocations_list.append(str(steward_allocation.key))

                # steward_allocation.final_registration = True
                steward_allocation.save()
                # steward_ware_house = StewardWareHouse.objects.filter(steward=steward_allocation.steward,
                #                                                      date__date=steward_allocation.date.date()).first()
                # if not steward_ware_house:
                #     steward_ware_house = StewardWareHouse(steward=steward_allocation.steward,
                #                                           date=steward_allocation.date)
                #     steward_ware_house.save()
                # steward_ware_house.bar_quantity += 1
                # steward_ware_house.number_of_carcasses += steward_allocation.real_number_of_carcasses
                # steward_ware_house.weight_of_carcasses += steward_allocation.real_weight_of_carcasses
                # steward_ware_house.save()

            sms_steward_allocations = threading.Thread(target=steward_allocations_sms,
                                                       args=(allocations_list,))

            sms_steward_allocations.start()

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

        else:

            steward_allocation = StewardAllocation.objects.filter(key=request.data['steward_allocation_key'],
                                                                  trash=False).last()
            request.data.pop('steward_allocation_key')
            if int(request.data['logged_registration_code']) != steward_allocation.registration_code:
                return Response({"result": "کد وارد شده صحیح نیست"}, status=status.HTTP_403_FORBIDDEN)

            steward_allocation.role = {
                "role": request.data['role'],
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date_register": str(datetime.now())
            }
            if 'logged_registration_code' in request.data.keys():
                steward_allocation.state = 'accepted'
                steward_allocation.save()
            request.data.pop('role')
            serializer = self.serializer_class(steward_allocation)
            serializer.update(instance=steward_allocation, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = StewardAllocation.objects.get(key=request.GET["steward_allocation_key"])
        steward_ware_house = StewardWareHouse.objects.get(key=allocation.steward_ware_house.key, trash=False)
        steward_ware_house.allocated_total_number_of_carcasses -= allocation.number_of_carcasses
        steward_ware_house.allocated_total_weight_of_carcasses -= allocation.weight_of_carcasses
        steward_ware_house.save()
        allocation.delete()
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class StewardWareHouseViewSet(viewsets.ModelViewSet):
    queryset = StewardWareHouse.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardWareHouseSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        now = datetime.now().date()
        date = datetime.strptime(request.GET['date'],
                                 '%Y-%m-%d').date() if 'date' in request.GET else now

        steward = Steward.objects.get(guilds__user=user, trash=False)
        steward_ware_house = StewardWareHouse.objects.filter(steward=steward,
                                                             date__date=date,
                                                             trash=False).last()

        if steward_ware_house is None:
            ware_house_date = datetime(year=date.year, month=date.month, day=date.day, hour=1, minute=12, second=20)
            steward_ware_house = StewardWareHouse(
                steward=steward,
                date=ware_house_date
            )
            steward_ware_house.save()

        bar_quantity = 0
        number_of_carcasses = 0
        real_number_of_carcasses = 0
        weight_of_carcasses = 0
        real_weight_of_carcasses = 0
        ave_weight_of_carcasses = 0
        free_sale_number_of_carcasses = 0
        free_sale_weight_of_carcasses = 0

        allocations = StewardAllocation.objects.filter(steward=steward, system_registration_code=True, date__date=date,
                                                       trash=False, state='accepted',
                                                       receiver_state__in=('pending', 'accepted'))

        if allocations.count() > 0:
            for allocation in allocations:
                bar_quantity += 1
                number_of_carcasses += allocation.number_of_carcasses
                weight_of_carcasses += allocation.weight_of_carcasses
                if allocation.receiver_state == 'accepted':
                    real_number_of_carcasses += allocation.receiver_real_number_of_carcasses
                    real_weight_of_carcasses += allocation.receiver_real_weight_of_carcasses
                ave_weight_of_carcasses += weight_of_carcasses / number_of_carcasses
        free_bars = StewardFreeBarInformation.objects.filter(steward=steward, date__date=date, trash=False)
        total_quantity_free_bar = 0
        total_weight_free_bar = 0
        number_of_free_bar = 0
        if len(free_bars) > 0:
            for free_bar in free_bars:
                number_of_free_bar += 1
                total_quantity_free_bar += free_bar.number_of_carcasses
                total_weight_free_bar += free_bar.weight_of_carcasses
        steward_free_sale_bar_infos = StewardFreeSaleBarInformation.objects.filter(steward=steward,
                                                                                   date__date=date,
                                                                                   trash=False)

        free_sale_number_of_carcasses = steward_free_sale_bar_infos.aggregate(total=Sum('number_of_carcasses'))[
                                            'total'] or 0
        free_sale_weight_of_carcasses = steward_free_sale_bar_infos.aggregate(total=Sum('weight_of_carcasses'))[
                                            'total'] or 0
        steward_ware_house.bar_quantity = bar_quantity
        steward_ware_house.number_of_carcasses = number_of_carcasses
        steward_ware_house.real_number_of_carcasses = real_number_of_carcasses + total_quantity_free_bar
        steward_ware_house.weight_of_carcasses = weight_of_carcasses
        steward_ware_house.real_weight_of_carcasses = real_weight_of_carcasses + total_weight_free_bar
        steward_ware_house.free_bar_quantity = number_of_free_bar
        steward_ware_house.number_of_free_carcasses = total_quantity_free_bar
        steward_ware_house.weight_of_free_carcasses = total_weight_free_bar
        steward_ware_house.free_sale_quantity = free_sale_number_of_carcasses
        steward_ware_house.free_sale_weight = free_sale_weight_of_carcasses
        steward_ware_house.remain_total_number_of_carcasses = steward_ware_house.real_number_of_carcasses - steward_ware_house.allocated_total_number_of_carcasses
        steward_ware_house.remain_total_weight_of_carcasses = steward_ware_house.real_weight_of_carcasses - steward_ware_house.allocated_total_weight_of_carcasses
        steward_ware_house.save()
        return Response({
            "steward_key": steward.key,
            "bar_quantity": bar_quantity,
            "number_of_carcasses": steward_ware_house.number_of_carcasses,
            "real_number_of_carcasses": steward_ware_house.real_number_of_carcasses,
            "weight_of_carcasses": steward_ware_house.weight_of_carcasses,
            "real_weight_of_carcasses": steward_ware_house.real_weight_of_carcasses,
            "free_bar_quantity": steward_ware_house.free_bar_quantity,
            "number_of_free_carcasses": steward_ware_house.number_of_free_carcasses,
            "weight_of_free_carcasses": steward_ware_house.weight_of_free_carcasses,
            "allocated_total_number_of_carcasses": steward_ware_house.allocated_total_number_of_carcasses,
            "allocated_total_weight_of_carcasses": steward_ware_house.allocated_total_weight_of_carcasses,
            "remain_total_number_of_carcasses": steward_ware_house.remain_total_number_of_carcasses,
            "remain_total_weight_of_carcasses": steward_ware_house.remain_total_weight_of_carcasses,
            "free_sale_quantity": steward_ware_house.free_sale_quantity,
            "free_sale_weight": steward_ware_house.free_sale_weight,
            "total_average_weight_of_carcasses": round(
                steward_ware_house.real_weight_of_carcasses / steward_ware_house.real_number_of_carcasses,
                2) if steward_ware_house.real_number_of_carcasses > 0 else 0,
        }, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        ware_house = KillHouseWareHouse.objects.get(key=request.data['key'])
        ware_house.updated_number_of_carcasses = request.data['updated_number_of_carcasses']
        ware_house.updated_weight_of_carcasses = request.data['updated_weight_of_carcasses']
        ware_house.total_weight_of_carcasses = request.data[
                                                   'updated_weight_of_carcasses'] + ware_house.weight_of_carcasses
        ware_house.total_number_of_carcasses = request.data[
                                                   'updated_number_of_carcasses'] + ware_house.number_of_carcasses
        ware_house.save()
        serializer = self.serializer_class(ware_house)
        serializer.update(instance=ware_house, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalReportOfStewardWareHouseForDailyBroadCastViewSet(viewsets.ModelViewSet):
    queryset = StewardWareHouse.objects.all()
    serializer_class = StewardWareHouseSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(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, trash=False)

        number_of_steward = Steward.objects.filter(
            pk__in=steward_ware_houses.values('steward')
        )

        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 Response({
            "buyers": len(number_of_steward),
            "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 TotalReportOfStewardWareHouseForDailyBroadCastInDetailsViewSet(viewsets.ModelViewSet):
    queryset = Steward.objects.all()
    serializer_class = StewardWareHouseForDailyBroadCastOInDetailsSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(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, trash=False)
        stewards = Steward.objects.filter(
            pk__in=steward_ware_houses.values('steward')
        )

        serializer = self.serializer_class(stewards, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class ChooseProductForGuildViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProductSerializer

    # def update(self, request, pk=None, *args, **kwargs):
    #     product = Product.objects.get(key=request.data['product_key'])
    #     gulid = Guilds.objects.get(key=request.data['guild_key'])
    #     request.data.pop('product_key')
    #     request.data.pop('guild_key')
    #     if Product.objects.filter(guild=gulid,name=product.name).exists():
    #         return Response({"result":"این محصول قبلا ثبت شده"})
    #     serializer = self.serializer_class(product)
    #     serializer.update(instance=product, validated_data=request.data)
    #     return Response(serializer.data, status=status.HTTP_200_OK)


class GuildsWareHouseTotalProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProductSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        guild = Guilds.objects.get(user=user, trash=False)
        products = Product.objects.filter(Q(general=False, guild=guild) | Q(general=True, guild__isnull=True),
                                          trash=False).order_by('priority')
        product_serializer = ProductSerializer(products, many=True)
        return Response(product_serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        product = Product.objects.get(key=request.data['product_key'])
        request.data.pop('product_key')
        serializer = self.serializer_class(product)
        serializer.update(instance=product, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class GuildsWareHouseProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProductSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        guild = Guilds.objects.get(user=user, trash=False)
        products = Product.objects.filter(
            Q(general=False, guild=guild, show=True) | Q(general=True, guild__isnull=True),
            trash=False).order_by('priority')
        product_serializer = ProductSerializer(products, many=True)
        return Response(product_serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        product = Product.objects.get(key=request.data['product_key'])
        request.data.pop('product_key')
        serializer = self.serializer_class(product)
        serializer.update(instance=product, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


def change_product_state(product_key):
    additional_product = AdditionalProducts.objects.get(key=product_key)
    products = Product.objects.filter(name=additional_product.name, trash=False)
    if products:
        for product in products:
            product.selling_approved_price = additional_product.selling_approved_price
            product.selling_free_price = additional_product.selling_free_price
            product.selling_more_than_inventory = additional_product.selling_more_than_inventory
            product.selling_other_products = additional_product.selling_other_products
            product.price = additional_product.price
            product.save()


def change_roles_products_state(state, price, steward_price, guild_price):
    roles_products = RolesProducts.objects.filter(trash=False)
    for roles_product in roles_products:
        if roles_product.kill_house:
            roles_product.approved_price_status = state
            roles_product.approved_price = price
        else:
            if roles_product.guild.steward:
                roles_product.approved_price = steward_price
                roles_product.approved_price_status = state if steward_price > 0 else False
            else:
                roles_product.approved_price = guild_price
                roles_product.approved_price_status = state if guild_price > 0 else False
        if state:
            roles_product.free_price = 0

        roles_product.save()


class ServerMainProductsViewSet(viewsets.ModelViewSet):
    queryset = AdditionalProducts.objects.all()
    permission_classes = [AllowAny]
    serializer_class = AdditionalProductsSerializer

    def list(self, request, *args, **kwargs):
        products = AdditionalProducts.objects.filter(trash=False).order_by('id')

        product_serializer = AdditionalProductsSerializer(products, many=True)
        return Response(product_serializer.data, status=status.HTTP_200_OK)


class AdditionalProductsViewSet(viewsets.ModelViewSet):
    queryset = AdditionalProducts.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AdditionalProductsSerializer

    def list(self, request, *args, **kwargs):
        products = AdditionalProducts.objects.filter(trash=False).order_by('id')

        product_serializer = AdditionalProductsSerializer(products, many=True)
        return Response(product_serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        product = AdditionalProducts.objects.get(key=request.data['product_key'])
        request.data.pop('product_key')
        serializer = self.serializer_class(product)
        serializer.update(instance=product, validated_data=request.data)
        change_guild_products_info = threading.Thread(target=change_product_state,
                                                      args=(product.key,))

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


class GuildsWareHouseViewSet(viewsets.ModelViewSet):
    queryset = GuildsWareHouse.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsWareHouseSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        now = datetime.now().date()
        date = datetime.strptime(request.GET['date'],
                                 '%Y-%m-%d').date() if 'date' in request.GET else now

        guild = Guilds.objects.get(user=user, trash=False)
        guild_ware_house = GuildsWareHouse.objects.filter(guilds=guild,
                                                          # date__date=date,
                                                          trash=False).first()

        if guild_ware_house is None:
            ware_house_date = datetime(year=date.year, month=date.month, day=date.day, hour=1, minute=12, second=20)
            guild_ware_house = GuildsWareHouse(
                guilds=guild,
                date=ware_house_date
            )
            guild_ware_house.save()

        bar_quantity = 0
        number_of_carcasses = 0
        real_number_of_carcasses = 0
        weight_of_carcasses = 0
        real_weight_of_carcasses = 0
        ave_weight_of_carcasses = 0

        allocations = StewardAllocation.objects.filter(
            (Q(allocation_type='steward_broadcast') | Q(allocation_type='kill_house_broadcast')), guilds=guild,
            system_registration_code=True,
            # date__date=date,
            trash=False, state='accepted', receiver_state__in=('pending', 'accepted'))
        accepted_allocations = allocations.filter(receiver_state='accepted')
        if len(allocations) > 0:
            bar_quantity = len(allocations)
            number_of_carcasses = allocations.aggregate(total=Sum('number_of_carcasses'))['total'] or 0
            real_number_of_carcasses = accepted_allocations.aggregate(total=Sum('receiver_real_number_of_carcasses'))[
                                           'total'] or 0
            weight_of_carcasses = allocations.aggregate(total=Sum('weight_of_carcasses'))['total'] or 0
            real_weight_of_carcasses = accepted_allocations.aggregate(total=Sum('receiver_real_weight_of_carcasses'))[
                                           'total'] or 0
            ave_weight_of_carcasses = weight_of_carcasses / number_of_carcasses if number_of_carcasses > 0 else 0

        # if allocations.count() > 0:
        #     for allocation in allocations:
        #         bar_quantity += 1
        #         number_of_carcasses += allocation.number_of_carcasses
        #         real_number_of_carcasses += allocation.receiver_real_number_of_carcasses
        #         weight_of_carcasses += allocation.weight_of_carcasses
        #         real_weight_of_carcasses += allocation.receiver_real_weight_of_carcasses
        #         ave_weight_of_carcasses += weight_of_carcasses / number_of_carcasses
        guild_ware_house.bar_quantity = bar_quantity
        guild_ware_house.number_of_carcasses = number_of_carcasses
        guild_ware_house.real_number_of_carcasses = real_number_of_carcasses
        guild_ware_house.weight_of_carcasses = weight_of_carcasses
        guild_ware_house.real_weight_of_carcasses = real_weight_of_carcasses
        guild_ware_house.remain_total_number_of_carcasses = guild_ware_house.real_number_of_carcasses - guild_ware_house.allocated_total_number_of_carcasses if guild_ware_house.real_number_of_carcasses > 0 else 0
        guild_ware_house.remain_total_weight_of_carcasses = guild_ware_house.real_weight_of_carcasses - guild_ware_house.allocated_total_weight_of_carcasses if guild_ware_house.real_weight_of_carcasses > 0 else 0
        guild_ware_house.save()
        return Response({
            "bar_quantity": bar_quantity,
            "number_of_carcasses": guild_ware_house.number_of_carcasses,
            "real_number_of_carcasses": guild_ware_house.real_number_of_carcasses,
            "weight_of_carcasses": guild_ware_house.weight_of_carcasses,
            "real_weight_of_carcasses": guild_ware_house.real_weight_of_carcasses,
            "allocated_total_number_of_carcasses": guild_ware_house.allocated_total_number_of_carcasses,
            "allocated_total_weight_of_carcasses": guild_ware_house.allocated_total_weight_of_carcasses,
            "remain_total_number_of_carcasses": guild_ware_house.remain_total_number_of_carcasses,
            "remain_total_weight_of_carcasses": guild_ware_house.remain_total_weight_of_carcasses,
            "total_average_weight_of_carcasses": round(
                guild_ware_house.real_weight_of_carcasses / guild_ware_house.real_number_of_carcasses,
                2) if guild_ware_house.real_number_of_carcasses > 0 else 0,
        }, status=status.HTTP_200_OK)


class VetSupervisorViewSet(viewsets.ModelViewSet):
    queryset = VetSupervisor.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = VetSupervisorSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            operator = user.supervisor_user.all()

            # send to serializer
            serializer = self.serializer_class(operator[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityVetViewSet(viewsets.ModelViewSet):
    queryset = CityVet.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityVetSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            operator = user.city_vet_user.all().last()

            serializer = self.serializer_class(operator)
            return Response(serializer.data, status=status.HTTP_200_OK)


class ProvinceCheckKillRequestViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckOperatorRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceCheckOperatorRequestSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user)
        now = datetime.now()
        state = request.data['state']
        request.data.pop('state')
        if 'quantity' in request.data.keys() and request.data['quantity'] != None:
            quantity = request.data['quantity']
            request.data.pop('quantity')
        else:
            quantity = None
            # request.data.pop('quantity')
        if 'breed' in request.data.keys() and request.data['breed'] != None:
            breed = request.data['breed']
            request.data.pop('breed')
        else:
            breed = None
            # request.data.pop('breed')

        kill_request = KillRequest.objects.get(key=request.data['kill_request_key'])
        request.data.pop('kill_request_key')
        if state == 'accepted':
            kill_request.province_state = 'accepted'
            if quantity != None:
                kill_request.province_quantity = kill_request.kill_capacity
                kill_request.kill_capacity = int(quantity)
                kill_request.remain_quantity = int(quantity)
            if breed != None:
                kill_request.old_chicken_breed = kill_request.chicken_breed
                kill_request.chicken_breed = breed
            kill_request.save()
            price = Pricing.objects.all()
            if price.count() > 0:
                price = price.last()
                factor = KillRequestFactor(
                    kill_request=kill_request,
                    amount=round((kill_request.kill_capacity * kill_request.Index_weight) * price.live_chicken_price,
                                 0),
                    # amount=round((kill_request.kill_capacity * kill_request.Index_weight) * price.live_chicken_price,
                    #              0) * 1000,
                    minimum_amount=round(
                        ((kill_request.kill_capacity * kill_request.Index_weight) * price.live_chicken_price) * (
                                70 / 100),
                        0)

                )
                factor.save()
                kill_request.factor_amount = factor.amount
                kill_request.save()
                mobile = kill_request.kill_house.kill_house_operator.user.mobile
                kill_house_name = kill_request.kill_house.name
                # sms_province_kill_request_accept_sms = threading.Thread(
                #     target=province_kill_request_accept_sms,
                #     args=(
                #         mobile, kill_house_name))
                # sms_province_kill_request_accept_sms.start()
            confirmation_of_the_need_for_slaughterhouse = threading.Thread(
                target=confirmation_of_the_need_for_slaughterhouse_sms_threading,
                args=(
                    kill_request.kill_house.name))
            confirmation_of_the_need_for_slaughterhouse.start()
        else:
            mobile = kill_request.kill_house.kill_house_operator.user.mobile
            kill_house_name = kill_request.kill_house.name
            sms_province_kill_request_reject_sms = threading.Thread(
                target=province_kill_request_reject_sms,
                args=(
                    mobile, kill_house_name))
            sms_province_kill_request_reject_sms.start()

            kill_request.province_state = 'rejected'
            kill_request.message = request.data['msg']
            kill_request.state = 'archive'
            kill_request.save()
        return Response(status=status.HTTP_201_CREATED)


class VetCheckAllocationsViewSet(viewsets.ModelViewSet):
    queryset = VetCheckAllocations.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = VetCheckAllocationsSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user)
        vet_superviser = VetSupervisor.objects.filter(address__province=user.province)
        kill_house_request = KillHouseRequest.objects.get(key=request.data['kill_house_request_key'])
        clearance_code = request.data['code']
        role = request.data['role']
        if 'code' in request.data.keys():
            date_time_of_now = datetime.now().date()
            if OperationLimitation.objects.all().first().vet_farm_limitation == True and role not in ['Supporter',
                                                                                                      'AdminX',
                                                                                                      'Supporter']:

                if date_time_of_now > kill_house_request.kill_request.recive_date.date() + timedelta(days=1):
                    return Response(
                        {"result": "به علت مغایرت در تاریخ ثبت و تاریخ کشتار امکان ثبت اطلاعات وجود ندارد!"},
                        status=status.HTTP_403_FORBIDDEN)

            if KillHouseRequest.objects.filter(clearance_code=clearance_code, trash=False).exists():
                return Response({"result": "کد وارد شده تکراری میباشد!"}, status=status.HTTP_403_FORBIDDEN)

        request.data.pop('kill_house_request_key')
        request.data.pop('role')
        request.data.pop('code')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            check_request = serializer.create(validated_data=request.data)
            now = datetime.now()
            formatted_now = now.strftime('%Y-%m-%dT%H:%M:%S')

            if role == 'ProvinceOperator':
                if vet_superviser.count() > 0:
                    vet_superviser = vet_superviser.last()
                    check_request.vet = vet_superviser.vet
                    check_request.save()
            kill_house_request.clearance_code = clearance_code

            kill_house_request.registrar_clearance_code = {
                'role': role,
                'name': user.fullname,
                'mobile': user.mobile,
                'date': str(formatted_now),
            }
            kill_house_request.save()
            try:
                get_gid(kill_house_request.clearance_code)
            except:
                pass
            check_request.kill_house_request = kill_house_request
            try:
                vet = Vet.objects.get(user=user)
                check_request.vet = vet
                check_request.reviewer = {
                    'role': role,
                    'name': vet.user.fullname,
                    'mobile': vet.user.mobile,
                }
            except:
                check_request.reviewer = {
                    'role': role,
                    'name': user.fullname,
                    'mobile': user.mobile,
                }

            check_request.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def update(self, request, pk=None, selected_kill_house_request=None, *args, **kwargs):

        code = request.data['code']
        kill_house_request = KillHouseRequest.objects.get(key=request.data['kill_house_request_key'], trash=False)
        if KillHouseRequest.objects.filter(clearance_code=code, trash=False).exists():
            return Response(
                {"result": "کد وارد شده تکراری میباشد!"},
                status=status.HTTP_403_FORBIDDEN
            )
        if kill_house_request.aggregate_status == True:
            kill_house_requests = KillHouseRequest.objects.filter(
                aggregate_code=kill_house_request.aggregate_code).order_by('id')

            for kill_house_request in kill_house_requests:
                if 'code' in request.data.keys():
                    kill_house_request.clearance_code = request.data['code']
                if 'traffic_code' in request.data.keys():
                    kill_house_request.traffic_code = request.data['traffic_code']

                kill_house_request.save()
        else:
            kill_house_request.clearance_code = code
            kill_house_request.save()
        try:
            get_gid(kill_house_request.clearance_code)
        except:
            pass
        return Response({"result": "کد ترخیص با موفقیت ویرایش شد"}, status=status.HTTP_200_OK)

    def destroy(self, request, *args, **kwargs):
        kill = KillHouseRequest.objects.get(key=request.GET['kill_house_request_key'], trash=False)

        vat_check_request = VetCheckAllocations.objects.get(kill_house_request=kill, trash=False)
        vat_check_request.delete()
        kill.clearance_code = None
        kill.traffic_code = None
        kill.aggregate_status = False
        kill.aggregate_code = None
        kill.save()
        return Response({'msg': f'بار به شماره {kill.bar_code} از تجمیع خارج شد.'}, status=status.HTTP_200_OK)


class AggregateVetCheckAllocationsViewSet(viewsets.ModelViewSet):
    queryset = VetCheckAllocations.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = VetCheckAllocationsSerializer

    def create(self, request, *args, **kwargs):
        # Extract necessary data from request
        user = get_object_or_404(SystemUserProfile, user=request.user)
        province = user.province
        clearance_code = request.data.get('code')
        traffic_code = request.data.get('traffic_code')
        role = request.data.get('role')
        kill_house_request_keys = request.data['kill_house_requests_list']

        # Fetch related objects in a single query
        kill_house_requests = KillHouseRequest.objects.filter(key__in=kill_house_request_keys).order_by('id')
        aggregate_code = kill_house_requests.first().bar_code
        vet_supervisor = VetSupervisor.objects.filter(address__province=province).last()
        operation_limitation = OperationLimitation.objects.first()
        if clearance_code is not None and KillHouseRequest.objects.filter(clearance_code=clearance_code,
                                                                          trash=False).exists():
            return Response(
                {"result": "کد وارد شده تکراری میباشد!"},
                status=status.HTTP_403_FORBIDDEN
            )
        # Validation
        if clearance_code and operation_limitation.vet_farm_limitation and role not in ['Supporter', 'AdminX']:
            first_kill_house_request = kill_house_requests.first()
            if first_kill_house_request and now().date() > (
                    first_kill_house_request.kill_request.recive_date.date() + timedelta(days=1)):
                return Response(
                    {"result": "به علت مغایرت در تاریخ ثبت و تاریخ کشتار امکان ثبت اطلاعات وجود ندارد!"},
                    status=status.HTTP_403_FORBIDDEN
                )

        # Prepare data for saving
        request_data = request.data.copy()  # Use copy to avoid modifying original request data
        request_data.pop('kill_house_requests_list', None)
        request_data.pop('role', None)
        request_data.pop('code', None)
        now_formatted = now().strftime('%Y-%m-%dT%H:%M:%S')

        for kill_house_request in kill_house_requests:
            if kill_house_request.aggregate_status:
                check_request = get_object_or_404(VetCheckAllocations, kill_house_request=kill_house_request,
                                                  trash=False)
            else:
                serializer = self.serializer_class(data=request_data)
                if serializer.is_valid():
                    check_request = serializer.save()
                    kill_house_request.aggregate_status = True
                    kill_house_request.aggregate_code = aggregate_code
                else:
                    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

            # Update vet and reviewer information
            if role == 'ProvinceOperator' and vet_supervisor:
                check_request.vet = vet_supervisor.vet

            if clearance_code:
                kill_house_request.clearance_code = clearance_code
                kill_house_request.traffic_code = traffic_code
                kill_house_request.registrar_clearance_code = {
                    'role': role,
                    'name': user.fullname,
                    'mobile': user.mobile,
                    'date': now_formatted,
                }

            # Set reviewer information
            try:
                vet = Vet.objects.get(user=user)
                check_request.vet = vet
                check_request.reviewer = {
                    'role': role,
                    'name': vet.user.fullname,
                    'mobile': vet.user.mobile,
                }
            except Vet.DoesNotExist:
                check_request.reviewer = {
                    'role': role,
                    'name': user.fullname,
                    'mobile': user.mobile,
                }

            # Save changes
            kill_house_request.save()
            check_request.kill_house_request = kill_house_request
            check_request.save()
        try:
            if kill_house_requests.first().clearance_code is not None:
                get_gid(kill_house_requests.first().clearance_code)
        except:
            pass
        return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None, *args, **kwargs):

        type = request.data.get('type')
        if type == 'cancel_aggregate':
            selected_kill_house_request = KillHouseRequest.objects.get(key=request.data['kill_house_request_key'])
            kill_house_requests = KillHouseRequest.objects.filter(
                aggregate_code=selected_kill_house_request.aggregate_code).order_by('id')
            for kill_house_request in kill_house_requests:
                check_request = get_object_or_404(VetCheckAllocations, kill_house_request=kill_house_request,
                                                  trash=False)
                check_request.delete()
                kill_house_request.aggregate_status = False
                kill_house_request.aggregate_code = None
                kill_house_request.save()
        else:
            selected_kill_house_request = KillHouseRequest.objects.get(key=request.data['kill_house_request_key'])
            kill_house_requests = KillHouseRequest.objects.filter(
                aggregate_code=selected_kill_house_request.aggregate_code).order_by('id')

            for kill_house_request in kill_house_requests:
                if 'code' in request.data.keys():
                    kill_house_request.clearance_code = request.data['code']
                if 'traffic_code' in request.data.keys():
                    kill_house_request.traffic_code = request.data['traffic_code']

                kill_house_request.save()
            try:
                if kill_house_requests.first().clearance_code is not None:
                    get_gid(kill_house_requests.first().clearance_code)
            except:
                pass
        return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)


class ProvincePercentLeftOverViewSet(viewsets.ModelViewSet):
    queryset = ProvincePercentLeftOver.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvincePercentLeftOverSerializer


# ویوست مربوط یه قیمت گذاری
class PricingViewSet(viewsets.ModelViewSet):
    queryset = Pricing.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PricingSerializer

    # تابع مربوط یه قیمت گذاری
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        # role = request.data['role']
        # request.data.pop('role')
        user = SystemUserProfile.objects.get(user=request.user)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            prices = Pricing.objects.filter(trash=False)
            date1 = (datetime.strptime(request.data['date'], '%Y-%m-%d %H:%M:%S')).date()
            for price in prices:
                if price.date.year == date1.year and price.date.month == date1.month and price.date.day == date1.day:
                    price.live_chicken_price = float(request.data['live_chicken_price'])
                    price.ceiling_price = float(request.data['ceiling_price'])
                    price.floor_price = float(request.data['floor_price'])
                    # price.dead_chicken_price = float(request.data['dead_chicken_price'])
                    # price.major_seller_price = float(request.data['major_seller_price'])
                    # price.retail_seller_price = float(request.data['retail_seller_price'])
                    price.save()
                    return Response({"result": "object update"}, status=status.HTTP_200_OK)
            pricing = serializer.create(validated_data=request.data)
            # pricing.role = role
            pricing.operator = user
            pricing.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    # تابع مربوط یه نمایش قیمت های ثبت شده
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        if 'role' in request.GET:
            # if request.GET['role'] == 'Poultry':
            now = datetime.now().date()
            # pricing = Pricing.objects.filter(date__year=now.year, date__month=now.month, date__day=now.day,
            #                                  trash=False)
            pricing = Pricing.objects.all()
            if pricing.count() > 0:
                queryset = pricing.last()
                serializer = PricingSerializer(queryset)
                return Response(serializer.data, status=status.HTTP_200_OK)

            else:
                queryset = []
                return Response(queryset, status=status.HTTP_200_OK)

        else:
            queryset = Pricing.objects.filter(trash=False).order_by('-date')
            serializer = PricingSerializer(queryset, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)


# class ProvinceCheckOperatorOutRequestViewSet(viewsets.ModelViewSet):
#     queryset = ProvinceCheckOperatorOutRequest.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = ProvinceCheckOperatorOutRequestSerializer
#
#     def create(self, request, *args, **kwargs):
#         # refresh(request.user.id)
#         user = SystemUserProfile.objects.get(user=request.user, trash=False)
#         poultry_request = PoultryRequest.objects.get(key=request.data['poultry_request_key'], trash=False)
#         hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
#         wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
#         request.data.pop('poultry_request_key')
#         state = request.data['state']
#         message = request.data['message']
#         request.data.pop('message')
#         # if state == 'accepted':
#         #     if wage_type and wage_type.status == True:
#         #         if 'payer_type' in request.data.keys() and request.data['payer_type'] is not None:
#         #             poultry_request.payer_type = request.data['payer_type']
#         #             if request.data['payer_type'] == 'buyer':
#         #                 poultry_request.payer_fullname = poultry_request.buyer['firstName'] + " " + \
#         #                                                  poultry_request.buyer[
#         #                                                      'lastName']
#         #             else:
#         #                 poultry_request.payer_fullname = poultry_request.poultry.user.fullname
#         #             poultry_request.save()
#         #
#         #             request.data.pop('payer_type')
#         #         mobile_sms = ''
#         #         if 'buyer_mobile' in request.data.keys() and request.data['buyer_mobile'] is not None:
#         #             poultry_request.buyer['mobile'] = request.data['buyer_mobile']
#         #             mobile_sms = request.data['buyer_mobile']
#         #             poultry_request.save()
#         #             # request.data.pop('buyer_mobile')
#         #         if 'poultry_mobile' in request.data.keys() and request.data['poultry_mobile'] is not None:
#         #             if poultry_request.poultry.user.mobile != request.data['poultry_mobile']:
#         #                 first_mobile_number = poultry_request.poultry.user.mobile
#         #                 second_mobile_number = request.data['poultry_mobile']
#         #                 # request.data.pop('poultry_mobile')
#         #                 system_user_profile = SystemUserProfile.objects.get(mobile=first_mobile_number, trash=False)
#         #                 user = User.objects.get(id=system_user_profile.user.id)
#         #
#         #                 if SystemUserProfile.objects.filter(mobile=second_mobile_number, trash=False).exists():
#         #                     return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
#         #                                     status=status.HTTP_403_FORBIDDEN)
#         #                 data = {
#         #                     "first_mobile_number": first_mobile_number,
#         #                     "second_mobile_number": second_mobile_number,
#         #                 }
#         #                 req = requests.post(
#         #                     url=ARTA_URL_CHANGE_MOBILE_NUMBER,
#         #                     data=data,
#         #                     verify=False
#         #                 )
#         #                 if req.status_code == 200:
#         #                     user.username = second_mobile_number
#         #                     user.save()
#         #                     system_user_profile.mobile = second_mobile_number
#         #                     system_user_profile.save()
#         #             mobile_sms = poultry_request.poultry.user.mobile
#         #         request.data.pop('buyer_mobile')
#         #         request.data.pop('poultry_mobile')
#         serializer = self.serializer_class(data=request.data)
#         if serializer.is_valid():
#             check_out = serializer.create(validated_data=request.data)
#             check_out.poultry_request = poultry_request
#             check_out.save()
#             if state == 'accepted':
#                 poultry_request.state_process = 'accepted'
#                 poultry_request.province_state = 'accepted'
#                 poultry_request.agent = {
#                     "role": None,
#                     "fullname": user.fullname,
#                     "mobile": user.mobile,
#                     "date": str(datetime.now()),
#                 }
#                 # if wage_type and wage_type.status == False:
#                 hatching.out_province_killed_weight += int(poultry_request.quantity * poultry_request.Index_weight)
#
#                 hatching.out_province_killed_quantity += poultry_request.quantity
#                 hatching.save()
#                 poultry_request.hatching_left_over = hatching.left_over
#                 # poultry_request.archive_wage = True
#                 # else:
#                 #     province_out_request_transaction_sms(province=hatching.poultry.address.province.name,
#                 #                                          buyer=poultry_request.buyer['firstName'] + " " +
#                 #                                                poultry_request.buyer[
#                 #                                                    'lastName'],
#                 #                                          poultry_name=poultry_request.poultry.user.fullname,
#                 #                                          quantity=poultry_request.quantity,
#                 #                                          index_weight=poultry_request.Index_weight,
#                 #                                          wage=poultry_request.total_wage_amount,
#                 #                                          mobile=mobile_sms, order_code=poultry_request.order_code,
#                 #                                          date=poultry_request.send_date.date())
#
#             else:
#                 poultry_request.state_process = 'rejected'
#                 poultry_request.province_state = 'rejected'
#                 poultry_request.agent = {
#                     "role": None,
#                     "fullname": user.fullname,
#                     "mobile": user.mobile,
#                     "date": str(datetime.now()),
#                 }
#             poultry_request.message = message if message != "" else None
#
#             poultry_request.final_state = 'archive'
#             poultry_request.save()
#             check_serializer = self.serializer_class(check_out)
#
#             return Response(check_serializer.data, status=status.HTTP_201_CREATED)
#         return Response(serializer.errors)
#
#     def destroy(self, request, *args, **kwargs):
#         # refresh(request.user.id)
#         poultry_request = PoultryRequest.objects.get(key=request.GET['poultry_request_key'], trash=False)
#         hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
#         check = ProvinceCheckOperatorOutRequest.objects.get(poultry_request=poultry_request, trash=False)
#         check.trash = True
#         check.save()
#         hatching.out_province_killed_weight -= int(poultry_request.quantity * poultry_request.Index_weight)
#
#         hatching.out_province_killed_quantity -= poultry_request.quantity
#         hatching.save()
#         poultry_request.state_process = 'deleted'
#         poultry_request.province_state = 'deleted'
#         poultry_request.save()
#         return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)
#
#     def update(self, request, *args, **kwargs):
#         poultry_request = PoultryRequest.objects.get(key=request.data['poultry_request_key'], trash=False)
#         if 'quantity' in request.data.keys() and request.data['quantity'] is not None:
#             poultry_request.quantity = request.data['quantity']
#             poultry_request.Index_weight = request.data['Index_weight']
#             poultry_request.save()
#             poultry_request.total_wage_amount = int(
#                 (poultry_request.Index_weight * poultry_request.quantity) * poultry_request.wage)
#             poultry_request.save()
#             union_percent = poultry_request.union_share_percent / 100 if poultry_request.union_share_percent > 0 else 0
#             company_percent = poultry_request.company_share_percent / 100 if poultry_request.company_share_percent > 0 else 0
#             guilds_percent = poultry_request.guilds_share_percent / 100 if poultry_request.guilds_share_percent > 0 else 0
#             city_share_percent = poultry_request.city_share_percent / 100 if poultry_request.city_share_percent > 0 else 0
#             wallet_share_percent = poultry_request.wallet_share_percent / 100 if poultry_request.wallet_share_percent > 0 else 0
#             other_share_percent = poultry_request.other_share_percent / 100 if poultry_request.other_share_percent > 0 else 0
#             poultry_request.union_share = int(union_percent * poultry_request.total_wage_amount)
#             poultry_request.company_share = int(company_percent * poultry_request.total_wage_amount)
#             poultry_request.guilds_share = int(guilds_percent * poultry_request.total_wage_amount)
#             poultry_request.city_share = int(city_share_percent * poultry_request.total_wage_amount)
#             poultry_request.wallet_share = int(wallet_share_percent * poultry_request.total_wage_amount)
#             poultry_request.other_share = int(other_share_percent * poultry_request.total_wage_amount)
#             poultry_request.save()
#         if 'payer_type' in request.data.keys() and request.data['payer_type'] is not None:
#             poultry_request.payer_type = request.data['payer_type']
#             if request.data['payer_type'] == 'buyer':
#                 poultry_request.payer_fullname = poultry_request.buyer['firstName'] + " " + poultry_request.buyer[
#                     'lastName']
#             else:
#                 poultry_request.payer_fullname = poultry_request.poultry.user.fullname
#             poultry_request.save()
#
#         mobile_sms = ''
#         if 'buyer_mobile' in request.data.keys() and request.data['buyer_mobile'] is not None:
#             poultry_request.buyer['mobile'] = request.data['buyer_mobile']
#             mobile_sms = request.data['buyer_mobile']
#             poultry_request.save()
#         if 'poultry_mobile' in request.data.keys() and request.data['poultry_mobile'] is not None:
#             if poultry_request.poultry.user.mobile != request.data['poultry_mobile']:
#                 first_mobile_number = poultry_request.poultry.user.mobile
#                 second_mobile_number = request.data['poultry_mobile']
#                 system_user_profile = SystemUserProfile.objects.get(mobile=first_mobile_number, trash=False)
#                 user = User.objects.get(id=system_user_profile.user.id)
#
#                 if SystemUserProfile.objects.filter(mobile=second_mobile_number, trash=False).exists():
#                     return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
#                                     status=status.HTTP_403_FORBIDDEN)
#                 data = {
#                     "first_mobile_number": first_mobile_number,
#                     "second_mobile_number": second_mobile_number,
#                 }
#                 req = requests.post(
#                     url=ARTA_URL_CHANGE_MOBILE_NUMBER,
#                     data=data,
#                     verify=False
#                 )
#                 if req.status_code == 200:
#                     user.username = second_mobile_number
#                     user.save()
#                     system_user_profile.mobile = second_mobile_number
#                     system_user_profile.save()
#             mobile_sms = poultry_request.poultry.user.mobile
#         wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
#         if wage_type and wage_type.status == True:
#             province_out_request_transaction_sms(province=poultry_request.poultry.address.province.name,
#                                                  buyer=poultry_request.buyer['firstName'] + " " + poultry_request.buyer[
#                                                      'lastName'],
#                                                  poultry_name=poultry_request.poultry.user.fullname,
#                                                  quantity=poultry_request.quantity,
#                                                  index_weight=poultry_request.Index_weight,
#                                                  wage=poultry_request.total_wage_amount,
#                                                  mobile=mobile_sms, order_code=poultry_request.order_code,
#                                                  date=poultry_request.send_date.date(),
#                                                  amount=poultry_request.amount,
#                                                  sale_type=poultry_request.free_sale_in_province)
#
#         return Response({'result': 'با موفقیت انجام شد.'}, status=status.HTTP_201_CREATED)
class ProvinceCheckOperatorOutRequestViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckOperatorOutRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceCheckOperatorOutRequestSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        poultry_requests = PoultryRequest.objects.filter(key=request.data['poultry_request_key'], trash=False)
        request.data.pop('poultry_request_key')
        now = datetime.now().date()
        poultry = SystemUserProfile.objects.filter(
            key__in=poultry_requests.filter(payer_type='poultry', sms=False).values_list('poultry__user__key',
                                                                                         flat=True)).values_list('id',
                                                                                                                 flat=True)
        buyer = SystemUserProfile.objects.filter(
            key__in=poultry_requests.filter(payer_type='buyer', sms=False).values_list(
                'out_province_poultry_request_buyer__user__key',
                flat=True)).values_list('id', flat=True)
        poultry_requests_for_sms = poultry_requests.filter(payer_type='poultry').values_list('id', flat=True).distinct()
        wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
        if wage_type and wage_type.status == True:
            sms = threading.Thread(target=send_sms_for_final_approval_out_province_threading,
                                   args=(list(buyer), list(poultry_requests_for_sms)))
            sms.start()
        for poultry_request in poultry_requests:
            # if poultry_request.has_wage == False:
            hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
            if hatching.left_over >= poultry_request.quantity:
                hatching.out_province_killed_weight += int(poultry_request.quantity * poultry_request.Index_weight)
                hatching.out_province_killed_quantity += poultry_request.quantity
                hatching.save()
            else:
                different_quantity = poultry_request.quantity - hatching.left_over
                hatching.out_province_killed_weight += int(hatching.left_over * poultry_request.Index_weight)
                hatching.out_province_killed_quantity += hatching.left_over
                hatching.extra_killed_quantity += different_quantity
                hatching.save()
            url = f'https://rasadyar.net/pay/{base_url_for_sms_report}'
            if poultry_request.payer_type == 'poultry':
                poultry_request.payment_link = f'{url}/p{poultry_request.poultry.user.user_gate_way_id}{poultry_request.order_code}'
            else:
                poultry_request.payment_link = f'{url}/b{poultry_request.out_province_poultry_request_buyer.user.user_gate_way_id}'
            poultry_request.final_state = 'archive'
            poultry_request.province_state = 'accepted'
            poultry_request.state_process = 'accepted'
            poultry_request.agent = {
                "role": None,
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date": str(datetime.now())
            }
            poultry_request.hatching_left_over = poultry_request.hatching.left_over

            poultry_request.save()

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

    def destroy(self, request, *args, **kwargs):
        # refresh(request.user.id)
        poultry_request = PoultryRequest.objects.get(key=request.GET['poultry_request_key'], trash=False)
        hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
        check = ProvinceCheckOperatorOutRequest.objects.get(poultry_request=poultry_request, trash=False)
        check.trash = True
        check.save()
        hatching.out_province_killed_weight -= int(poultry_request.quantity * poultry_request.Index_weight)

        hatching.out_province_killed_quantity -= poultry_request.quantity
        hatching.save()
        poultry_request.state_process = 'deleted'
        poultry_request.province_state = 'deleted'
        poultry_request.save()
        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        poultry_request = PoultryRequest.objects.get(key=request.data['poultry_request_key'], trash=False)
        if 'quantity' in request.data.keys() and request.data['quantity'] is not None:
            poultry_request.quantity = request.data['quantity']
            poultry_request.Index_weight = request.data['Index_weight']
            poultry_request.save()
            poultry_request.total_wage_amount = int(
                (poultry_request.Index_weight * poultry_request.quantity) * poultry_request.wage)
            poultry_request.save()
            union_percent = poultry_request.union_share_percent / 100 if poultry_request.union_share_percent > 0 else 0
            company_percent = poultry_request.company_share_percent / 100 if poultry_request.company_share_percent > 0 else 0
            guilds_percent = poultry_request.guilds_share_percent / 100 if poultry_request.guilds_share_percent > 0 else 0
            city_share_percent = poultry_request.city_share_percent / 100 if poultry_request.city_share_percent > 0 else 0
            wallet_share_percent = poultry_request.wallet_share_percent / 100 if poultry_request.wallet_share_percent > 0 else 0
            other_share_percent = poultry_request.other_share_percent / 100 if poultry_request.other_share_percent > 0 else 0
            poultry_request.union_share = int(union_percent * poultry_request.total_wage_amount)
            poultry_request.company_share = int(company_percent * poultry_request.total_wage_amount)
            poultry_request.guilds_share = int(guilds_percent * poultry_request.total_wage_amount)
            poultry_request.city_share = int(city_share_percent * poultry_request.total_wage_amount)
            poultry_request.wallet_share = int(wallet_share_percent * poultry_request.total_wage_amount)
            poultry_request.other_share = int(other_share_percent * poultry_request.total_wage_amount)
            poultry_request.save()
        if 'payer_type' in request.data.keys() and request.data['payer_type'] is not None:
            poultry_request.payer_type = request.data['payer_type']
            if request.data['payer_type'] == 'buyer':
                poultry_request.payer_fullname = poultry_request.buyer['firstName'] + " " + poultry_request.buyer[
                    'lastName']
            else:
                poultry_request.payer_fullname = poultry_request.poultry.user.fullname
            poultry_request.save()

        mobile_sms = ''
        if 'buyer_mobile' in request.data.keys() and request.data['buyer_mobile'] is not None:
            poultry_request.buyer['mobile'] = request.data['buyer_mobile']
            mobile_sms = request.data['buyer_mobile']
            poultry_request.save()
        if 'poultry_mobile' in request.data.keys() and request.data['poultry_mobile'] is not None:
            if poultry_request.poultry.user.mobile != request.data['poultry_mobile']:
                first_mobile_number = poultry_request.poultry.user.mobile
                second_mobile_number = request.data['poultry_mobile']
                system_user_profile = SystemUserProfile.objects.get(mobile=first_mobile_number, trash=False)
                user = User.objects.get(id=system_user_profile.user.id)

                if SystemUserProfile.objects.filter(mobile=second_mobile_number, trash=False).exists():
                    return Response({"result": "این شماره در سامانه به نام شخص دیگری است"},
                                    status=status.HTTP_403_FORBIDDEN)
                data = {
                    "first_mobile_number": first_mobile_number,
                    "second_mobile_number": second_mobile_number,
                }
                req = requests.post(
                    url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                    data=data,
                    verify=False
                )
                if req.status_code == 200:
                    user.username = second_mobile_number
                    user.save()
                    system_user_profile.mobile = second_mobile_number
                    system_user_profile.save()
            mobile_sms = poultry_request.poultry.user.mobile
        wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
        if wage_type and wage_type.status == True:
            province_out_request_transaction_sms(province=poultry_request.poultry.address.province.name,
                                                 buyer=poultry_request.buyer['firstName'] + " " + poultry_request.buyer[
                                                     'lastName'],
                                                 poultry_name=poultry_request.poultry.user.fullname,
                                                 quantity=poultry_request.quantity,
                                                 index_weight=poultry_request.Index_weight,
                                                 wage=poultry_request.total_wage_amount,
                                                 mobile=mobile_sms, order_code=poultry_request.order_code,
                                                 date=poultry_request.send_date.date(),
                                                 amount=poultry_request.amount,
                                                 sale_type=poultry_request.free_sale_in_province)

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


# ویوست مربوط به تایید یا رد درخواست تایید شده شهرستان
class ProvinceCheckOperatorRequestViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckOperatorRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceCheckOperatorRequestSerializer

    # تابع مربوط به تایید یا رد درخواست تایید شده شهرستان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        state = request.data['state']

        try:
            key = request.data['key']
            request.data.pop('key')
        except:
            key = None

        try:
            poultry_key = request.data['poultry_key']
            request.data.pop('poultry_key')
            factor_fee = request.data['factor_fee']
            real_quantity = request.data['real_quantity']
            real_weight = request.data['real_weight']
            request.data.pop('factor_fee')
            request.data.pop('real_quantity')
            request.data.pop('real_weight')
        except:
            poultry_key = None
            factor_fee = None
            real_quantity = None
            real_weight = None

        if key != None:

            city_request = CityOperatorCheckRequest.objects.get(key=key, trash=False)
            poultry_request = PoultryRequest.objects.get(id=city_request.poultry_request.id, trash=False)
            hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key)
        else:
            poultry_request = PoultryRequest.objects.get(key=poultry_key, trash=False)
            hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key)

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        province_operator = ProvinceOperator.objects.get(user=user, trash=False)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            if key != None:
                if ProvinceCheckOperatorRequest.objects.filter(city_request_Poultry=city_request, trash=False).exists():
                    return Response({"result": "already exist"}, status=status.HTTP_403_FORBIDDEN)
            check = serializer.create(validated_data=request.data)
            province_fee = Pricing.objects.all()
            if province_fee.count() > 0:
                province_fee = province_fee.last().live_chicken_price
                check.fee = province_fee

            if key != None:
                check.city_request_Poultry = city_request
            check.province_operator_system = province_operator
            check.quantity = poultry_request.quantity
            send_date = poultry_request.send_date.date()
            price = Pricing.objects.filter(date__year=send_date.year, date__month=send_date.month,
                                           date__day=send_date.day, trash=False)
            if price:
                check.fee = price[0].live_chicken_price
            else:
                check.fee = 0

            check.poultry_request = poultry_request
            check.save()
            if state == 'reject':
                # poultry_request.state = {
                #     "city_operator": city_request.city_operator_system.user.first_name + " " + city_request.city_operator_system.user.last_name,
                #     "city_state": "accepted",
                #     "city_operator_mobile": city_request.city_operator_system.user.mobile,
                #     "city_operator_date_time_accepted": str(city_request.create_date),
                #     "province_operator": user.first_name + " " + user.last_name,
                #     "province_operator_mobile": user.mobile,
                #     "province_state": "rejected",
                #     "province_operator_date_time_accepted": str(check.create_date),
                #
                # }
                poultry_request.province_state = 'rejected'
                poultry_request.save()
                if poultry_request.kill_house_list != None and len(poultry_request.kill_house_list) > 0:
                    for item in poultry_request.kill_house_list:
                        parts = item.split("(")
                        name = parts[0].strip()
                        kill_request = KillRequest.objects.filter(kill_house__name=name,
                                                                  recive_date__date=poultry_request.send_date.date(),
                                                                  trash=False, poultry__isnull=True,
                                                                  province_state='accepted').first()
                        if kill_request:
                            kill_request.remain_quantity_for_poultry -= poultry_request.quantity
                            kill_request.save()
                if key != None:
                    city_request.province_state = 'reject'
                message = UserMessage(
                    message="درخواست شما با کد سفارش {0} از طرف کارشناس استان {1} رد شده است ".format(
                        poultry_request.order_code, user.fullname),
                    heading="پیام سیستم ثبت شده در تاریخ {0}".format(datetime.now()),
                    sender=user
                )
                message.save()
                message.users.add(poultry_request.poultry.user)
                # hatching.left_over += (poultry_request.quantity + poultry_request.losses)
                hatching.losses -= poultry_request.losses
                hatching.state = 'pending'
                hatching.allow_hatching = 'pending'
                hatching.save()
            elif state == 'accept':
                if poultry_key != None:
                    poultry_factor = ProvinceFactorToKillHouseForPoultry(
                        province_check_req=check,
                        total_weight=float(real_weight),
                        factor_fee=float(factor_fee),
                        real_weight=float(real_quantity),
                        out=True

                    )
                    poultry_factor.save()
                    if poultry_key != None:
                        if poultry_request.poultry.user_bank_info != None:
                            poultry_bank = BankCard.objects.get(
                                key=poultry_request.poultry.user_bank_info.key)
                            poultry_factor.bank = poultry_bank
                    poultry_factor.total_price = poultry_factor.total_weight * poultry_factor.factor_fee
                    poultry_factor.shares = {
                        "poultryShareWithProfit": poultry_factor.total_weight * poultry_factor.factor_fee,
                    }
                    poultry_factor.save()
                    poultry_factor.save()
                    province_factor = ProvinceFactorToKillHouse(
                        province_check_req=check,
                        total_weight=float(real_weight),
                        factor_fee=float(factor_fee),
                        real_weight=float(real_quantity),
                        out=True

                    )
                    province_factor.save()
                    financial_operator = ProvinceOperator.objects.filter(user__role__name='ProvinceFinancial',
                                                                         address__province=poultry_request.poultry.address.province)
                    if financial_operator.count() > 0:
                        financial_operator = financial_operator.last()
                        if financial_operator.user_bank_info != None:
                            province_bank = BankCard.objects.get(id=financial_operator.user_bank_info.id, trash=False)
                            province_factor.bank = province_bank
                    share_allocation = ShareOfAllocation.objects.all()
                    if share_allocation.count() > 0:
                        share_allocation = share_allocation.last()
                    percent = MonthlyProfitPercentage.objects.all().last()
                    percent = (percent.percent / 100) / percent.days
                    union = province_factor.total_weight * share_allocation.total
                    city_share = province_factor.total_weight * share_allocation.city_union
                    province_share = province_factor.total_weight * share_allocation.province_union
                    company_share = province_factor.total_weight * share_allocation.company
                    fanava_share = province_factor.total_weight * share_allocation.fanava
                    central_union_share = province_factor.total_weight * share_allocation.central_union
                    province_factor.total_price = (union * percent) + union
                    province_factor.shares = {
                        "unionShareWithProfit": (union * percent) + union,
                        "city_share": (city_share * percent) + city_share,
                        "province_share": (province_share * percent) + province_share,
                        "company_share": (company_share * percent) + company_share,
                        "fanava_share": (fanava_share * percent) + fanava_share,
                        "central_union_share": (central_union_share * percent) + central_union_share,
                    }
                    province_factor.poultry_factor = poultry_factor
                    province_factor.save()

                poultry_request.province_state = 'accepted'
                poultry_request.save()
                if key != None:
                    city_request.province_state = 'accept'
                message = UserMessage(
                    message="درخواست شما با کد سفارش {0} از طرف کارشناس استان {1} تایید شده است ".format(
                        poultry_request.order_code, user.fullname),
                    heading="پیام سیستم ثبت شده در تاریخ {0}".format(datetime.now()),
                    sender=user
                )
                message.save()
                message.users.add(poultry_request.poultry.user)
                if SmsLicense.objects.filter(province_approval=True).exists():
                    poultry_mobile = check.poultry_request.poultry.user.mobile
                    order_code = check.poultry_request.order_code
                    # poultry_request_receive_province_accept_sms(poultry_mobile, order_code
                    #                                             )
                    # sms_poultry_request_receive_province_accept_sms = threading.Thread(
                    #     target=poultry_request_receive_province_accept_sms,
                    #     args=(
                    #         poultry_mobile, order_code))
                    # sms_poultry_request_receive_province_accept_sms.start()

            if key != None:
                city_request.save()
            if poultry_request.out == True:
                poultry_request.final_state = 'archive'
                poultry_request.save()
            check_serializer = self.serializer_class(check)

            return Response(check_serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    # تابع مربوط به نمایش درخواست های تایید شده استان
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        info_dict = []
        info_list = []
        info_province_assignments_list = []
        if 'key' in request.GET:
            poultry_request = PoultryRequest.objects.get(key=request.GET['key'], trash=False)
            province_request = ProvinceCheckOperatorRequest.objects.filter(
                city_request_Poultry__poultry_request=poultry_request, trash=False
            )
            if province_request.count() > 0:
                province_request = province_request.last()
                send__date = province_request.city_request_Poultry.poultry_request.send_date
                kill_req = KillRequest.objects.filter(recive_date__year=send__date.year,
                                                      recive_date__month=send__date.month,
                                                      recive_date__day=send__date.day, trash=False)
                if kill_req:
                    is_car = True
                else:
                    is_car = False
                internal_dict_poultry = {
                    "id": province_request.city_request_Poultry.poultry_request.id,
                    "full_name": province_request.city_request_Poultry.poultry_request.poultry.user.fullname,
                    "city": province_request.city_request_Poultry.poultry_request.poultry.user.city.name,
                    "province": province_request.city_request_Poultry.poultry_request.poultry.user.province.name,
                    "mobile": province_request.city_request_Poultry.poultry_request.poultry.user.mobile,
                    "gis_code": province_request.city_request_Poultry.poultry_request.poultry.gis_code,
                    "poultry_request_quantity": province_request.city_request_Poultry.poultry_request.quantity,
                    "poultry_request_id": province_request.city_request_Poultry.poultry_request.id,
                    "poultry_request_inspector": province_request.city_request_Poultry.poultry_request.inspector,
                    "price": province_request.fee,
                    "date": province_request.city_request_Poultry.poultry_request.send_date,
                    "freezing": province_request.city_request_Poultry.poultry_request.freezing,
                    "register_date": province_request.city_request_Poultry.poultry_request.create_date,
                    "breed": province_request.city_request_Poultry.poultry_request.chicken_breed,
                    "order_code": province_request.city_request_Poultry.poultry_request.order_code,
                    "index_weight": province_request.city_request_Poultry.poultry_request.Index_weight,
                    "quantity": province_request.quantity,
                    "chicken_date": province_request.city_request_Poultry.poultry_request.poultry.incubation_date,
                    "age": (
                            datetime.now() - province_request.city_request_Poultry.poultry_request.hatching.date).days,
                    "key": province_request.key,
                    "is_car": is_car,
                    "province_assignments": "",
                    "kill_house_assignments": ""
                }
                if 'role' in request.GET:
                    if request.GET['role'] == 'KillHouse':
                        kill_house_operator = KillHouseOperator.objects.filter(user=user, trash=False)
                        if kill_house_operator.count() > 0:
                            kill_house_operator = kill_house_operator.last()
                            kill_house = KillHouse.objects.filter(kill_house_operator=kill_house_operator, trash=False)
                            province_kill_requests = ProvinceKillRequest.objects.filter(
                                province_request=province_request, killhouse_user__in=kill_house, trash=False)
                    elif request.GET['role'] == 'KillHouseVet':
                        vet = Vet.objects.filter(user=user, trash=False)
                        if vet.count() > 0:
                            vet = vet.last()
                            kill_house_vet = KillHouseVet.objects.filter(vet=vet)
                            kill_house_vet = kill_house_vet.last()
                            province_kill_requests = ProvinceKillRequest.objects.filter(
                                province_request=province_request, killhouse_user=kill_house_vet.kill_house,
                                trash=False)
                    else:
                        province_kill_requests = ProvinceKillRequest.objects.filter(
                            province_request=province_request, trash=False)
                    if province_kill_requests.count() > 0:
                        kill_house_check = None
                        for province_kill_request in province_kill_requests:
                            check = KillHouseCheckRequest.objects.filter(province_kill_request=province_kill_request)
                            if check.count() > 0:
                                kill_house_check = check.last().key
                            kill_house_reqs = True if KillHouseRequest.objects.filter(
                                province_kill_request=province_kill_request, trash=False) else False
                            bar = True if KillHouseAssignmentInformation.objects.filter(
                                kill_house_request__province_kill_request=province_kill_request, trash=False) else False
                            internal_dict_province_kill_request_infos = {
                                "province_kill_request_key": province_kill_request.key,
                                "automatic_state": province_kill_request.automatic,
                                "return_to_province": province_kill_request.return_to_province,
                                "kill_house_check_key": kill_house_check,
                                "payment_type": province_kill_request.payment_type,
                                "payment_dead_line": province_kill_request.payment_dead_line,
                                "kill_req_key": province_kill_request.kill_request.key,
                                "market": province_kill_request.kill_request.market,
                                "province_kill_request_state": province_kill_request.state,
                                "kill_house_key": province_kill_request.kill_request.kill_house.key,
                                "kill_house_name": province_kill_request.kill_request.kill_house.name,
                                "kill_house_user_name": province_kill_request.kill_request.kill_house.kill_house_operator.user.fullname,
                                "kill_house_user_city": province_kill_request.kill_request.kill_house.kill_house_operator.user.city.name,
                                "kill_house_mobile": province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
                                "quantity": province_kill_request.quantity,
                                "main_quantity": province_kill_request.main_quantity,
                                "time": province_kill_request.kill_request.recive_time,
                                "date": province_kill_request.kill_request.recive_date,
                                "province_kill_request_message": province_kill_request.message,
                                "kill_house_requests": kill_house_reqs,
                                "bar_information": bar,
                            }

                            info_province_assignments_list.append(internal_dict_province_kill_request_infos)

                        internal_dict_poultry["province_assignments"] = info_province_assignments_list
                    elif province_kill_requests.count() == 0:
                        internal_dict_poultry["province_assignments"] = None
                if 'role' in request.GET:
                    if request.GET['role'] == 'KillHouse':

                        kill_house_operator = KillHouseOperator.objects.filter(user=user, trash=False)
                        if kill_house_operator.count() > 0:
                            kill_house_operator = kill_house_operator.last()
                            kill_house = KillHouse.objects.filter(kill_house_operator=kill_house_operator, trash=False)
                            kill_house_requests = KillHouseRequest.objects.filter(
                                province_request=province_request, killhouse_user__in=kill_house, trash=False)
                    else:
                        kill_house_requests = KillHouseRequest.objects.filter(
                            province_request=province_request, trash=False)
                    if kill_house_requests.count() > 0:
                        for kill_house_req_obj in kill_house_requests:
                            internal_dict_infos = {
                                "kill_house_req_key": kill_house_req_obj.key,
                                "kill_req_key": kill_house_req_obj.kill_request.key,
                                "barcod": kill_house_req_obj.bar_code,
                                "kill_house_state": kill_house_req_obj.state,
                                "kill_house_name": kill_house_req_obj.kill_request.kill_house.name,
                                "kill_house_user_name": kill_house_req_obj.kill_request.kill_house.kill_house_operator.user.fullname,
                                "kill_house_user_city": kill_house_req_obj.kill_request.kill_house.kill_house_operator.user.city.name,
                                "kill_house_mobile": kill_house_req_obj.kill_request.kill_house.kill_house_operator.user.mobile,
                                "quantity": kill_house_req_obj.quantity,
                                "time": kill_house_req_obj.kill_request.recive_time,
                                "date": kill_house_req_obj.kill_request.recive_date,
                                "cars": kill_house_req_obj.car,
                                "show_kill_house": kill_house_req_obj.show_kill_house,
                                "kill_house_message": kill_house_req_obj.kill_house_message,
                            }

                            info_list.append(internal_dict_infos)

                        internal_dict_poultry["kill_house_assignments"] = info_list
                    elif kill_house_requests.count() == 0:
                        internal_dict_poultry["kill_house_assignments"] = None
                return Response(internal_dict_poultry, status=status.HTTP_200_OK)
            else:
                return Response([], status=status.HTTP_200_OK)

        province_requests = ProvinceCheckOperatorRequest.objects.filter(state='accept', end_state='active', trash=False
                                                                        ).order_by(
            'city_request_Poultry__poultry_request__send_date')

        for province_request in province_requests:
            send__date = province_request.city_request_Poultry.poultry_request.send_date
            kill_req = KillRequest.objects.filter(recive_date__year=send__date.year,
                                                  recive_date__month=send__date.month, recive_date__day=send__date.day,
                                                  trash=False)
            if kill_req:
                is_car = True
            else:
                is_car = False

            internal_dict_poultry = {
                "id": province_request.city_request_Poultry.poultry_request.id,
                "full_name": province_request.city_request_Poultry.poultry_request.user.fullname,
                "city": province_request.city_request_Poultry.poultry_request.user.address.city,
                "province": province_request.city_request_Poultry.poultry_request.user.address.province,
                "mobile": province_request.city_request_Poultry.poultry_request.user.mobile,
                "gis_code": province_request.city_request_Poultry.poultry_request.user.gis_code,
                "poultry_request_quantity": province_request.city_request_Poultry.poultry_request.quantity,
                "poultry_request_id": province_request.city_request_Poultry.poultry_request.id,
                "poultry_request_inspector": province_request.city_request_Poultry.poultry_request.inspector,
                "price": province_request.fee,
                "date": province_request.city_request_Poultry.poultry_request.send_date,
                "freezing": province_request.city_request_Poultry.poultry_request.freezing,
                "register_date": province_request.city_request_Poultry.poultry_request.create_date,
                "breed": province_request.city_request_Poultry.poultry_request.chicken_breed,
                "order_code": province_request.city_request_Poultry.poultry_request.order_code,
                "index_weight": province_request.city_request_Poultry.poultry_request.Index_weight,
                "quantity": province_request.quantity,
                "chicken_date": province_request.city_request_Poultry.poultry_request.user.incubation_date,
                "age": (
                               province_request.city_request_Poultry.poultry_request.send_date - province_request.city_request_Poultry.poultry_request.user.incubation_date).days + 2,
                "key": province_request.key,
                "is_car": is_car,
                "province_assignments": "",
                "Assignments": ""
            }

            for province_kill_request in ProvinceKillRequest.objects.filter(
                    province_request=province_request, trash=False):
                internal_dict_province_kill_request_infos = {
                    "province_kill_request_key": province_kill_request.key,
                    "automatic_state": province_kill_request.automatic,
                    "kill_req_key": province_kill_request.kill_request.key,
                    "market": province_kill_request.kill_request.market,
                    "province_kill_request_state": province_kill_request.state,
                    "kill_house_name": province_kill_request.kill_request.kill_house.name,
                    "kill_house_user_name": province_kill_request.kill_request.kill_house.user.fullname,
                    "kill_house_user_city": province_kill_request.kill_request.kill_house.user.address.city,
                    "kill_house_mobile": province_kill_request.kill_request.kill_house.user.mobile,
                    "quantity": province_kill_request.quantity,
                    "time": province_kill_request.kill_request.recive_time,
                    "date": province_kill_request.kill_request.recive_date,
                    "province_kill_request_message": province_kill_request.kill_house_message,
                }

                info_province_assignments_list.append(internal_dict_province_kill_request_infos)

            internal_dict_poultry["province_assignments"] = info_province_assignments_list

            for kill_house_req_obj in KillHouseRequest.objects.filter(
                    province_request=province_request, trash=False):
                internal_dict_infos = {
                    "kill_house_req_key": kill_house_req_obj.key,
                    "kill_req_key": kill_house_req_obj.kill_request.key,
                    "barcod": kill_house_req_obj.bar_code,
                    "kill_house_state": kill_house_req_obj.state,
                    "kill_house_name": kill_house_req_obj.kill_request.kill_house.name,
                    "kill_house_user_name": kill_house_req_obj.kill_request.kill_house.user.fullname,
                    "kill_house_user_city": kill_house_req_obj.kill_request.kill_house.user.address.city,
                    "kill_house_mobile": kill_house_req_obj.kill_request.kill_house.user.mobile,
                    "quantity": kill_house_req_obj.quantity,
                    "time": kill_house_req_obj.kill_request.recive_time,
                    "date": kill_house_req_obj.kill_request.recive_date,
                    "cars": kill_house_req_obj.car,
                    "show_kill_house": kill_house_req_obj.show_kill_house,
                    "kill_house_message": kill_house_req_obj.kill_house_message,
                }

                info_list.append(internal_dict_infos)

            internal_dict_poultry["Assignments"] = info_list
            # info_dict.update(internal_dict_poultry)
            info_dict.append(internal_dict_poultry)
            info_list = []

        return Response(info_dict, status=status.HTTP_200_OK)


# ویوست مربوط به تایید یا رد درخواست تایید شده شهرستان
class ProvinceRequestActionViewSet(viewsets.ModelViewSet):
    queryset = ProvinceRequestAction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceRequestActionSerializer

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

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        operator = ProvinceOperator.objects.get(user=user, trash=False)
        poultry_request = PoultryRequest.objects.get(key=request.data['poultry_request_key'], trash=False)
        auction_list = request.data['auction_list']
        request.data.pop('poultry_request_key')
        request.data.pop('auction_list')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            province_auction = serializer.create(validated_data=request.data)
            province_auction.poultry_request = poultry_request
            if len(auction_list) > 0:
                i = 0
                for auction in auction_list:
                    poultry_request_auction = PoultryRequestAuction(
                        poultry_request=poultry_request,
                        pricing=Pricing.objects.all(),
                        fee=auction['fee'],
                        hour=auction['hour']
                    )
                    poultry_request_auction.save()
                    poultry_auction = PoultryRequestAuction.objects.filter(poultry_request=poultry_request,
                                                                           state__in=('active', 'inactive'),
                                                                           trash=False).order_by(
                        'auction_date')
                    if poultry_auction.count() > 0:
                        if i == 0:
                            poultry_request_auction.auction_date = datetime.now() + timedelta(
                                hours=int(poultry_request_auction.hour))
                            poultry_request_auction.state = 'active'
                        else:
                            poultry_request_auction.auction_date = poultry_auction[i - 1].auction_date + timedelta(
                                hours=int(poultry_request_auction.hour))
                    i += 1
                    poultry_request_auction.save()

            poultry_request.auction = True
            poultry_request.save()
            province_auction.province_operator_system = operator
            province_auction.state = 'active'
            province_auction.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)


# ویوست مربوط به تایید یا رد اطلاعات بار وارد شده از سمت کشتارگاه
class ProvinceCheckInformationViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckInformation.objects.all()
    serializer_class = ProvinceCheckInformationSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به تایید یا رد اطلاعات بار وارد شده از سمت کشتارگاه
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)

        poultry_cost_wallet = 0
        city_cost_wallet = 0
        province_cost_wallet = 0
        kill_house_cost_wallet = 0
        if 'pay' in request.data.keys():
            pay = request.data['pay']
            request.data.pop('pay')
        else:
            if 'pay' in request.data.keys():
                request.data.pop('pay')
            pay = None

        if 'reason' in request.data.keys() and request.data['reason'] != None:
            reason = request.data['reason']
            request.data.pop('reason')
        else:
            if 'reason' in request.data.keys():
                request.data.pop('reason')
            reason = None

        if 'province_input_wage' in request.data.keys() and request.data['province_input_wage'] != None:
            province_input_wage = float(request.data['province_input_wage'])
            request.data.pop('province_input_wage')
        else:
            if 'province_input_wage' in request.data.keys():
                request.data.pop('province_input_wage')

            province_input_wage = None

        if 'province_input_amount' in request.data.keys() and 'province_input_amount_state' in request.data.keys() and \
                request.data['province_input_amount'] != None and request.data['province_input_amount_state'] != None:
            province_input_amount = float(request.data['province_input_amount'])
            request.data.pop('province_input_amount')
            province_input_amount_state = request.data['province_input_amount_state']
            request.data.pop('province_input_amount_state')
        else:
            if 'province_input_amount' in request.data.keys() and 'province_input_amount_state' in request.data.keys():
                request.data.pop('province_input_amount')
                request.data.pop('province_input_amount_state')

            province_input_amount = None
            province_input_amount_state = None

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        operator = ProvinceOperator.objects.get(user=user, trash=False)
        share_allocation = ShareOfAllocation.objects.all()
        if share_allocation.count() > 0:
            share_allocation = share_allocation.last()
            # total = share_allocation.total
        # else:
        #     total = 0

        kill_house_info = KillHouseAssignmentInformation.objects.get(key=request.data['kill_house_info_key'],
                                                                     trash=False)
        request.data.pop('kill_house_info_key')
        if 'bank' in request.data.keys():
            factor_person_type = request.data['bank']
            if request.data['bank'] == 'poultry':
                poultry = Poultry.objects.get(
                    key=kill_house_info.kill_house_request.province_request.poultry_request.poultry.key, trash=False)
                if poultry.user_bank_info != None:
                    bank = BankCard.objects.get(id=poultry.user_bank_info.id, trash=False)
                else:
                    return Response({"result": "اطلاعات مالی مرغدار وارد نشده است"}, status=status.HTTP_403_FORBIDDEN)
            elif request.data['bank'] == 'union':
                if operator.user_bank_info != None:
                    bank = BankCard.objects.get(id=operator.user_bank_info.id, trash=False)
                else:
                    return Response({"result": "اطلاعات مالی استان وارد نشده است"}, status=status.HTTP_403_FORBIDDEN)
            request.data.pop('bank')

        if 'real_weight' in request.data.keys():
            real_weight = float(request.data['real_weight'])
            request.data.pop('real_weight')
        else:
            real_weight = 0
        if 'fee' in request.data.keys():
            fee = request.data['fee']
            request.data.pop('fee')
        else:
            fee = 0

        if kill_house_info.kill_house_request.province_kill_request != None:
            province_check = kill_house_info.kill_house_check.province_kill_request.province_request
            pou_req = kill_house_info.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request
        else:
            province_check = None

        try:
            kill_house_image_without_load = request.data['kill_house_image_without_load']
            request.data.pop('kill_house_image_without_load')
        except:
            kill_house_image_without_load = None

        try:
            kill_house_image_with_load = request.data['kill_house_image_with_load']
            request.data.pop('kill_house_image_with_load')
        except:
            kill_house_image_with_load = None

        try:
            kill_house_car_weight_without_load = request.data['kill_house_car_weight_without_load']
            request.data.pop('kill_house_car_weight_without_load')

        except:
            kill_house_car_weight_without_load = None
        try:
            kill_house_car_weight_with_load = request.data['kill_house_car_weight_with_load']
            request.data.pop('kill_house_car_weight_with_load')

        except:
            kill_house_car_weight_with_load = None

        if KillHouseComplaint.objects.filter(bar=kill_house_info, state='pending').exists():
            return Response({"result": "can not create"}, status=status.HTTP_406_NOT_ACCEPTABLE)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            province_info = serializer.create(validated_data=request.data)
            province_info.kill_house_assignment = kill_house_info
            province_info.save()
            if province_info.state == 'accepted':
                kill_house_info.state = 'accepted'
                if kill_house_image_without_load != None:
                    kill_house_info.car_weight_without_load_image = send_image_to_server(kill_house_image_without_load)
                elif kill_house_image_with_load != None:
                    kill_house_info.car_weight_with_load_image = send_image_to_server(kill_house_image_with_load)
                elif kill_house_car_weight_without_load != None:
                    kill_house_info.car_weight_without_load = kill_house_car_weight_without_load
                elif kill_house_car_weight_with_load != None:
                    kill_house_info.car_weight_with_load = kill_house_car_weight_with_load
                kill_house_info.save()
                if pay == 'together':
                    province_info.kill_house_assignment = kill_house_info
                    province_info.save()
                    if province_check != None:
                        if KillHouseComplaint.objects.filter(state='accepted', bar=kill_house_info).exists():
                            t_weight = kill_house_info.weight_withs_losses
                        else:
                            t_weight = kill_house_info.net_weight

                        list1 = KillHouseRequest.objects.filter(
                            province_kill_request=kill_house_info.kill_house_request.province_kill_request)

                        factor = ProvinceFactorToKillHouse(
                            province_check_info=province_info,
                            total_weight=t_weight,
                            factor_fee=float(fee),
                            factor_person_type=factor_person_type,
                            # factor_fee=kill_house_info.kill_house_check.province_kill_request.fee,
                            factor_date=kill_house_info.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.send_date,
                            factor_bar_code=kill_house_info.kill_house_request.bar_code,
                            real_weight=real_weight,
                            province_check_req=kill_house_info.kill_house_check.province_kill_request.province_request,
                        )
                        factor.save()
                        province_factors_count = 0
                        poultry_factors_count = 0
                        total_count = 0
                        province_factors_counter = 0
                        province_factors = ProvinceFactorToKillHouse.objects.filter(
                            province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request,
                            poultry_factor__isnull=True)
                        poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                            province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request)
                        if province_factors.count() > 0:
                            province_factors_count = province_factors.count()
                        if poultry_factors.count() > 0:
                            poultry_factors_count = poultry_factors.count()
                            for poultry in poultry_factors:
                                if ProvinceFactorToKillHouse.objects.filter(poultry_factor=poultry).exists():
                                    province_factors_counter += 1
                        if poultry_factors_count == province_factors_counter or province_factors_counter == 0:
                            total_count = province_factors_count + poultry_factors_count
                        if province_factors_counter > 0:
                            if poultry_factors_count > 0:
                                poultry_factors_count -= province_factors_counter
                                total_count = province_factors_count + poultry_factors_count
                            else:
                                total_count = province_factors_count
                        if bank != None:
                            factor.bank = bank
                            factor.save()
                        province_check.total_weight_at_end += factor.total_weight
                        province_check.save()
                        province_info.save()
                        province_kill_req = ProvinceKillRequest.objects.get(
                            key=kill_house_info.kill_house_check.province_kill_request.key)

                        province_kill_req.fee = fee
                        if province_kill_req.payment_type == 'credit':
                            percent = MonthlyProfitPercentage.objects.all().last()
                            percent = (percent.percent / 100) / percent.days
                            total = factor.total_weight * factor.factor_fee
                            union = factor.total_weight * share_allocation.total
                            city_share = factor.total_weight * share_allocation.city_union
                            province_share = factor.total_weight * share_allocation.province_union
                            company_share = factor.total_weight * share_allocation.company
                            fanava_share = factor.total_weight * share_allocation.fanava
                            central_union_share = factor.total_weight * share_allocation.central_union
                            factor.total_price = ((total + union) * percent) + (total + union)
                            factor.shares = {
                                "poultryShareWithProfit": (total * percent) + total,
                                "unionShareWithProfit": (union * percent) + union,
                                "city_share": (city_share * percent) + city_share,
                                "province_share": (province_share * percent) + province_share,
                                "company_share": (company_share * percent) + company_share,
                                "fanava_share": (fanava_share * percent) + fanava_share,
                                "central_union_share": (central_union_share * percent) + central_union_share,
                            }
                            factor.save()
                            # factor.today_price = total +
                            if list1.count() > 0 and total_count > 0:
                                if list1.count() == total_count:
                                    dead_line = PaymentDeadLine.objects.all().last()
                                    province_kill_req.payment_dead_line = datetime.now().date() + timedelta(
                                        days=dead_line.days)
                        else:
                            if province_input_wage != None:
                                province_share_allocation = province_input_wage
                                factor.province_wage = province_input_wage
                            else:
                                province_share_allocation = share_allocation.total
                                factor.province_wage = share_allocation.total
                            if province_input_amount != None:
                                if province_input_amount_state != None and province_input_amount_state == 'decrease':
                                    factor.total_price = (factor.total_weight * factor.factor_fee) + (
                                            factor.total_weight * province_share_allocation) - province_input_amount
                                    factor.province_input_amount_type = 'decrease'
                                    factor.province_input_amount = province_input_amount
                                else:
                                    factor.total_price = (factor.total_weight * factor.factor_fee) + (
                                            factor.total_weight * province_share_allocation) + province_input_amount
                                    factor.province_input_amount_type = 'plus'
                                    factor.province_input_amount = province_input_amount
                                if reason != None:
                                    factor.reason = reason

                            else:
                                factor.total_price = (factor.total_weight * factor.factor_fee) + (
                                        factor.total_weight * province_share_allocation)
                            kill_request_sms_payment = KillRequest.objects.filter(
                                key=kill_house_info.kill_house_check.province_kill_request.kill_request.key)
                            if kill_request_sms_payment.count() > 0:
                                kill_request_sms_payment = kill_request_sms_payment.last()
                                if kill_request_sms_payment.sms_payment == True:
                                    factor.total_price += 50000
                            factor.shares = {
                                "poultryShareWithProfit": factor.total_weight * factor.factor_fee,
                                "unionShareWithProfit": factor.total_weight * province_share_allocation,
                                "poultry_share": factor.total_weight * factor.factor_fee,
                                "city_share": 0,
                                "province_share": factor.total_weight * province_share_allocation,
                                "company_share": 0,
                                "fanava_share": 0,
                                "central_union_share": 0,
                                # "city_share": factor.total_weight * share_allocation.city_union,
                                # "province_share": factor.total_weight * share_allocation.province_union,
                                # "company_share": factor.total_weight * share_allocation.company,
                                # "fanava_share": factor.total_weight * share_allocation.fanava,
                                # "central_union_share": factor.total_weight * share_allocation.central_union,
                            }
                            factor.save()

                        province_kill_req.save()
                        poultry_cost_wallet = factor.shares['poultryShareWithProfit']
                        city_cost_wallet = factor.shares['city_share']
                        province_cost_wallet = factor.shares['province_share']
                        kill_house_cost_wallet = factor.shares['poultryShareWithProfit'] + factor.shares[
                            'unionShareWithProfit']

                    else:
                        factor = ProvinceFactorToKillHouse(
                            province_check_info=province_info,
                            total_weight=kill_house_info.net_weight,
                            factor_fee=float(fee),
                            # factor_fee=kill_house_info.kill_house_request.kill_house_request_auction_winner.fee,
                            factor_date=kill_house_info.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.poultry_request.send_date,
                            factor_bar_code=kill_house_info.kill_house_request.bar_code,
                            real_weight=real_weight,
                            province_check_req=kill_house_info.kill_house_check.province_kill_request.province_request,

                        )
                        factor.save()
                        if bank != None:
                            factor.bank = bank
                        factor.total_price = (factor.total_weight * factor.factor_fee) + (
                                factor.total_weight * share_allocation.total)
                        factor.save()
                        province_info.province_operator = operator
                        province_info.save()
                        auction_winner = KillHouseRequestActionWinner.objects.get(
                            key=kill_house_info.kill_house_request.kill_house_request_auction_winner.key)
                        auction_winner.fee = fee
                        auction_winner.save()

                    province_factors_count = 0
                    poultry_factors_count = 0
                    total_count = 0
                    province_factors_counter = 0
                    kill_house_requests = KillHouseRequest.objects.filter(
                        province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request)
                    province_factors = ProvinceFactorToKillHouse.objects.filter(
                        province_check_info__kill_house_assignment__kill_house_request__province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request,
                        poultry_factor__isnull=True)
                    poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                        province_check_info__kill_house_assignment__kill_house_request__province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request)
                    if province_factors.count() > 0:
                        province_factors_count = province_factors.count()
                    if poultry_factors.count() > 0:
                        poultry_factors_count = poultry_factors.count()
                        for poultry in poultry_factors:
                            if ProvinceFactorToKillHouse.objects.filter(poultry_factor=poultry).exists():
                                province_factors_counter += 1
                    if poultry_factors_count == province_factors_counter or province_factors_counter == 0:
                        total_count = province_factors_count + poultry_factors_count
                    if province_factors_counter > 0:
                        if poultry_factors_count > 0:
                            poultry_factors_count -= province_factors_counter
                            total_count = province_factors_count + poultry_factors_count
                        else:
                            total_count = province_factors_count

                    if kill_house_requests.count() == total_count:
                        poultry_request = PoultryRequest.objects.get(
                            key=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request.key)
                        poultry_request.awaiting_payment = True
                        poultry_request.save()
                    poultry_wallet = pou_req.poultry.wallet
                    city_wallet = CityOperator.objects.get(key=pou_req.city_operator.key).wallet
                    province_wallet = operator.wallet

                    poultry_transaction = Itransaction(
                        wallet=pou_req.poultry.wallet,
                        transfer_amount=poultry_cost_wallet,
                        transaction_type='creditor',
                        payment_code=kill_house_info.kill_house_request.bar_code,
                        file_id=pou_req.id,
                    )
                    poultry_transaction.save()
                    # poultry_wallet.inventory += poultry_transaction.transfer_amount
                    # poultry_wallet.save()

                    kill_housse_wallet = kill_house_info.kill_house_request.province_kill_request.kill_request.kill_house.kill_house_operator.wallet
                    kill_house_transaction = Itransaction(
                        wallet=kill_housse_wallet,
                        transfer_amount=kill_house_cost_wallet,
                        transaction_type='debtor',
                        payment_code=kill_house_info.kill_house_request.bar_code,
                        file_id=pou_req.id,

                    )
                    kill_house_transaction.save()
                    # kill_housse_wallet.inventory -= kill_house_transaction.transfer_amount
                    # kill_housse_wallet.save()

                    if city_cost_wallet > 0 and province_cost_wallet > 0:
                        city_transaction = Itransaction(
                            wallet=city_wallet,
                            transfer_amount=city_cost_wallet,
                            transaction_type='creditor',
                            payment_code=kill_house_info.kill_house_request.bar_code,
                            file_id=pou_req.id,

                        )
                        city_transaction.save()
                        # city_wallet.inventory += city_transaction.transfer_amount
                        # city_wallet.save()

                        province_transaction = Itransaction(
                            wallet=province_wallet,
                            transfer_amount=province_cost_wallet,
                            transaction_type='creditor',
                            payment_code=kill_house_info.kill_house_request.bar_code,
                            file_id=pou_req.id,

                        )
                        province_transaction.save()
                        # province_wallet.inventory += city_transaction.transfer_amount
                        # province_wallet.save()
                    if factor.total_price == 0:
                        kill_house_factor = KillHouseFactorToProvince(
                            province_factor=factor,
                            importer='ProvinceOperator',
                            first_payment=True,
                        )
                        kill_house_factor.save()
                        factor.kill_house_factor_info = 'accepted'
                        factor.paid_state = 'paid'
                        factor.decreasing_amount = factor.total_price

                        factor.save()
                    else:
                        kill_house_factor_payment = KillRequestFactorPayment.objects.filter(
                            kill_request_factor__kill_request=kill_house_info.kill_house_check.province_kill_request.kill_request)

                        if kill_house_factor_payment.count() > 0:
                            kill_house_factor_payment = kill_house_factor_payment.last()
                            factor.kill_house_factor_payment = kill_house_factor_payment.remain_amount
                            factor.save()
                            if factor.total_price > kill_house_factor_payment.remain_amount and kill_house_factor_payment.remain_amount > 0:
                                factor.previous_amount = factor.total_price
                                factor.decreasing_amount = kill_house_factor_payment.remain_amount
                                factor.total_price -= kill_house_factor_payment.remain_amount
                                kill_house = KillHouse.objects.get(
                                    key=kill_house_info.kill_house_check.province_kill_request.kill_request.kill_house.key)
                                kill_house.wallet_amount -= kill_house_factor_payment.remain_amount
                                kill_house.save()
                                kill_house_factor_payment.remain_amount = 0
                                kill_house_factor_payment.save()

                            else:

                                kill_house_factor = KillHouseFactorToProvince(
                                    province_factor=factor,
                                    payment_code=kill_house_factor_payment.payment_code,
                                    factor_image=kill_house_factor_payment.image,
                                    importer='ProvinceOperator',
                                    first_payment=True,
                                )
                                kill_house_factor.save()
                                factor.kill_house_factor_info = 'accepted'
                                factor.paid_state = 'paid'
                                factor.decreasing_amount = factor.total_price

                                factor.save()
                                kill_house = KillHouse.objects.get(
                                    key=kill_house_info.kill_house_check.province_kill_request.kill_request.kill_house.key)
                                kill_house.wallet_amount -= factor.total_price
                                kill_house.save()
                                kill_house_factor_payment.remain_amount -= factor.total_price
                                kill_house_factor_payment.save()

                    province_info_serializer = self.serializer_class(province_info)
                    return Response(province_info_serializer.data, status=status.HTTP_201_CREATED)

                else:
                    if province_check != None:
                        if KillHouseComplaint.objects.filter(state='accepted', bar=kill_house_info).exists():
                            t_weight = kill_house_info.weight_withs_losses
                        else:
                            t_weight = kill_house_info.net_weight
                        # list1 = KillHouseRequest.objects.filter(
                        #     province_kill_request=kill_house_info.kill_house_request.province_kill_request)

                        poultry_factor = ProvinceFactorToKillHouseForPoultry(
                            province_check_info=province_info,
                            total_weight=t_weight,
                            factor_fee=float(fee),
                            # factor_fee=kill_house_info.kill_house_check.province_kill_request.fee,
                            factor_date=kill_house_info.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.send_date,
                            factor_bar_code=kill_house_info.kill_house_request.bar_code,
                            real_weight=real_weight,
                            province_check_req=kill_house_info.kill_house_check.province_kill_request.province_request,

                        )
                        poultry_factor.save()
                        if province_check.city_request_Poultry.poultry_request.poultry.user_bank_info != None:
                            poultry_bank = BankCard.objects.get(
                                key=province_check.city_request_Poultry.poultry_request.poultry.user_bank_info.key)
                            poultry_factor.bank = poultry_bank
                            poultry_factor.save()
                        # province_factors_count = 0
                        # poultry_factors_count = 0
                        # total_count = 0
                        # province_factors_counter = 0
                        # province_factors = ProvinceFactorToKillHouse.objects.filter(
                        #     province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request)
                        # # poultry_factor__isnull=True)
                        # poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                        #     province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request)
                        # if province_factors.count() > 0:
                        #     province_factors_count = province_factors.count()
                        # if poultry_factors.count() > 0:
                        #     poultry_factors_count = poultry_factors.count()
                        #     for poultry in poultry_factors:
                        #         if ProvinceFactorToKillHouse.objects.filter(poultry_factor=poultry).exists():
                        #             province_factors_counter += 1
                        #
                        # if poultry_factors_count == province_factors_counter or province_factors_counter == 0:
                        #     if poultry_factors_count == province_factors_counter and poultry_factors_count != 0:
                        #         if province_factors_count == province_factors_counter:
                        #             total_count = poultry_factors_count
                        #         elif province_factors_count > province_factors_counter:
                        #             total_count = poultry_factors_count + (
                        #                     province_factors_count - province_factors_counter)
                        # total_count = province_factors_count + poultry_factors_count
                        # if province_factors_counter > 0:
                        #     if poultry_factors_count > 0:
                        #         poultry_factors_count -= province_factors_counter
                        #         total_count = province_factors_count + poultry_factors_count
                        #     else:
                        #         total_count = province_factors_count

                        province_kill_req = ProvinceKillRequest.objects.get(
                            key=kill_house_info.kill_house_check.province_kill_request.key)

                        if province_kill_req.payment_type == 'credit':
                            percent = MonthlyProfitPercentage.objects.all().last()
                            percent = (percent.percent / 100) / percent.days
                            total = poultry_factor.total_weight * poultry_factor.factor_fee
                            poultry_factor.total_price = (total * percent) + total
                            poultry_factor.shares = {
                                "poultryShareWithProfit": (total * percent) + total,
                            }
                            poultry_factor.save()

                            # if list1.count() > 0 and total_count > 0:
                            #     if list1.count() == total_count:
                            if province_kill_req.payment_dead_line == None:
                                dead_line = PaymentDeadLine.objects.all().last()
                                province_kill_req.payment_dead_line = datetime.now().date() + timedelta(
                                    days=dead_line.days)
                        else:
                            poultry_factor.total_price = (poultry_factor.total_weight * poultry_factor.factor_fee)
                            poultry_factor.shares = {
                                "poultryShareWithProfit": poultry_factor.total_weight * poultry_factor.factor_fee,
                            }
                            poultry_factor.save()
                            province_check.save()
                            province_info.save()
                        poultry_cost_wallet = poultry_factor.shares['poultryShareWithProfit']
                        kill_house_cost_wallet = poultry_factor.shares['poultryShareWithProfit']
                        if share_allocation.total != 0:
                            if KillHouseComplaint.objects.filter(state='accepted', bar=kill_house_info).exists():
                                t_weight = kill_house_info.weight_withs_losses
                            else:
                                t_weight = kill_house_info.net_weight
                            factor = ProvinceFactorToKillHouse(
                                province_check_info=province_info,
                                total_weight=t_weight,
                                factor_fee=float(fee),
                                # factor_fee=kill_house_info.kill_house_check.province_kill_request.fee,
                                factor_date=kill_house_info.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.send_date,
                                factor_bar_code=kill_house_info.kill_house_request.bar_code,
                                real_weight=real_weight,
                                province_check_req=kill_house_info.kill_house_check.province_kill_request.province_request,
                            )
                            factor.save()
                            # province_factors_count = 0
                            # poultry_factors_count = 0
                            # total_count = 0
                            # province_factors_counter = 0
                            # province_factors = ProvinceFactorToKillHouse.objects.filter(
                            #     province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request)
                            # # poultry_factor__isnull=True)
                            # poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                            #     province_check_info__kill_house_assignment__kill_house_request__province_kill_request=kill_house_info.kill_house_request.province_kill_request)
                            # if province_factors.count() > 0:
                            #     province_factors_count = province_factors.count()
                            # if poultry_factors.count() > 0:
                            #     poultry_factors_count = poultry_factors.count()
                            #     for poultry in poultry_factors:
                            #         if ProvinceFactorToKillHouse.objects.filter(poultry_factor=poultry).exists():
                            #             province_factors_counter += 1
                            # if poultry_factors_count == province_factors_counter or province_factors_counter == 0:
                            #     if poultry_factors_count == province_factors_counter and poultry_factors_count != 0:
                            #         if province_factors_count == province_factors_counter:
                            #             total_count = poultry_factors_count
                            #         elif province_factors_count > province_factors_counter:
                            #             total_count = poultry_factors_count + (
                            #                     province_factors_count - province_factors_counter)

                            # total_count = province_factors_count + poultry_factors_count
                            # if province_factors_counter > 0:
                            #     if poultry_factors_count > 0:
                            #         poultry_factors_count -= province_factors_counter
                            #         total_count = province_factors_count + poultry_factors_count
                            #     else:
                            #         total_count = province_factors_count

                            if bank != None:
                                factor.bank = bank
                                factor.save()
                            province_check.total_weight_at_end += factor.total_weight
                            province_check.save()
                            province_info.save()
                            province_kill_req = ProvinceKillRequest.objects.get(
                                key=kill_house_info.kill_house_check.province_kill_request.key)
                            province_kill_req.fee = fee
                            if province_kill_req.payment_type == 'credit':
                                percent = MonthlyProfitPercentage.objects.all().last()
                                percent = (percent.percent / 100) / percent.days
                                union = factor.total_weight * share_allocation.total
                                city_share = factor.total_weight * share_allocation.city_union
                                province_share = factor.total_weight * share_allocation.province_union
                                company_share = factor.total_weight * share_allocation.company
                                fanava_share = factor.total_weight * share_allocation.fanava
                                central_union_share = factor.total_weight * share_allocation.central_union
                                factor.total_price = (union * percent) + union
                                factor.shares = {
                                    "unionShareWithProfit": (union * percent) + union,
                                    "city_share": (city_share * percent) + city_share,
                                    "province_share": (province_share * percent) + province_share,
                                    "company_share": (company_share * percent) + company_share,
                                    "fanava_share": (fanava_share * percent) + fanava_share,
                                    "central_union_share": (central_union_share * percent) + central_union_share,
                                }
                                factor.poultry_factor = poultry_factor
                                factor.save()
                                # factor.today_price = total +

                                # if list1.count() > 0 and total_count > 0:
                                #     if list1.count() == total_count:
                                if province_kill_req.payment_dead_line == None:
                                    dead_line = PaymentDeadLine.objects.all().last()
                                    province_kill_req.payment_dead_line = datetime.now().date() + timedelta(
                                        days=dead_line.days)
                            else:
                                factor.total_price = factor.total_weight * share_allocation.total
                                factor.shares = {
                                    "unionShareWithProfit": factor.total_weight * share_allocation.total,
                                    "city_share": factor.total_weight * share_allocation.city_union,
                                    "province_share": factor.total_weight * share_allocation.province_union,
                                    "company_share": factor.total_weight * share_allocation.company,
                                    "fanava_share": factor.total_weight * share_allocation.fanava,
                                    "central_union_share": factor.total_weight * share_allocation.central_union,
                                }
                                factor.poultry_factor = poultry_factor
                                factor.save()
                            kill_house_cost_wallet += factor.shares['unionShareWithProfit']
                            city_cost_wallet = factor.shares['city_share']
                            province_cost_wallet = factor.shares['province_share']
                        province_info.save()
                        province_kill_req.save()

                    else:
                        factor = ProvinceFactorToKillHouse(
                            province_check_info=province_info,
                            total_weight=kill_house_info.net_weight,
                            factor_fee=float(fee),
                            # factor_fee=kill_house_info.kill_house_request.kill_house_request_auction_winner.fee,
                            factor_date=kill_house_info.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.poultry_request.send_date,
                            factor_bar_code=kill_house_info.kill_house_request.bar_code,
                            real_weight=real_weight,

                        )
                        factor.save()
                        if bank != None:
                            factor.bank = bank
                        factor.total_price = (factor.total_weight * factor.factor_fee) + (
                                factor.total_weight * share_allocation.total)
                        factor.save()
                        province_info.province_operator = operator
                        province_info.save()
                        auction_winner = KillHouseRequestActionWinner.objects.get(
                            key=kill_house_info.kill_house_request.kill_house_request_auction_winner.key)
                        auction_winner.fee = fee
                        auction_winner.save()

                    province_factors_count = 0
                    poultry_factors_count = 0
                    total_count = 0
                    province_factors_counter = 0
                    kill_house_requests = KillHouseRequest.objects.filter(
                        province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request)
                    province_factors = ProvinceFactorToKillHouse.objects.filter(
                        province_check_info__kill_house_assignment__kill_house_request__province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request,
                        poultry_factor__isnull=True)
                    poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                        province_check_info__kill_house_assignment__kill_house_request__province_kill_request__province_request__city_request_Poultry__poultry_request=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request)
                    if province_factors.count() > 0:
                        province_factors_count = province_factors.count()
                    if poultry_factors.count() > 0:
                        poultry_factors_count = poultry_factors.count()
                        for poultry in poultry_factors:
                            if ProvinceFactorToKillHouse.objects.filter(poultry_factor=poultry).exists():
                                province_factors_counter += 1
                    if poultry_factors_count == province_factors_counter or province_factors_counter == 0:
                        total_count = province_factors_count + poultry_factors_count
                    if province_factors_counter > 0:
                        if poultry_factors_count > 0:
                            poultry_factors_count -= province_factors_counter
                            total_count = province_factors_count + poultry_factors_count
                        else:
                            total_count = province_factors_count

                    if kill_house_requests.count() == total_count:
                        poultry_request = PoultryRequest.objects.get(
                            key=kill_house_info.kill_house_request.province_kill_request.province_request.city_request_Poultry.poultry_request.key)
                        poultry_request.awaiting_payment = True
                        poultry_request.save()
                    poultry_wallet = pou_req.poultry.wallet
                    city_wallet = CityOperator.objects.get(key=pou_req.city_operator.key).wallet
                    province_wallet = operator.wallet

                    poultry_transaction = Itransaction(
                        wallet=pou_req.poultry.wallet,
                        transfer_amount=poultry_cost_wallet,
                        transaction_type='creditor',
                        payment_code=kill_house_info.kill_house_request.bar_code,
                        file_id=pou_req.id,

                    )
                    poultry_transaction.save()
                    # poultry_wallet.inventory += poultry_transaction.transfer_amount
                    # poultry_wallet.save()

                    kill_housse_wallet = kill_house_info.kill_house_request.province_kill_request.kill_request.kill_house.kill_house_operator.wallet
                    kill_house_transaction = Itransaction(
                        wallet=kill_housse_wallet,
                        transfer_amount=kill_house_cost_wallet,
                        transaction_type='debtor',
                        payment_code=kill_house_info.kill_house_request.bar_code,
                        file_id=pou_req.id,

                    )
                    kill_house_transaction.save()
                    # kill_housse_wallet.inventory -= kill_house_transaction.transfer_amount
                    # kill_housse_wallet.save()

                    if city_cost_wallet > 0 and province_cost_wallet > 0:
                        city_transaction = Itransaction(
                            wallet=city_wallet,
                            transfer_amount=city_cost_wallet,
                            transaction_type='creditor',
                            payment_code=kill_house_info.kill_house_request.bar_code,
                            file_id=pou_req.id,

                        )
                        city_transaction.save()
                        # city_wallet.inventory += city_transaction.transfer_amount
                        # city_wallet.save()

                        province_transaction = Itransaction(
                            wallet=province_wallet,
                            transfer_amount=province_cost_wallet,
                            transaction_type='creditor',
                            payment_code=kill_house_info.kill_house_request.bar_code,
                            file_id=pou_req.id,

                        )
                        province_transaction.save()
                        # province_wallet.inventory += city_transaction.transfer_amount
                        # province_wallet.save()

                    province_info_serializer = self.serializer_class(province_info)
                    return Response(province_info_serializer.data, status=status.HTTP_201_CREATED)



            elif province_info.state == 'rejected':
                kill_house_info.state = 'rejected'
                kill_house_info.message = province_info.message
                kill_house_info.save()
                # province_check.save()
                province_info.province_operator = operator
                province_info.save()
                province_info_serializer = self.serializer_class(province_info)
                return Response(province_info_serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors)

    # تابع مربوط به نمایش  اطلاعات بار وارد شده از سمت کشتارگاه
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)

        province_operator = UserProfile.objects.get(user=request.user, trash=False)
        # info_dict = {}
        info_dict = []
        info_list = []
        province_requests = ProvinceCheckOperatorRequest.objects.filter(state='accept', end_state='active', trash=False)

        for province_request in province_requests:
            internal_dict_poultry = {
                "id": province_request.city_request_Poultry.poultry_request.id,
                "full_name": province_request.city_request_Poultry.poultry_request.user.fullname,
                "mobile": province_request.city_request_Poultry.poultry_request.user.mobile,
                "poultry_request_quantity": province_request.city_request_Poultry.poultry_request.quantity,
                "price": province_request.fee,
                "date": province_request.city_request_Poultry.poultry_request.send_date,
                "breed": province_request.city_request_Poultry.poultry_request.chicken_breed,
                "order_code": province_request.city_request_Poultry.poultry_request.order_code,
                "informations": ""
            }
            for kill_house_req_obj in KillHouseRequest.objects.filter(state='accepted', active_state='active',
                                                                      province_request=province_request, trash=False):
                province_req = kill_house_req_obj.province_request

                kill_house_assignment = KillHouseAssignmentInformation.objects.filter(
                    kill_house_check__province_kill_request__province_request=province_req, trash=False)
                # poultry_assignment = PoultryAssignmentInformation.objects.filter(
                #     kill_house_check_poultry__kill_house_request__bar_code=kill_house_req_obj.bar_code)
                if kill_house_assignment:
                    # return Response (kill_house_assignment[0].car_weight_without_load)
                    internal_dict_infos = {
                        "barcod": kill_house_req_obj.bar_code,
                        "kill_house_state": kill_house_req_obj.state,
                        "kill_house_name": kill_house_req_obj.kill_request.kill_house.name,
                        "kill_house_user_name": kill_house_req_obj.kill_request.kill_house.user.fullname,
                        "kill_house_mobile": kill_house_req_obj.kill_request.kill_house.user.mobile,
                        "quantity": kill_house_req_obj.quantity,
                        "time": kill_house_req_obj.kill_request.recive_time,
                        "date": kill_house_req_obj.kill_request.recive_date,
                        "cars": kill_house_req_obj.car,
                        "kill_house_assigment_key": kill_house_assignment[0].key,
                        "kill_house_assigment_state": kill_house_assignment[0].state,
                        "kill_house_weight_without_load": kill_house_assignment[0].car_weight_without_load,
                        "kill_house_weight_with_load": kill_house_assignment[0].car_weight_with_load,
                        "kill_house_image_without_load": kill_house_assignment[0].car_weight_without_load_image,
                        "kill_house_image_with_load": kill_house_assignment[0].car_weight_with_load_image,
                        "kill_house_net_weight": kill_house_assignment[0].net_weight,
                    }
                    if kill_house_assignment[0].state == 'accepted':
                        province_check_info = ProvinceCheckInformation.objects.get(
                            kill_house_assignment=kill_house_assignment[0],
                            state='accepted', trash=False)
                        internal_dict_infos.update({"province_operator": province_operator.fullname,
                                                    "date_of_registration": province_check_info.create_date})

                    info_list.append(internal_dict_infos)

                if not kill_house_assignment:
                    internal_dict_infos = {
                        "barcod": kill_house_req_obj.bar_code,
                        "kill_house_state": kill_house_req_obj.state,
                        "kill_house_name": kill_house_req_obj.kill_request.kill_house.name,
                        "kill_house_user_name": kill_house_req_obj.kill_request.kill_house.user.fullname,
                        "kill_house_mobile": kill_house_req_obj.kill_request.kill_house.user.mobile,
                        "quantity": kill_house_req_obj.quantity,
                        "time": kill_house_req_obj.kill_request.recive_time,
                        "date": kill_house_req_obj.kill_request.recive_date,
                        "cars": kill_house_req_obj.car,
                        "kill_house_assigment_key": "",
                        "poultry_assigment_key": "",
                        "kill_house_weight_without_load": "",
                        "kill_house_weight_with_load": "",
                        "poultry_weight_without_load": "",
                        "poultry_weight_with_load": "",
                        "kill_house_image_without_load": "",
                        "kill_house_image_with_load": "",
                        "poultry_image_without_load": "",
                        "poultry_image_with_load": "",
                        "kill_house_net_weight": "",
                        "poultry_net_weight": ""
                    }
                    info_list.append(internal_dict_infos)

            internal_dict_poultry["informations"] = info_list
            info_dict.append(internal_dict_poultry)
            info_list = []

        return Response(info_dict, status=status.HTTP_200_OK)


class ProvinceFactorToKillHouseForPoultryViewSet(viewsets.ModelViewSet):
    queryset = ProvinceFactorToKillHouseForPoultry.objects.all()
    serializer_class = ProvinceFactorToKillHouseForPoultrySerializer
    permission_classes = [TokenHasReadWriteScope]


# ویوست مربوط به فاکتور استان برای کشتارگاه
class ProvinceFactorToKillHouseViewSet(viewsets.ModelViewSet):
    queryset = ProvinceFactorToKillHouse.objects.all()
    serializer_class = ProvinceFactorToKillHouseSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به نمایش فاکتور استان برای کشتارگاه
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user)

        if 'role' in request.GET:
            if request.GET['role'] == 'KillHouse':
                now = datetime.now().date()
                date1 = datetime.strptime(str(request.GET['date1']),
                                          '%Y-%m-%d').date() if 'date1' in request.GET else now
                date2 = datetime.strptime(str(request.GET['date2']),
                                          '%Y-%m-%d').date() if 'date2' in request.GET else now
                factors = []
                operator = KillHouseOperator.objects.get(user=user)
                kill_house = KillHouse.objects.filter(kill_house_operator=operator)
                factor_list = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__killhouse_user__in=kill_house)
                factors = [
                    factor for factor in factor_list
                    if date1 <= factor.province_check_req.poultry_request.send_date.date() <= date2
                ]
                factor_serializer = self.serializer_class(factors, many=True)
                return Response(factor_serializer.data, status=status.HTTP_200_OK)
            elif request.GET['role'] == 'ProvinceFinancial':
                factors = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__killhouse_user__system_address__province=user.province,
                    paid_state='pending')
                factor_serializer = self.serializer_class(factors, many=True)
                return Response(factor_serializer.data, status=status.HTTP_200_OK)

            elif request.GET['role'] == 'ProvinceOperator':

                factors = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__killhouse_user__system_address__province=user.province,
                    paid_state='pending')
                factor_serializer = self.serializer_class(factors, many=True)
                return Response(factor_serializer.data, status=status.HTTP_200_OK)


            elif request.GET['role'] == 'CityOperator':
                factors = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_request__killhouse_user__system_address__city=user.city,
                    paid_state='pending')
                factor_serializer = self.serializer_class(factors, many=True)
                return Response(factor_serializer.data, status=status.HTTP_200_OK)

            elif request.GET['role'] == 'Poultry':

                factors = ProvinceFactorToKillHouse.objects.filter(
                    province_check_req__poultry_request__poultry__user=user,
                    paid_state='pending', trash=False)
                factor_serializer = self.serializer_class(factors, many=True)
                return Response(factor_serializer.data, status=status.HTTP_200_OK)

        if request.GET['type'] == 'kill_house':
            key = request.GET['key']
            # user = UserProfile.objects.get(user=request.user)
            # # kill_house = KillHouse.objects.get(user=user)
            # # factor_dict_list = []
            factor_list = []
            provinc_factor_to_kill_house = ProvinceFactorToKillHouse.objects.get(
                province_check_info__kill_house_assignment__key=key, trash=False)
            kill_house_factor = KillHouseFactorToProvince.objects.filter(
                province_factor=provinc_factor_to_kill_house, trash=False)
            internal_dict_factors = {
                "full_name": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.user.fullname,
                "mobile": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.user.mobile,
                "weight": provinc_factor_to_kill_house.total_weight,
                "bar_code": provinc_factor_to_kill_house.factor_bar_code,
                "date": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.send_date,
                "gis_code": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request.user.gis_code,
                "fee": provinc_factor_to_kill_house.factor_fee,
                "total_amount": provinc_factor_to_kill_house.total_price,
                "total_amount_char": words(provinc_factor_to_kill_house.total_price) + " " + "ریال",
                "bank": provinc_factor_to_kill_house.bank,
                "key": provinc_factor_to_kill_house.key,

            }
            if kill_house_factor:
                internal_dict_factors.update({
                    "payment_code": kill_house_factor[0].payment_code,
                    "factor_image": kill_house_factor[0].factor_image,
                    "kill_house_factor_state": kill_house_factor[0].state,

                })
            if not kill_house_factor:
                internal_dict_factors.update({
                    "payment_code": None,
                    "factor_image": None,
                    "kill_house_factor_state": None,

                })

            factor_list.append(internal_dict_factors)

            return Response(factor_list, status=status.HTTP_200_OK)

        if request.GET['type'] == 'province':

            factor_dict_list = []
            factor_list = []
            for province_check in ProvinceCheckOperatorRequest.objects.filter(state='accept',
                                                                              financial_archive='pending', trash=False):
                poultry_req = province_check.city_request_Poultry.poultry_request
                internal_dict_poultry = {"full_name": poultry_req.user.fullname, "mobile": poultry_req.user.mobile,
                                         "gis_code": poultry_req.user.gis_code,
                                         "poultry_request_id": poultry_req.id,
                                         "date": poultry_req.send_date,
                                         "weight": province_check.total_weight_at_end,
                                         "price": province_check.fee,
                                         "breed": poultry_req.chicken_breed,
                                         "inspector": poultry_req.inspector,
                                         "order_code": poultry_req.order_code, "factors": ""}

                for provinc_factor_to_kill_house in ProvinceFactorToKillHouse.objects.filter(
                        province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request=province_check,
                        trash=False):

                    internal_dict_factors = {
                        "province_operator": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator.fullname,
                        "province_mobile": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.province_operator.mobile,
                        "weight": provinc_factor_to_kill_house.total_weight,
                        "bar_code": provinc_factor_to_kill_house.factor_bar_code,
                        "kill_house_name": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
                        "kill_house_mobile": provinc_factor_to_kill_house.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.user.mobile,
                        "cost": provinc_factor_to_kill_house.total_price,
                        "bank": provinc_factor_to_kill_house.bank,
                        "factor": provinc_factor_to_kill_house.bank,
                    }
                    kill_house_factor = KillHouseFactorToProvince.objects.filter(
                        province_factor=provinc_factor_to_kill_house)
                    if kill_house_factor:
                        internal_dict_factors.update({
                            "kill_house_Send_factor_information": "accepted",
                            "payment_code": kill_house_factor[0].payment_code,
                            "factor_image": kill_house_factor[0].factor_image,
                            "factor_key": kill_house_factor[0].key,
                            "factor_state": kill_house_factor[0].state
                        })
                    else:
                        internal_dict_factors.update({
                            "kill_house_Send_factor_information": "pending",
                            "payment_code": "",
                            "factor_image": "",
                            "factor_key": "",
                            "factor_state": ""
                        })

                    factor_list.append(internal_dict_factors)
                internal_dict_poultry["factors"] = factor_list
                factor_dict_list.append(internal_dict_poultry)
                factor_list = []

            return Response(factor_dict_list, status=status.HTTP_200_OK)


class KillHouseFactorToPoultryViewSet(viewsets.ModelViewSet):
    queryset = KillHouseFactorToPoultry.objects.all()
    serializer_class = KillHouseFactorToPoultrySerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به ایجاد فاکتور کشتارگاه برای استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)

        role = request.data['role']
        province_factor = ProvinceFactorToKillHouseForPoultry.objects.get(key=request.data['key'], trash=False)
        request.data.pop('key')
        request.data.pop('role')
        try:
            factor_image = request.data['factor_image']
            request.data.pop('factor_image')
        except:
            factor_image = None
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            factor = serializer.create(validated_data=request.data)
            if factor_image != None:
                factor.factor_image = send_image_to_server(factor_image)

            factor.province_factor = province_factor
            factor.importer = role
            factor.save()
            province_factor.kill_house_factor_info = 'accepted'
            province_factor.paid_state = 'paid'
            province_factor.save()
            factor_serializer = self.serializer_class(factor)
            return Response(factor_serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)

        role = request.data['role']
        kill_house_factor = KillHouseFactorToPoultry.objects.get(key=request.data['key'], trash=False)
        request.data.pop('key')
        request.data.pop('role')
        try:
            image = request.data['factor_image']
            request.data.pop('factor_image')
        except:
            image = None
        if image != None:
            kill_house_factor.factor_image = send_image_to_server(image)
        kill_house_factor.state = 'pending'
        kill_house_factor.importer = role
        kill_house_factor.save()

        serializer = self.serializer_class(kill_house_factor)
        serializer.update(instance=kill_house_factor, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


# ویوست مربوط به فاکتور کشتارگاه برای استان
class KillHouseFactorToProvinceViewSet(viewsets.ModelViewSet):
    queryset = KillHouseFactorToProvince.objects.all()
    serializer_class = KillHouseFactorToProvinceSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به ایجاد فاکتور کشتارگاه برای استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        role = request.data['role']
        province_factor = ProvinceFactorToKillHouse.objects.get(key=request.data['key'], trash=False)
        request.data.pop('key')
        request.data.pop('role')
        try:
            factor_image = request.data['factor_image']
            request.data.pop('factor_image')
        except:
            factor_image = None
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            factor = serializer.create(validated_data=request.data)
            if factor_image != None:
                factor.factor_image = send_image_to_server(factor_image)

            factor.province_factor = province_factor
            factor.importer = role
            factor.save()
            province_factor.kill_house_factor_info = 'accepted'
            province_factor.paid_state = 'paid'
            province_factor.save()
            factor_serializer = self.serializer_class(factor)
            return Response(factor_serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        role = request.data['role']
        kill_house_factor = KillHouseFactorToProvince.objects.get(key=request.data['key'], trash=False)
        request.data.pop('key')
        request.data.pop('role')
        try:
            image = request.data['factor_image']
            request.data.pop('factor_image')
        except:
            image = None
        if image != None:
            kill_house_factor.factor_image = send_image_to_server(image)
        kill_house_factor.state = 'pending'
        kill_house_factor.message = None
        kill_house_factor.importer = role
        kill_house_factor.save()

        serializer = self.serializer_class(kill_house_factor)
        serializer.update(instance=kill_house_factor, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if 'role' in request.GET:
            if request.GET['role'] == 'KillHouse':
                now = datetime.now().date()
                date1 = datetime.strptime(str(request.GET['date1']),
                                          '%Y-%m-%d').date() if 'date1' in request.GET else now
                date2 = datetime.strptime(str(request.GET['date2']),
                                          '%Y-%m-%d').date() if 'date2' in request.GET else now
                kill_house_operator = KillHouseOperator.objects.get(user=user, trash=False)
                kill_house = KillHouse.objects.filter(kill_house_operator=kill_house_operator)
                factor_list = KillHouseFactorToProvince.objects.filter(
                    province_factor__province_check_info__kill_house_assignment__kill_house_request__killhouse_user__in=kill_house)

                factors = [
                    factor for factor in factor_list
                    if date1 <= factor.modify_date.date() <= date2
                ]


            elif request.GET['role'] == 'ProvinceFinancial':
                factors = KillHouseFactorToProvince.objects.filter(state__in=('pending', 'accepted'),
                                                                   province_factor__province_check_info__kill_house_assignment__kill_house_request__killhouse_user__system_address__province=user.province)
        serializer = self.serializer_class(factors, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ProvinceImportKillHouseOutFactorsViewSet(viewsets.ModelViewSet):
    queryset = ProvinceImportKillHouseOutFactors.objects.all()
    serializer_class = ProvinceImportKillHouseOutFactorsSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به ایجاد فاکتور کشتارگاه برای استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        if 'poultry_factor_key' in request.data.keys():
            poultry_factor = ProvinceFactorToKillHouseForPoultry.objects.get(key=request.data['poultry_factor_key'])
            request.data.pop('poultry_factor_key')
            province_check_request = ProvinceCheckOperatorRequest.objects.get(key=poultry_factor.province_check_req.key)
        else:
            poultry_factor = None

        if 'province_factor_key' in request.data.keys():
            province_factor = ProvinceFactorToKillHouse.objects.get(key=request.data['province_factor_key'])
            request.data.pop('province_factor_key')
            province_check_request = ProvinceCheckOperatorRequest.objects.get(
                key=province_factor.province_check_req.key)

        else:
            province_factor = None
        image = request.data['image']
        request.data.pop('image')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            payment_factor = serializer.create(validated_data=request.data)
            payment_factor.province_check = province_check_request
            payment_factor.image = send_image_to_server(image)
            if poultry_factor != None:
                payment_factor.kill_house_factor_poultry = poultry_factor
                poultry_factor.paid_state = 'paid'
                poultry_factor.save()
            else:
                payment_factor.kill_house_factor = province_factor
                province_factor.paid_state = 'paid'
                province_factor.save()

            payment_factor.save()
            deposit_allocation = DepositAllocation.objects.filter(poultry=province_check_request.poultry_request)
            if deposit_allocation.count() > 0:
                deposit_allocation = deposit_allocation.last()
                if poultry_factor != None:
                    deposit_allocation.poultry_share += poultry_factor.shares['poultryShareWithProfit']
                else:
                    deposit_allocation.city_share += province_factor.shares['city_share']
                    deposit_allocation.province_share += province_factor.shares['province_share']
                    deposit_allocation.company_share += province_factor.shares['company_share']
                    deposit_allocation.central_union_share += province_factor.shares['central_union_share']
                    deposit_allocation.fanava_share += province_factor.shares['fanava_share']
                deposit_allocation.save()
            else:

                if poultry_factor != None:

                    deposit_allocation = DepositAllocation(poultry=province_check_request.poultry_request,
                                                           poultry_share=poultry_factor.shares[
                                                               'poultryShareWithProfit'],
                                                           )
                    deposit_allocation.save()

                else:
                    deposit_allocation = DepositAllocation(poultry=province_check_request.poultry_request,
                                                           city_share=province_factor.shares['city_share'],
                                                           province_share=province_factor.shares['province_share'],
                                                           company_share=province_factor.shares['company_share'],
                                                           central_union_share=province_factor.shares[
                                                               'central_union_share'],
                                                           fanava_share=province_factor.shares['fanava_share'],
                                                           )

                    deposit_allocation.save()
            province_factors = ProvinceFactorToKillHouse.objects.filter(
                province_check_req=province_check_request).count()
            poultry_factors = ProvinceFactorToKillHouseForPoultry.objects.filter(
                province_check_req=province_check_request).count()
            out_factors = ProvinceImportKillHouseOutFactors.objects.filter(
                province_check=province_check_request).count()
            if out_factors == province_factors + poultry_factors:
                poultry_request = PoultryRequest.objects.get(key=province_check_request.poultry_request.key)
                poultry_request.final_state = 'archive'
                poultry_request.save()

            factor_serializer = self.serializer_class(payment_factor)
            return Response(factor_serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)


# ویوست مربوط به تایید یا رذ فاکتورهای ارسالی از سمت کشتارگاه
class ProvinceCheckKillHouseFactorViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckKillHouseFactor.objects.all()
    serializer_class = ProvinceCheckKillHouseFactorSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به تایید یا رذ فاکتورهای ارسالی از سمت کشتارگاه
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        kill_house_factor = None
        kill_house_poultry_factor = None
        if request.data['type'] == 'province':
            kill_house_factor = KillHouseFactorToProvince.objects.get(key=request.data['key'], trash=False)
            request.data.pop('key')
            request.data.pop('type')

        else:
            kill_house_poultry_factor = KillHouseFactorToPoultry.objects.get(key=request.data['key'])
            request.data.pop('key')
            request.data.pop('type')

        if kill_house_factor != None:
            if kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner != None:
                auction = kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner
                poultry_request = kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.poultry_request
            else:
                auction = None
            if auction == None:
                if kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request != None:
                    province_check = kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request
                    poultry_request = kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request
        else:
            if kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner != None:
                auction = kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner
                poultry_request = kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_request.kill_house_request_auction_winner.kill_house_request_auction.poultry_request
            else:
                auction = None
            if auction == None:
                if kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request != None:
                    province_check = kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request
                    poultry_request = kill_house_poultry_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.province_request.city_request_Poultry.poultry_request
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            check = serializer.create(validated_data=request.data)
            if check.state == 'accepted':

                if kill_house_factor != None:
                    check.kill_house_factor = kill_house_factor
                    kill_house_factor.state = 'accepted'
                    kill_house_factor.save()
                else:
                    check.kill_house_factor_poultry = kill_house_poultry_factor
                    kill_house_poultry_factor.state = 'accepted'
                    kill_house_poultry_factor.save()

                if auction != None:
                    kill_house_factors = KillHouseFactorToProvince.objects.filter(state='accepted',
                                                                                  province_factor__province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=poultry_request,
                                                                                  trash=False)
                    kill_house_poultry_factors = KillHouseFactorToPoultry.objects.filter(state='accepted',
                                                                                         province_factor__province_check_info__kill_house_assignment__kill_house_request__kill_house_request_auction_winner__kill_house_request_auction__poultry_request=poultry_request,
                                                                                         trash=False)
                    # kill_house_requests = KillHouseRequest.objects.filter(
                    #     kill_house_request_auction_winner__kill_house_request_auction__poultry_request=poultry_request,
                    #     state='accepted',
                    #     active_state='inactive', trash=False)
                else:
                    kill_house_factors = KillHouseFactorToProvince.objects.filter(state='accepted',
                                                                                  province_factor__province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request=province_check,
                                                                                  trash=False,
                                                                                  province_factor__sum_state='pending')
                    kill_house_poultry_factors = KillHouseFactorToPoultry.objects.filter(state='accepted',
                                                                                         province_factor__province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request=province_check,
                                                                                         trash=False,
                                                                                         province_factor__sum_state='pending')
                    # kill_house_requests = KillHouseRequest.objects.filter(province_request=province_check,
                    #                                                       state='accepted',
                    #                                                       active_state='inactive', trash=False)

                # kill_house_requests_counter = len(kill_house_requests)
                # kill_house_factors_counter = len(kill_house_factors)
                # if kill_house_factors_counter == kill_house_requests_counter:
                total_amount = 0
                total_weight = 0
                poultry_share = 0
                city_share = 0
                province_share = 0
                company_share = 0
                central_union_share = 0
                fanava_share = 0
                if kill_house_factor != None:
                    for factor in kill_house_factors:
                        total_amount += factor.province_factor.total_price
                        total_weight += factor.province_factor.total_weight
                        if 'poultryShareWithProfit' in factor.province_factor.shares:
                            poultry_share += factor.province_factor.shares['poultryShareWithProfit']
                        else:
                            poultry_share = 0
                        city_share += factor.province_factor.shares['city_share']
                        province_share += factor.province_factor.shares['province_share']
                        company_share += factor.province_factor.shares['company_share']
                        central_union_share += factor.province_factor.shares['central_union_share']
                        fanava_share += factor.province_factor.shares['fanava_share']
                        f = ProvinceFactorToKillHouse.objects.get(key=factor.province_factor.key)
                        f.sum_state = 'complete'
                        f.save()

                    deposit_allocation = DepositAllocation.objects.filter(poultry=poultry_request)
                    if deposit_allocation.count() > 0:
                        deposit_allocation = deposit_allocation.last()
                        deposit_allocation.poultry_share += poultry_share
                        deposit_allocation.city_share += city_share
                        deposit_allocation.province_share += province_share
                        deposit_allocation.company_share += company_share
                        deposit_allocation.central_union_share += central_union_share
                        deposit_allocation.fanava_share += fanava_share
                        deposit_allocation.save()
                    else:

                        deposit_allocation = DepositAllocation(poultry=poultry_request,
                                                               poultry_share=poultry_share,
                                                               city_share=city_share,
                                                               province_share=province_share,
                                                               company_share=company_share,
                                                               central_union_share=central_union_share,
                                                               fanava_share=fanava_share,
                                                               )

                        deposit_allocation.save()
                else:

                    for factor in kill_house_poultry_factors:
                        total_amount += factor.province_factor.total_price
                        total_weight += factor.province_factor.total_weight
                        poultry_share += factor.province_factor.total_price
                        # poultry_share += factor.province_factor.shares['poultryShareWithProfit']
                        fa = ProvinceFactorToKillHouseForPoultry.objects.get(key=factor.province_factor.key)
                        fa.sum_state = 'complete'
                        fa.save()
                    deposit_allocation = DepositAllocation.objects.filter(poultry=poultry_request)
                    if deposit_allocation.count() > 0:
                        deposit_allocation = deposit_allocation.last()
                        deposit_allocation.poultry_share += poultry_share
                        deposit_allocation.poultry_share_payment += poultry_share
                        deposit_allocation.save()
                    else:

                        deposit_allocation = DepositAllocation(poultry=poultry_request,
                                                               poultry_share=poultry_share,
                                                               poultry_share_payment=poultry_share
                                                               )

                        deposit_allocation.save()

                if auction == None:
                    if province_check != None:
                        province_check.total_cost_at_end = total_amount
                        province_check.factor_state = 'accepted'
                        # province_check.financial_archive = 'accepted'
                        province_check.save()
                # poultry_request.inspector = 'pending'
                # poultry_request.save()

                province_factor_to_kill_house = ProvinceFactorToKillHouse.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request__city_request_Poultry__poultry_request=deposit_allocation.poultry,
                    trash=False)
                province_factor_to_kill_house_poultry = ProvinceFactorToKillHouseForPoultry.objects.filter(
                    province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request__city_request_Poultry__poultry_request=deposit_allocation.poultry,
                    trash=False)

                kill_house_requests = KillHouseRequest.objects.filter(
                    province_request__city_request_Poultry__poultry_request=deposit_allocation.poultry,
                    state='accepted',
                    active_state='inactive', trash=False)

                # total = 0
                # if province_factor_to_kill_house.count() > 0:
                #     for factor in province_factor_to_kill_house:
                #         total += factor.total_price
                # if province_factor_to_kill_house_poultry.count() > 0:
                #     for poultry_factor in province_factor_to_kill_house_poultry:
                #         total += poultry_factor.total_price
                # deposit_total = deposit_allocation.poultry_share_payment + deposit_allocation.city_share_payment + deposit_allocation.province_share_payment + deposit_allocation.company_share_payment + deposit_allocation.central_union_share_payment + deposit_allocation.fanava_share_payment
                #
                # if total == deposit_total:
                counter = 0
                if province_factor_to_kill_house.count() > 0:
                    counter = province_factor_to_kill_house.count()
                for po_factor in province_factor_to_kill_house_poultry:
                    if ProvinceFactorToKillHouse.objects.filter(poultry_factor=po_factor).exists():
                        continue
                    else:
                        counter += 1
                if counter == kill_house_requests.count():
                    poultry_request = PoultryRequest.objects.get(key=deposit_allocation.poultry.key)
                    poultry_request.inspector = 'pending'
                    poultry_request.awaiting_payment = False
                    poultry_request.save()

            if check.state == 'rejected':
                if kill_house_factor != None:
                    kill_house_factor.state = 'rejected'
                    check.kill_house_factor = kill_house_factor
                    kill_house_factor.message = check.message
                    kill_house_factor.save()
                else:
                    kill_house_poultry_factor.state = 'rejected'
                    kill_house_poultry_factor.message = check.message
                    kill_house_poultry_factor.save()

            check.save()
            check_serializer = self.serializer_class(check)
            return Response(check_serializer.data, status=status.HTTP_201_CREATED)

        return Response(serializer.errors)


# ویوست مربوط به تخصیصات مالی برای استان و شهرستان و مرغدار
class DepositAllocationViewSet(viewsets.ModelViewSet):
    queryset = DepositAllocation.objects.all()
    serializer_class = DepositAllocationSerializer
    permission_classes = [TokenHasReadWriteScope]

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

    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)

        deposit = DepositAllocation.objects.get(key__exact=request.data["key"], trash=False)
        province_factor_to_kill_house = ProvinceFactorToKillHouse.objects.filter(
            province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request__city_request_Poultry__poultry_request=deposit.poultry,
            trash=False)
        province_factor_to_kill_house_poultry = ProvinceFactorToKillHouseForPoultry.objects.filter(
            province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request__city_request_Poultry__poultry_request=deposit.poultry,
            trash=False)

        kill_house_requests = KillHouseRequest.objects.filter(
            province_request__city_request_Poultry__poultry_request=deposit.poultry,
            state='accepted',
            active_state='inactive', trash=False)

        request.data.pop('key')
        pay_for = request.data['type']
        request.data.pop('type')
        image = request.data['image']
        pay = request.data['payment']
        request.data.pop('image')
        request.data.pop('payment')
        if pay_for == 'Poultry':
            deposit.city_image = send_image_to_server(image)
            deposit.poultry_share_payment += float(pay)
            list1 = []
            if deposit.poultry_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.poultry_share_payment_info = list1
            else:
                list1 = list(deposit.poultry_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.poultry_share_payment_info = list1
            deposit.save()
        elif pay_for == 'CityOperator':
            # deposit.city_image = send_image_to_server(image)
            deposit.city_share_payment += float(pay)
            list1 = []
            if deposit.city_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.city_share_payment_info = list1
            else:
                list1 = list(deposit.city_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                # list1.append(list1.append({city_pay: ARVAN_deposit_URL + "{0}.jpg".format(str(ran))}))
                deposit.city_share_payment_info = list1
            deposit.save()
        elif pay_for == 'ProvinceOperator':
            # deposit.city_image = send_image_to_server(image)
            deposit.province_share_payment += float(pay)
            list1 = []
            if deposit.province_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.province_share_payment_info = list1
            else:
                list1 = list(deposit.province_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.province_share_payment_info = list1
            deposit.save()
        elif pay_for == 'fanava':
            # deposit.city_image = send_image_to_server(image)
            deposit.fanava_share_payment += float(pay)
            list1 = []
            if deposit.fanava_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.fanava_share_payment_info = list1
            else:
                list1 = list(deposit.fanava_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.fanava_share_payment_info = list1
            deposit.save()
        elif pay_for == 'company':
            # deposit.city_image = send_image_to_server(image)
            deposit.company_share_payment += float(pay)
            list1 = []
            if deposit.company_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.company_share_payment_info = list1
            else:
                list1 = list(deposit.company_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.company_share_payment_info = list1
            deposit.save()
        elif pay_for == 'central':
            # deposit.city_image = send_image_to_server(image)
            deposit.central_union_share_payment += float(pay)
            list1 = []
            if deposit.central_union_share_payment_info == list1:
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.central_union_share_payment_info = list1
            else:
                list1 = list(deposit.central_union_share_payment_info)
                list1.append({"pay": pay, "image": send_image_to_server(image)})
                deposit.central_union_share_payment_info = list1
            deposit.save()
        # total = 0
        # if province_factor_to_kill_house.count() > 0:
        #     for factor in province_factor_to_kill_house:
        #         total += factor.total_price
        #     if province_factor_to_kill_house_poultry.count() > 0:
        #         for poultry_factor in province_factor_to_kill_house_poultry:
        #             total += poultry_factor.total_price
        #     deposit_total = deposit.poultry_share_payment + deposit.city_share_payment + deposit.province_share_payment + deposit.company_share_payment + deposit.central_union_share_payment + deposit.fanava_share_payment
        #
        #     if total == deposit_total:
        #         counter = province_factor_to_kill_house.count()
        #         for po_factor in province_factor_to_kill_house_poultry:
        #             if ProvinceFactorToKillHouse.objects.filter(poultry_factor=po_factor).exists():
        #                 continue
        #             else:
        #                 counter += 1
        #         if counter == kill_house_requests.count():
        #             poultry_request = PoultryRequest.objects.get(key=deposit.poultry.key)
        #             poultry_request.final_state = 'archive'
        #             poultry_request.save()

        serializer = self.serializer_class(deposit)
        serializer.update(instance=deposit, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # تابع مربوط به نمایش تخصیصات مالی برای استان و شهرستان و مرغدار
    # def list(self, request, *args, **kwargs):
    #     # refresh(request.user.id)
    #     user = SystemUserProfile.objects.get(user=request.user, trash=False)
    # final_list = []
    # factor_dict_list = []
    # factor_list = []
    # for province_check_request in ProvinceCheckOperatorRequest.objects.filter(state='accept',
    #                                                                           factor_state='accepted',
    #                                                                           deposit_allocation_archive='pending',
    #                                                                           trash=False):
    #     poultry = province_check_request.city_request_Poultry.poultry_request.user
    #     city_operator = province_check_request.city_request_Poultry.city_operator
    #     deposit_allocation = DepositAllocation.objects.filter(
    #         poultry=province_check_request.city_request_Poultry.poultry_request)
    #
    #     internal_dict_poultry = {
    #         "full_name": province_check_request.city_request_Poultry.poultry_request.user.fullname,
    #         "mobile": province_check_request.city_request_Poultry.poultry_request.user.mobile,
    #         "gis_code": province_check_request.city_request_Poultry.poultry_request.user.gis_code,
    #         "quantity": province_check_request.city_request_Poultry.poultry_request.quantity,
    #         "breed": province_check_request.city_request_Poultry.poultry_request.chicken_breed,
    #         "order_code": province_check_request.city_request_Poultry.poultry_request.order_code,
    #         "fee": province_check_request.fee,
    #         "date": province_check_request.city_request_Poultry.poultry_request.send_date,
    #         "total_weight": province_check_request.total_weight_at_end,
    #         "total_amount": province_check_request.total_cost_at_end,
    #         "factors": ""}
    #
    #     if user.role.name == 'Poultry':
    #         if deposit_allocation:
    #             internal_dict_poultry.update({"poultry_share": deposit_allocation[0].poultry_share,
    #                                           "poultry_bank_name": user.user_bank_info.bank_name,
    #                                           "poultry_card_number": user.user_bank_info.card,
    #                                           "poultry_shaba": user.user_bank_info.shaba,
    #                                           "poultry_bank_account_number": user.user_bank_info.account,
    #                                           "poultry_image": deposit_allocation[0].poultry_image,
    #                                           "Union_share": deposit_allocation[0].province_share +
    #                                                          deposit_allocation[0].city_share,
    #                                           "province": province_check_request.province_operator.address.province,
    #                                           })
    #             factor_dict_list.append(internal_dict_poultry)
    #             factor_list = []
    #     if user.role.name == 'CityOperator':
    #         if deposit_allocation:
    #             internal_dict_poultry.update({
    #                 "city": city_operator.address.city,
    #                 "city_bank_name": city_operator.user_bank_info.bank_name,
    #                 "name_of_bank_user": city_operator.user_bank_info.name_of_bank_user,
    #                 "city_share": deposit_allocation[0].city_share,
    #                 "city_image": deposit_allocation[0].city_image,
    #             })
    #             factor_dict_list.append(internal_dict_poultry)
    #             factor_list = []
    #     if user.role.name == 'ProvinceOperator':
    #         for kill_house_req_obj in KillHouseRequest.objects.filter(province_request=province_check_request,
    #                                                                   state='accepted', trash=False):
    #             province_req = kill_house_req_obj.province_request
    #
    #             for kill_house_factor in KillHouseFactorToProvince.objects.filter(
    #                     province_factor__province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request=province_req,
    #                     state='accepted', trash=False):
    #                 internal_dict_factors = {
    #                     "barcod": kill_house_factor.province_factor.factor_bar_code,
    #                     "kill_house_name": kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
    #                     "kill_house_mobile": kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.user.mobile,
    #                     "payment_code": kill_house_factor.payment_code,
    #                     "cost": kill_house_factor.province_factor.total_price,
    #                     "factor_key": kill_house_factor.key,
    #                     "factor_state": kill_house_factor.state,
    #                     "factor_payment_state": kill_house_factor.payment_state,
    #                     "factor_payment_method": kill_house_factor.payment_method
    #                 }
    #                 factor_list.append(internal_dict_factors)
    #         internal_dict_poultry["factors"] = factor_list
    #         internal_dict_poultry.update({
    #             "total_money": province_check_request.total_cost_at_end,
    #         })
    #         deposit_allocation = DepositAllocation.objects.filter(
    #             poultry=province_check_request.city_request_Poultry.poultry_request)
    #         if deposit_allocation:
    #             if user.role.name == 'ProvinceOperator':
    #                 internal_dict_poultry.update({"allocation_key": deposit_allocation[0].key,
    #                                               "poultry_share": deposit_allocation[0].poultry_share,
    #                                               "poultry_bank_info": poultry.user_bank_info.name_of_bank_user,
    #                                               "poultry_bank_name": user.user_bank_info.bank_name,
    #                                               "poultry_card_number": user.user_bank_info.card,
    #                                               "poultry_shaba": user.user_bank_info.shaba,
    #                                               "poultry_image": deposit_allocation[0].poultry_image,
    #                                               "city_share": deposit_allocation[0].city_share,
    #                                               "city_bank_info": city_operator.user_bank_info.name_of_bank_user,
    #                                               "city_bank_name": city_operator.user_bank_info.bank_name,
    #                                               "city_card_number": city_operator.user_bank_info.card,
    #                                               "city_shaba": city_operator.user_bank_info.shaba,
    #                                               "city_image": deposit_allocation[0].city_image,
    #                                               "province_share": deposit_allocation[0].province_share,
    #                                               "province_bank_info": province_check_request.province_operator.user_bank_info.name_of_bank_user,
    #                                               })
    #         factor_dict_list.append(internal_dict_poultry)
    #         factor_list = []
    #

    # return Response(factor_dict_list, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        factor_list = []
        user = SystemUserProfile.objects.get(user=request.user)
        allocations = DepositAllocation.objects.filter(poultry__poultry__address__province=user.province).order_by('id')
        serializer_request = self.serializer_class(allocations, many=True)
        return Response(serializer_request.data, status=status.HTTP_200_OK)


class InspectorOperatorViewSet(viewsets.ModelViewSet):
    queryset = InspectorOperator.objects.all()
    serializer_class = InspectorOperatorSerializer
    permission_classes = [TokenHasReadWriteScope]

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            operator = InspectorOperator.objects.get(user=user, trash=False)
            inspector_operator_serializer = InspectorOperatorSerializer(operator)
            profile_info = {
                'inspector': inspector_operator_serializer.data,
            }
            return Response(profile_info, status=status.HTTP_200_OK)


# ویوست مربوط به تایید یا رد پرونده مرغدار توسط بازرس استان
class PovinceInspectorViewSet(viewsets.ModelViewSet):
    queryset = PovinceInspector.objects.all()
    serializer_class = PovinceInspectorSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به تایید یا رد پرونده مرغدار توسط بازرس استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        inspector = InspectorOperator.objects.get(user=user, trash=False)
        key = request.data['key']
        request.data.pop('key')
        poultry_request = PoultryRequest.objects.get(key=key, trash=False)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            inspector_req = serializer.create(validated_data=request.data)
            inspector_req.poultry_request = poultry_request
            if inspector_req.state == 'accepted':
                poultry_request.inspector = 'accepted'
                poultry_request.final_state = 'archive'
            elif inspector_req.state == 'rejected':
                poultry_request.inspector = 'rejected'
                poultry_request.final_state = 'archive'
            poultry_request.save()
            inspector_req.inspector = user
            inspector_req.inspector_operator = inspector
            inspector_req.save()
            serializer_request = self.serializer_class(inspector_req)
            return Response(serializer_request.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    # تابع مربوط به نمایش پرونده های تایید شده  یا رد شده توسط بازرس استان
    # def list(self, request, *args, **kwargs):
    #     user = UserProfile.objects.get(user=request.user)
    #     final_list = []
    #     factor_dict_list = []
    #     factor_list = []
    #     for province_check_request in ProvinceCheckOperatorRequest.objects.filter(state='accept',
    #                                                                               factor_state='accepted',
    #                                                                               deposit_allocation_archive='accepted'):
    #         poultry = province_check_request.city_request_Poultry.poultry_request.user
    #         city_operator = province_check_request.city_request_Poultry.city_operator
    #         deposit_allocation = DepositAllocation.objects.filter(
    #             poultry=province_check_request.city_request_Poultry.poultry_request)
    #
    #         internal_dict_poultry = {
    #             "full_name": province_check_request.city_request_Poultry.poultry_request.user.fullname,
    #             "mobile": province_check_request.city_request_Poultry.poultry_request.user.mobile,
    #             "gis_code": province_check_request.city_request_Poultry.poultry_request.user.gis_code,
    #             "quantity": province_check_request.city_request_Poultry.poultry_request.quantity,
    #             "breed": province_check_request.city_request_Poultry.poultry_request.chicken_breed,
    #             "order_code": province_check_request.city_request_Poultry.poultry_request.order_code,
    #             "fee": province_check_request.fee,
    #             "date": province_check_request.city_request_Poultry.poultry_request.send_date,
    #             "total_weight": province_check_request.total_weight_at_end,
    #             "total_amount": province_check_request.total_cost_at_end,
    #             "factors": ""}
    #         if user.role.name == 'ProvinceOperator':
    #             for kill_house_req_obj in KillHouseRequest.objects.filter(province_request=province_check_request,
    #                                                                       state='accepted'):
    #                 province_req = kill_house_req_obj.province_request
    #
    #                 for kill_house_factor in KillHouseFactorToProvince.objects.filter(
    #                         province_factor__province_check_info__kill_house_assignment__kill_house_check__province_kill_request__province_request=province_req,
    #                         state='accepted'):
    #                     internal_dict_factors = {
    #                         "barcod": kill_house_factor.province_factor.factor_bar_code,
    #                         "kill_house_name": kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.name,
    #                         "kill_house_mobile": kill_house_factor.province_factor.province_check_info.kill_house_assignment.kill_house_check.province_kill_request.kill_request.kill_house.user.mobile,
    #                         "payment_code": kill_house_factor.payment_code,
    #                         "cost": kill_house_factor.province_factor.total_price,
    #                         "factor_key": kill_house_factor.key,
    #                         "factor_state": kill_house_factor.state,
    #                         "factor_payment_state": kill_house_factor.payment_state,
    #                         "factor_payment_method": kill_house_factor.payment_method
    #                     }
    #                     factor_list.append(internal_dict_factors)
    #             internal_dict_poultry["factors"] = factor_list
    #             internal_dict_poultry.update({
    #                 "total_money": province_check_request.total_cost_at_end,
    #             })
    #             deposit_allocation = DepositAllocation.objects.filter(
    #                 poultry=province_check_request.city_request_Poultry.poultry_request)
    #             if deposit_allocation:
    #                 if user.role.name == 'ProvinceOperator':
    #                     internal_dict_poultry.update({"allocation_key": deposit_allocation[0].key,
    #                                                   "poultry_share": deposit_allocation[0].poultry_share,
    #                                                   "poultry_bank_info": poultry.user_bank_info.name_of_bank_user,
    #                                                   "poultry_bank_name": user.user_bank_info.bank_name,
    #                                                   "poultry_card_number": user.user_bank_info.card,
    #                                                   "poultry_shaba": user.user_bank_info.shaba,
    #                                                   "poultry_image": deposit_allocation[0].poultry_image,
    #                                                   "city_share": deposit_allocation[0].city_share,
    #                                                   "city_bank_info": city_operator.user_bank_info.name_of_bank_user,
    #                                                   "city_bank_name": city_operator.user_bank_info.bank_name,
    #                                                   "city_card_number": city_operator.user_bank_info.card,
    #                                                   "city_shaba": city_operator.user_bank_info.shaba,
    #                                                   "city_image": deposit_allocation[0].city_image,
    #                                                   "province_share": deposit_allocation[0].province_share,
    #                                                   "province_bank_info": province_check_request.province_operator.user_bank_info.name_of_bank_user,
    #                                                   })
    #             factor_dict_list.append(internal_dict_poultry)
    #             factor_list = []
    #
    #     return Response(factor_dict_list, status=status.HTTP_200_OK)


# ویوست مربوط به دریافت درخواست مرغدار که در هر مرحله ای رد شده باشه برای پنل استان
class RejectedRequestsViewSet(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    serializer_class = PoultryRequestSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به نمایش درخواست مرغدار که در هر مرحله ای رد شده باشه برای پنل استان
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user)
        objects = []
        objects_list = []
        poultry_request = PoultryRequest.objects.filter(poultry__address__province=user.province)
        # for value in self.queryset:
        for value in poultry_request:
            for i in value.poultry_check.filter():
                if i.state == "rejected" or i.state == "reject":
                    objects.append({
                        'rejected_position': 'city-operator',
                        'rejected_position_farsi': 'اپراتور شهرستان',
                        'city_operator': i.city_operator_system.user.fullname,
                        'modify_date': i.modify_date,
                        'reason_message': i.message,
                        'value': self.serializer_class(value).data
                    })
                    break
                for item in i.Poultry_city_request_to_province.filter():
                    if item.state == "rejected" or item.state == "reject":
                        objects.append({
                            'rejected_position': 'province-operator',
                            'rejected_position_farsi': 'اپراتور استان',
                            'province_operator': item.province_operator_system.user.fullname,
                            'modify_date': item.modify_date,
                            'city_operator': item.city_request_Poultry.city_operator_system.user.fullname,
                            'reason_message': item.message,
                            'value': self.serializer_class(value).data
                        })
                        break
                    for x in item.kill_house_province.filter():
                        if x.state == "rejected" or x.state == "reject":
                            objects.append({
                                'rejected_position': 'kill-house-request',
                                'rejected_position_farsi': 'درخواست کشتارگاه',
                                'kill_house': x.kill_request.kill_house.name,
                                'modify_date': x.modify_date,
                                'province_operator': x.province_request.province_operator_system.user.fullname,
                                'city_operator': x.province_request.city_request_Poultry.city_operator_system.user.fullname,
                                'reason_message': x.message,
                                'value': self.serializer_class(value).data
                            })
                            break
                        for y in x.province_kill_house_check.filter():
                            for m in y.kill_house_check_req.filter():
                                for n in m.kill_house_assign.filter():
                                    if n.state == "rejected" or n.state == "reject":
                                        objects.append({
                                            'rejected_position': 'financial',
                                            'rejected_position_farsi': 'مالی',
                                            'province_operator': n.kill_house_assignment.kill_house_check.
                                                province_kill_request.province_request.province_operator_system.user.fullname,
                                            'kill_house': n.kill_house_assignment.kill_house_check.province_kill_request
                                                .kill_request.kill_house.name,
                                            'city_operator': n.kill_house_assignment.kill_house_check.province_kill_request
                                                .province_request.city_request_Poultry.city_operator_system.user.fullname,
                                            'modify_date': n.modify_date,
                                            'reason_message': n.message,
                                            'value': self.serializer_class(value).data
                                        })
                                    for v in n.province_info.filter():
                                        pass
            for i in value.poultry_request_inspector.filter():
                if i.state == "rejected" or i.state == "reject":
                    objects.append({
                        'rejected_position': 'inspector-operator',
                        'rejected_position_farsi': 'اپراتور بازرس استان',
                        'inspector_operator': i.inspector_operator.user.fullname,
                        'modify_date': i.modify_date,
                        'reason_message': i.message,
                        'value': self.serializer_class(value).data
                    })
                    break
        for item in objects:
            objects_dict = {}
            kill_house_objects = []
            objects_dict['rejected_position'] = item['rejected_position']
            objects_dict['rejected_position_farsi'] = item['rejected_position_farsi']
            objects_dict['fullname'] = item['value']['poultry']['userprofile']['full_name']
            objects_dict['mobile'] = item['value']['poultry']['userprofile']['mobile']
            objects_dict['city'] = item['value']['poultry']['address']['city']['name']
            objects_dict['province'] = item['value']['poultry']['address']['province']['name']

            if 'city_operator' in item.keys():
                objects_dict['city_operator'] = item['city_operator']
            if 'province_operator' in item.keys():
                objects_dict['province_operator'] = item['province_operator']
            if 'kill_house' in item.keys():
                objects_dict['kill_house'] = item['kill_house']
            objects_dict['modify_date'] = item['modify_date']
            objects_dict['reason_message'] = item['reason_message']
            if item['value']['process']['province_kill_requests'] is not None:
                for kill_item in item['value']['process']['province_kill_requests']:
                    if kill_item['kill_house_requests']:
                        for i in kill_item['kill_house_requests']:
                            kill_dict = {}
                            kill_dict['kill_house_name'] = i['kill_house_name']
                            kill_dict['kill_house_owner_name'] = i['kill_house_user_name']
                            kill_dict['mobile'] = i['kill_house_mobile']
                            kill_dict['quantity'] = i['quantity']
                            kill_dict['date'] = i['date']
                            kill_dict['time'] = i['time']
                            kill_dict['barcode'] = i['barcod']
                            kill_dict['car_model'] = i['type_car']
                            kill_dict['pelak'] = i['pelak']
                            kill_dict['car_quantity'] = i['capocity']
                            kill_dict['driver_name'] = i['driver_name']
                            kill_house_objects.append(kill_dict)
            objects_dict['kill_house'] = kill_house_objects
            objects_dict['poultry_quantity'] = item['value']['quantity']
            objects_dict['send_date'] = item['value']['send_date']
            objects_dict['chicken_breed'] = item['value']['chicken_breed']
            objects_dict['Index_weight'] = item['value']['Index_weight']
            objects_dict['order_code'] = item['value']['order_code']
            objects_dict['create_date'] = item['value']['create_date']
            objects_dict['id'] = item['value']['id']
            kill_date = datetime.strptime(str(item['value']['send_date']), '%Y-%m-%dT%H:%M:%S')
            # objects_dict['age'] = (kill_date - chicken_date).days + 2
            objects_list.append(objects_dict)
        return Response(objects_list)


# ویوست مربوط به بررسی قیمت گذاری برای پنل استان
class ProvinceCheckRequestsPriceViewSet(viewsets.ModelViewSet):
    queryset = ProvinceCheckOperatorRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceCheckOperatorRequestSerializer

    # تابع مربوط به بررسی قیمت گذاری برای پنل استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        next_day = datetime.now() + timedelta(days=1)
        now = datetime.now()
        price = Pricing.objects.filter(date__gte=next_day.date(), trash=False)
        if price:
            pass

        elif not price and now.hour == 12:
            user = UserProfile.objects.get(role__name='ProvinceFinancial', trash=False)
            message = UserMessage(
                message="کاربر گرامی {} 12 ساعت تا شزوع روز بعد باقی است لطفا قیمت های روز بعد را وارد نمایید  ".format(
                    user.fullname))
            message.save()
            message.users.add(user)
            return Response('message_sent')
        elif not price and now.hour == 17:
            users = UserProfile.objects.filter(role__name__in=('ProvinceFinancial', 'ProvinceInspector'), trash=False)
            for user in users:
                message = UserMessage(
                    message="کاربر گرامی {} 7 ساعت تا شزوع روز بعد باقی است لطفا قیمت های روز بعد را وارد نمایید".format(
                        user.fullname))
                message.save()
                message.users.add(user)
            return Response('message_sent')

        elif not price and now.hour == 22:
            users = UserProfile.objects.filter(
                role__name__in=('ProvinceFinancial', 'ProvinceOperator', 'ProvinceInspector'), trash=False)
            for user in users:
                message = UserMessage(
                    message="کاربر گرامی {} 2 ساعت تا شزوع روز بعد باقی است لطفا قیمت های روز بعد را وارد نمایید".format(
                        user.fullname))
                message.save()
                message.users.add(user)
                price_reminder(user.mobile, user.fullname)
            return Response('sms sent')


# ویوست مربوط به آنالیز قیمت گذاری برای پنل استان
class PriceAnalysisViewSet(viewsets.ModelViewSet):
    queryset = PriceAnalysis.objects.all()
    serializer_class = PriceAnalysisorSerializer
    permission_classes = [TokenHasReadWriteScope]

    # تابع مربوط به آنالیز قیمت گذاری برای پنل استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            price_analys = serializer.create(validated_data=request.data)
            price_analys.corn_Ration_free_price = price_analys.anacorn_percent * price_analys.corn_free_price
            price_analys.Soy_Ration_free_price = price_analys.Soy_percent * price_analys.Soy_free_price
            price_analys.Oil_Ration_free_price = price_analys.Oil_percent * price_analys.Oil_free_price
            price_analys.Dicalcium_Ration_free_price = price_analys.Dicalcium_percent * price_analys.Dicalcium_free_price
            price_analys.Carbonate_Ration_free_price = price_analys.Carbonate_percent * price_analys.Carbonate_free_price
            price_analys.mineral_Ration_supplement_free_price = price_analys.mineral_supplement_percent * price_analys.mineral_supplement_free_price
            price_analys.vitamin_Ration_free_supplement_percent = price_analys.vitamin_supplement_percent * price_analys.vitamin_supplement_total_free_price
            price_analys.baking_Ration_soda_free_price = price_analys.baking_soda_percent * price_analys.baking_soda_free_price
            price_analys.Salt_Ration_free_price = price_analys.Salt_percent * price_analys.Salt_free_price
            price_analys.metiunin_Ration_free_price = price_analys.metiunin_percent * price_analys.metiunin_free_price
            price_analys.Lysine_Ration_free_price = price_analys.Lysine_percent * price_analys.Lysine_free_price
            price_analys.threonine_Ration_free_price = price_analys.threonine_percent * price_analys.threonine_free_price
            price_analys.Antifungal_Ration_free_price = price_analys.Antifungal_percent * price_analys.Antifungal_free_price
            price_analys.Colleen_Ration_free_price = price_analys.Colleen_percent * price_analys.Colleen_free_price
            price_analys.total_percent = price_analys.anacorn_percent + price_analys.Soy_percent + price_analys.Oil_percent + price_analys.Dicalcium_percent + price_analys.Carbonate_percent + price_analys.mineral_supplement_percent + price_analys.vitamin_supplement_percent + price_analys.baking_soda_percent + price_analys.Salt_percent + price_analys.metiunin_percent + price_analys.Lysine_percent + price_analys.threonine_percent + price_analys.Antifungal_percent + price_analys.Colleen_percent
            price_analys.total_ration = price_analys.corn_Ration_free_price + price_analys.Soy_Ration_free_price + price_analys.Oil_Ration_free_price + price_analys.Dicalcium_Ration_free_price + price_analys.Carbonate_Ration_free_price + price_analys.mineral_Ration_supplement_free_price + price_analys.vitamin_Ration_free_supplement_percent + price_analys.baking_Ration_soda_free_price + price_analys.Salt_Ration_free_price + price_analys.metiunin_Ration_free_price + price_analys.Lysine_Ration_free_price + price_analys.threonine_Ration_free_price + price_analys.Antifungal_Ration_free_price + price_analys.Colleen_Ration_free_price
            price_analys.corn_total_free_price = 5 * (price_analys.total_ration / 2.5)
            price_analys.Soy_total_free_price = price_analys.period_chicken / 2.5
            price_analys.Oil_total_free_price = price_analys.Vaccination_period / 50000
            price_analys.Dicalcium_total_free_price = price_analys.Multivitamin_course / 50000
            price_analys.Carbonate_total_free_price = price_analys.directors_office / 50000
            price_analys.mineral_supplement_total_free_price = price_analys.Water_gas_electricity_period / 50000
            price_analys.vitamin_supplement_total_free_price = price_analys.Water_gas_the_current_cost_of_the_period_unit / 50000
            price_analys.baking_soda_total_free_price = price_analys.Course_repairs / 50000
            price_analys.Salt_free_total_price = price_analys.motfar_ga_durah / 50000
            price_analys.metiunin_total_free_price = price_analys.Paper_reel / 50000
            price_analys.Lysine_total_free_price = price_analys.Course_disinfection / 50000
            price_analys.threonine_total_free_price = price_analys.Lamp / 50000
            price_analys.Antifungal_total_free_price = 60
            price_analys.inulin_total_free_price = 50
            price_analys.Fire_total_emulsion_free_price = 25
            price_analys.Colleen_total_free_price = price_analys.Course_loss / 50000
            price_analys.chicken_price = price_analys.corn_total_free_price + price_analys.Soy_total_free_price + price_analys.Oil_total_free_price + price_analys.Dicalcium_total_free_price + price_analys.Carbonate_total_free_price + price_analys.mineral_supplement_total_free_price + price_analys.vitamin_supplement_total_free_price + price_analys.baking_soda_total_free_price + price_analys.Salt_free_total_price + price_analys.metiunin_total_free_price + price_analys.Lysine_total_free_price + price_analys.threonine_total_free_price + price_analys.Antifungal_total_free_price + price_analys.inulin_total_free_price + price_analys.Fire_total_emulsion_free_price + price_analys.Colleen_total_free_price
            price_analys.save()
            serializer_request = self.serializer_class(price_analys)
            return Response(serializer_request.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)


# ویوست مربوط به ثبت درخواست مرغ منجمد و ایجاد فاکتور پنل استان
class WareHouseFactorViewSet(viewsets.ModelViewSet):
    queryset = WareHouseFactor.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WareHouseFactorSerializer

    # نابع مربوط به ثبت درخواست مرغ منجمد و ایجاد فاکتور پنل استان
    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = UserProfile.objects.get(user=request.user, trash=False)
        role = Group.objects.get(name=user.role.name)
        ware_factor = WareHouseFactor.objects.all()
        letter_number = ware_factor.last().letter_number + 1 if len(ware_factor) > 0 else 100000
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            ware_house_factor = serializer.create(validated_data=request.data)
            if role.name == 'Jahad':
                ware_house_factor.first_operator = user
                today = jdatetime.datetime.now()
                today = today.date()

                ware_house_factor.letter_number_jahad = int(
                    str(today.year) + str(today.month) + str(today.day) + str(ware_house_factor.letter_number))
                serializer_request = self.serializer_class(ware_house_factor)
                return Response(serializer_request.data, status=status.HTTP_201_CREATED)
            ware_house_factor.total_wage = float(ware_house_factor.weight) * float(ware_house_factor.wage)
            ware_house_factor.total_fee = float(ware_house_factor.weight) * float(ware_house_factor.fee)
            ware_house_factor.total_cost = ware_house_factor.total_fee + ware_house_factor.total_wage
            ware_house_factor.second_operator = user
            ware_house_factor.letter_number = letter_number
            ware_house_factor.save()
            serializer_request = self.serializer_class(ware_house_factor)
            return Response(serializer_request.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    # نابع مربوط به ویرایش درخواست مرغ منجمد ثبت شده پنل استان
    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)

        user = UserProfile.objects.get(user=request.user, trash=False)
        role = Group.objects.get(name=user.role.name)
        ware_house_factor = WareHouseFactor.objects.get(key__exact=request.data["key"], trash=False)
        request.data.pop('key')
        if role.name == 'Jahad':
            if ware_house_factor.state == 'completed':
                return Response({'result': 'can not update'}, status=status.HTTP_403_FORBIDDEN)
            else:
                ware_house_factor.first_operator = user
                ware_house_factor.save()
            serializer = self.serializer_class(ware_house_factor)
            serializer.update(instance=ware_house_factor, validated_data=request.data)

        else:
            try:
                wage = float(request.data['wage'])
                fee = float(request.data['fee'])
                request.data.pop('wage')
                request.data.pop('fee')
            except:
                wage = ware_house_factor.wage
                fee = ware_house_factor.fee

            try:
                weight = float(request.data['weight'])
                request.data.pop('weight')
                ware_house_factor.weight = weight
            except:
                weight = ware_house_factor.weight
            ware_house_factor.state = 'completed'
            ware_house_factor.fee = fee
            ware_house_factor.wage = wage
            ware_house_factor.total_wage = weight * wage
            ware_house_factor.total_fee = weight * fee
            ware_house_factor.total_cost = ware_house_factor.total_fee + ware_house_factor.total_wage
            ware_house_factor.second_operator = user
            ware_house_factor.save()
            serializer = self.serializer_class(ware_house_factor)
            serializer.update(instance=ware_house_factor, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # نابع مربوط به نمایش درخواست مرغ منجمد ثبت شده پنل استان
    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        queryset = WareHouseFactor.objects.filter(trash=False).order_by('-create_date')
        # queryset = WareHouseFactor.objects.all().order_by('-create_date')
        serializer = WareHouseFactorSerializer(queryset, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    # نابع مربوط به حذف درخواست مرغ منجمد ثبت شده پنل استان
    def destroy(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        queryset = WareHouseFactor.objects.get(id=pk, trash=False)
        queryset.trash = True
        queryset.save()
        return Response(queryset.trash, status=status.HTTP_200_OK)


class ManageCarsByProvince(viewsets.ModelViewSet):
    queryset = KillHouseADDCAR.objects.all()
    serializer_class = KillHouseADDCARSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        """
            Show List Of KillHouse Cars To Province
        """
        kill_house_object = KillHouse.objects.get(key=request.GET['key'], trash=False)
        kill_house_cars = self.queryset.filter(kill_house=kill_house_object, trash=False)

        # Send Data To Serializer
        serializer = self.serializer_class(kill_house_cars)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        """
            Update KillHouse Cars (activate cars) By Province Operator
        """
        car_key = request.data['key']
        request.data.pop('key')
        car_object = self.queryset.get(key=car_key, trash=False)

        # Sending Data To Serializer & Update Information
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            obj = serializer.update(
                validated_data=request.data,
                instance=car_object
            )
            serializer = self.serializer_class(obj)
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class KillHouseListForProvince(viewsets.ModelViewSet):
    queryset = KillHouse.objects.all()
    serializer_class = KillHouseSerializer
    permission_classes = [TokenHasReadWriteScope]

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        """
            show List of KillHouses for Province Operator To Manage
        """
        userprofile = SystemUserProfile.objects.get(
            user=request.user, trash=False
        )
        if 'show_poultry' in request.GET:
            kill_house_objects_list = []
            now = datetime.now().date()
            date = datetime.strptime(str(request.GET['date']),
                                     '%Y-%m-%d').date() if 'date' in request.GET else now
            # poultry = Poultry.objects.filter(user=userprofile).last()
            kill_house_objects = KillHouse.objects.filter(
                system_address__province=userprofile.province, trash=False
            )
            for kill_house_object in kill_house_objects:
                quantity_sum = 0
                poultry_quantity_sum = 0
                first_quantity = 0
                kill_req_key = None
                total_kill_request = KillRequest.objects.filter(kill_house=kill_house_object, recive_date__date=date,
                                                                trash=False, province_state__in=('pending', 'accepted'))

                kill_request = total_kill_request.filter(poultry__isnull=True, province_state='accepted').first()
                direct_buying_export_kill_request = total_kill_request.filter(poultry__isnull=False,
                                                                              province_state__in=(
                                                                                  'pending', 'accepted'))
                direct_buying_export_kill_request_quantity = \
                    direct_buying_export_kill_request.aggregate(total=Sum('kill_capacity'))[
                        'total'] or 0

                if kill_request:
                    # quantity_sum = kill_request.kill_capacity - (
                    #         kill_request.remain_quantity_for_poultry + direct_buying_export_kill_request_quantity)
                    quantity_sum = kill_request.kill_capacity - kill_request.remain_quantity_for_poultry
                    first_quantity = kill_request.kill_capacity
                    poultry_quantity_sum = kill_request.remain_quantity_for_poultry
                    kill_req_key = kill_request.key

                    kill_house_dict = {
                        "name": kill_house_object.name,
                        "killer": kill_house_object.killer,
                        "fullname": kill_house_object.kill_house_operator.user.fullname,
                        "quantity_sum": quantity_sum,
                        "first_quantity": first_quantity,
                        "poultry_quantity_sum": poultry_quantity_sum,
                        "kill_req_key": kill_req_key,
                    }
                    kill_house_objects_list.append(kill_house_dict)
            return Response(kill_house_objects_list, status=status.HTTP_200_OK)

        else:

            kill_house_objects = KillHouse.objects.filter(
                system_address__province=userprofile.province, trash=False
            )

        # Send Data To Serializer
        serializer = self.serializer_class(kill_house_objects, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ShareOfAllocationViewSet(viewsets.ModelViewSet):
    queryset = ShareOfAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ShareOfAllocationSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        share = self.queryset
        if share:
            share = share.last()
        else:
            share = ShareOfAllocation(province=user.province)
            share.save()
        serializer = ShareOfAllocationSerializer(share)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        share = ShareOfAllocation.objects.all().last()
        serializer = self.serializer_class(share)
        serializer.update(instance=share, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PaymentDeadLineViewSet(viewsets.ModelViewSet):
    queryset = PaymentDeadLine.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PaymentDeadLineSerializer


class MonthlyProfitPercentageViewSet(viewsets.ModelViewSet):
    queryset = MonthlyProfitPercentage.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = MonthlyProfitPercentageSerializer

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        queryset = MonthlyProfitPercentage.objects.all().last()
        serializer = MonthlyProfitPercentageSerializer(queryset)
        return Response(serializer.data, status=status.HTTP_200_OK)

    #
    # def create(self, request, *args, **kwargs):
    #     serializer = self.serializer_class(data=request.data)
    #     if serializer.is_valid():
    #         share = serializer.create(validated_data=request.data)
    #         serializer_request = self.serializer_class(ware_house_factor)
    #         return Response(serializer_request.data, status=status.HTTP_201_CREATED)
    #     return Response(serializer.errors)


def update_factor_total_price():
    factors = ProvinceFactorToKillHouse.objects.filter(
        province_check_info__kill_house_assignment__kill_house_request__province_kill_request__payment_type='credit',
        paid_state='pending')
    for factor in factors:
        total = factor.total_weight * factor.factor_fee
        factor.total_price += (total * 0.001)
        factor.save()
    return Response({"result": "factors updated"}, status=status.HTTP_200_OK)


class WalletViewset(viewsets.ModelViewSet):
    queryset = Wallet.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = walletSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            new_wallet = serializer.create(validated_data=request.data)
            new_wallet.save()
            w = self.serializer_class(new_wallet)
            return Response(w.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        queryset = self.queryset.get(key=request.GET['wallet_key'])
        transactions = Itransaction.objects.filter(wallet=queryset, state__in=("pending", "waiting")).order_by(
            'create_date')
        serializer = ItransactionSerializer(transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ItransactionViewset(viewsets.ModelViewSet):
    queryset = Itransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ItransactionSerializer

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        itransaction_list = []
        itransactions = Itransaction.objects.all()

        for transaction in itransactions:
            itransaction_list.append(transaction)

        t = ItransactionSerializer(itransaction_list, many=True)

        return Response(t.data, status.HTTP_200_OK)


class DebttViewset(viewsets.ModelViewSet):
    queryset = Debt.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DebtSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        wallet_receive = Wallet.objects.get(key=request.data['wallet_receive'])
        user_receive = SystemUserProfile.objects.get(key=request.data['user_key'])
        request.data.pop('wallet_receive')
        request.data.pop('user_key')
        image = request.data['image']
        request.data.pop('image')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            new_debt = serializer.create(validated_data=request.data)
            new_debt.image = send_image_to_server(image)
            # os.remove("{0}.jpg".format(str(ran)))

            itransactions = Itransaction.objects.filter(make_location_state='outside', wallet=wallet_receive).order_by(
                'create_date')
            if itransactions.count() > 0:
                itransactions = itransactions.last()
                payment_code = itransactions.payment_code + 1
            else:
                payment_code = int(str(user_receive.base_order) + '01')
            new_transaction = Itransaction(
                wallet=wallet_receive,
                transfer_amount=new_debt.cost,
                transaction_type='debtor',
                payment_code=payment_code
            )
            new_transaction.save()
            new_debt.itransaction = new_transaction
            new_debt.save()
            wallet_receive.inventory -= new_debt.cost
            wallet_receive.save()
            d = self.serializer_class(new_debt)
            return Response(d.data, status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        debt_list = []
        debts = Debt.objects.all()
        for debt in debts:
            debt_list.append(debt)
        d = DebtSerializer(debt_list, many=True)
        return Response(d.data, status=status.HTTP_200_OK)


class PenaltyViewset(viewsets.ModelViewSet):
    queryset = Penalty.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PenaltySerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        wallet_receive = Wallet.objects.get(key=request.data['wallet_id'])
        request.data.pop('wallet_id')
        user_receive = SystemUserProfile.objects.get(key=request.data['user_key'])
        request.data.pop('user_key')
        image = request.data['image']
        request.data.pop('image')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            new_penalty = serializer.create(validated_data=request.data)

            new_penalty.image = send_image_to_server(image)
            # os.remove("{0}.jpg".format(str(ran)))
            itransactions = Itransaction.objects.filter(make_location_state='outside',
                                                        wallet=wallet_receive).order_by('create_date')

            if itransactions.count() > 0:
                itransactions = itransactions.last()
                payment_code = itransactions.payment_code + 1
            else:
                payment_code = int(str(user_receive.base_order) + '01')

            new_transaction = Itransaction(
                wallet=wallet_receive,
                transfer_amount=new_penalty.cost,
                transaction_type='penalty',
                payment_code=payment_code
            )
            new_transaction.save()
            new_penalty.itransaction = new_transaction
            new_penalty.save()
            wallet_receive.inventory -= new_penalty.cost
            wallet_receive.save()
            p = self.serializer_class(new_penalty)
            return Response(p.data, status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        penalty_list = []
        penaltys = Penalty.objects.all()
        for penalty in penaltys:
            penalty_list.append(penalty)
        p = PenaltySerializer(penalty_list, many=True)
        return Response(p.data, status=status.HTTP_200_OK)


class DepositViewset(viewsets.ModelViewSet):
    queryset = Deposit.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = DepositSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        wallet_receive = Wallet.objects.get(key=request.data['wallet_key'])
        request.data.pop('wallet_key')
        user_receive = SystemUserProfile.objects.get(key=request.data['user_key'])
        request.data.pop('user_key')
        image = request.data['image']
        request.data.pop('image')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            new_deposit = serializer.create(validated_data=request.data)
            new_deposit.image = send_image_to_server(image)
            itransactions = Itransaction.objects.filter(make_location_state='outside',
                                                        wallet=wallet_receive).order_by('create_date')

            if itransactions.count() > 0:
                itransactions = itransactions.last()
                payment_code = itransactions.payment_code + 1
            else:
                payment_code = int(str(user_receive.base_order) + '01')
            new_transaction = Itransaction(
                wallet=wallet_receive,
                transfer_amount=new_deposit.cost,
                transaction_type='deposit',
                payment_code=payment_code
            )
            new_transaction.save()
            new_deposit.itransaction = new_transaction
            new_deposit.save()
            wallet_receive.inventory += new_deposit.cost
            wallet_receive.save()
            d = self.serializer_class(new_deposit)
            return Response(d.data, status.HTTP_201_CREATED)


class FinancialDocumentViewset(viewsets.ModelViewSet):
    queryset = FinancialDocument.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = FinancialDocumentSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        transaction_list = request.data['transaction_list']
        request.data.pop('transaction_list')
        user = SystemUserProfile.objects.get(id=request.data['user_id'])
        request.data.pop('user_id')
        if 'image' in request.data.keys():
            images = request.data['image']
            request.data.pop('image')
        else:
            images = None
        image_list = []

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            new_financial_document = serializer.create(validated_data=request.data)
            if images != None:
                for image in images:
                    image_list.append(send_image_to_server(image))

                new_financial_document.image = image_list

            for transaction in transaction_list:
                tr = Itransaction.objects.get(key=transaction)
                tr.state = "paid"
                tr.save()
            wallet = tr.wallet

            new_financial_document.wallet = wallet
            new_financial_document.transaction_details = transaction_list
            new_financial_document.save()
            if new_financial_document.type != 'zero':

                itransactions = Itransaction.objects.filter(file_id=0, wallet=wallet).order_by(
                    'create_date')
                if itransactions.count() > 0:
                    itransactions = itransactions.last()
                    payment_code = itransactions.payment_code + 1
                else:
                    payment_code = int(str(user.base_order) + '01')
                new_transaction = Itransaction(
                    wallet=wallet,
                    transfer_amount=new_financial_document.cost,
                    transaction_type=new_financial_document.type,
                    payment_code=payment_code,

                )
                new_transaction.save()
                new_financial_document.payment_code = payment_code
                new_financial_document.save()

            f = self.serializer_class(new_financial_document)
            return Response(f.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(id=request.GET['user_id'])
        if 'all' in request.GET:
            documents = FinancialDocument.objects.all()
            total_list = []
            if documents.count() > 0:
                for document in documents:
                    total_debtor = 0
                    total_creditor = 0
                    transactions = Itransaction.objects.filter(key__in=document.transaction_details)
                    payment_code = document.payment_code
                    if transactions.count() > 0:

                        for transaction in transactions:
                            if transaction.transaction_type == 'debtor' or transaction.transaction_type == 'penalty' or transaction.transaction_type == 'negative':
                                total_debtor += transaction.transfer_amount
                            elif transaction.transaction_type == "creditor" or transaction.transaction_type == 'deposit' or transaction.transaction_type == 'positive':
                                total_creditor += transaction.transfer_amount
                        inter_dict = {
                            "national_id": user.national_id,
                            "cost": document.cost,
                            "image": document.image,
                            "description": document.description,
                            "payment_code": payment_code,
                            "total_debtors": total_debtor,
                            "total_creditor": total_creditor
                        }
                        total_list.append(inter_dict)

        return Response(total_list, status=status.HTTP_200_OK)


class ReportingAllwalletRequestsViewset(viewsets.ModelViewSet):
    poultery_query = Poultry.objects.all()
    province_query = ProvinceOperator.objects.all()
    killhouse_query = KillHouseOperator.objects.all()
    vet_query = Vet.objects.all()
    city_query = CityOperator.objects.all()
    driver_query = KillHouseDriver.objects.all()
    inspector_query = InspectorOperator.objects.all()
    vet_query = Vet.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    poultry_filterset = PoultryFilterSet
    serializer_class = PoultrySerializer
    city_filterset = CityOperatorFilterSet
    province_filterset = ProvinceOperatorFilterSet
    killhouseoperator_filterset = KillHouseOperatorFilterSet
    killhousedriver_filterset = KillHouseDriverFilterSet
    inspector_filterset = InspectorOperatorFilterSet
    vet_filterset = VetFilterSet

    filterset_fields = [
        'user__mobile',
        'user__first_name',
        'user__last_name',
        'user__city__name',
        'user__province_name',
        'user__base_order',
        'user__national_id',

    ]

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

        total_list = []
        poultry_query_val = []
        province_query_val = []
        killhouse_query_val = []
        driver_query_val = []
        city_query_val = []
        inspector_query_val = []
        vet_query_val = []
        poultry_limited_dict = {}
        province_limited_dict = {}
        killhouse_limited_dict = {}
        city_limited_dict = {}
        driver_limited_dict = {}
        inspector_limited_dict = {}
        vet_limited_dict = {}
        province_limited_query = []
        killhouse_limited_query = []
        city_limited_query = []
        driver_limited_query = []
        inspector_limited_query = []
        values_item = []
        province_query_var = []
        killhouse_query_var = []
        city_query_var = []
        driver_query_var = []
        inspector_query_var = []
        vet_query_var = []
        poultry_limited_query = []
        vet_limited_query = []

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

                        if not province_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.province_filterset(data=query,
                                                            queryset=self.province_query)).filter():
                                    ps = self.province_filterset(data=query,
                                                                 queryset=self.province_query)
                                    filtered_province_operator = ps.filter()
                                    if filtered_province_operator:
                                        province_limited_query.append(query)

                        if not killhouse_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.killhouseoperator_filterset(data=query,
                                                                     queryset=self.killhouse_query)).filter():
                                    ps = self.killhouseoperator_filterset(data=query,
                                                                          queryset=self.killhouse_query)
                                    filtered_killhouse_operator = ps.filter()
                                    if filtered_killhouse_operator:
                                        killhouse_limited_query.append(query)

                        if not city_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.city_filterset(data=query,
                                                        queryset=self.city_query)).filter():
                                    ps = self.city_filterset(data=query,
                                                             queryset=self.city_query)
                                    filtered_city_operator = ps.filter()
                                    if filtered_city_operator:
                                        city_limited_query.append(query)

                        if not driver_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.killhousedriver_filterset(data=query,
                                                                   queryset=self.driver_query)).filter():
                                    ps = self.killhousedriver_filterset(data=query,
                                                                        queryset=self.city_query)
                                    filtered_driver = ps.filter()
                                    if filtered_driver:
                                        driver_limited_query.append(query)

                        if not inspector_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.inspector_filterset(data=query,
                                                             queryset=self.inspector_query)).filter():
                                    ps = self.inspector_filterset(data=query,
                                                                  queryset=self.inspector_query)
                                    filtered_inspector_operator = ps.filter()
                                    if filtered_inspector_operator:
                                        inspector_limited_query.append(query)

                        if not vet_query_var:
                            for item in self.filterset_fields:
                                query = QueryDict('{0}={1}'.format(item, val))
                                if (self.vet_filterset(data=query,
                                                       queryset=self.vet_query)).filter():
                                    ps = self.vet_filterset(data=query,
                                                            queryset=self.vet_query)
                                    filtered_vet = ps.filter()
                                    if filtered_vet:
                                        vet_limited_query.append(query)

                    for i in poultry_limited_query:
                        for key, value in i.items():
                            poultry_limited_dict[key] = value

                    if len(poultry_limited_dict) > 0:
                        for i in Poultry.objects.filter(**poultry_limited_dict):
                            poultry_query_val.append(i)

                        if len(poultry_query_val) > 0:
                            for poultry in poultry_query_val:
                                poulty_wallet = poultry.wallet
                                creditor = 0
                                debtor = 0
                                penalty = 0
                                deposit = 0
                                for i in Itransaction.objects.filter(wallet=poulty_wallet):
                                    if i.transaction_type == 'creditor':
                                        creditor += i.transfer_amount
                                    elif i.transaction_type == 'debtor':
                                        debtor += i.transfer_amount
                                    elif i.transaction_type == 'penalty':
                                        penalty += i.transfer_amount
                                    elif i.transaction_type == 'deposit':
                                        deposit += i.transfer_amount

                                internal_dict = {
                                    "base_orde": poultry.user.base_order,
                                    "fullname": poultry.user.fullname,
                                    "id": poultry.user.id,
                                    # "role": poultry.user.name,
                                    "mobile": poultry.user.mobile,
                                    "national_id": poultry.user.national_id,
                                    "wallet_key": poultry.wallet.key,
                                    "inventory": poultry.wallet.inventory,
                                    "city": poultry.user.city.name,
                                    "province": poultry.user.province.name,
                                    "creditor": creditor,
                                    "debtor": debtor,
                                    "penalty": penalty,
                                    "deposit": deposit,
                                    "depositable": (creditor + deposit) - (debtor + penalty)

                                }
                                total_list.append(internal_dict)

                    for i in province_limited_query:
                        for key, value in i.items():
                            province_limited_dict[key] = value
                    if len(province_limited_dict) > 0:
                        if len(values_item) == len(province_limited_dict):

                            for i in ProvinceOperator.objects.filter(**province_limited_dict):
                                province_query_val.append(i)

                            if len(province_query_val) > 0:
                                for province in province_query_val:
                                    province_wallet = province.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=province_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount
                                    internal_dict = {
                                        "base_orde": province.user.base_order,
                                        "fullname": province.user.fullname,
                                        "id": province.user.id,
                                        # "role": poultry.user.name,
                                        "mobile": province.user.mobile,
                                        "national_id": province.user.national_id,
                                        "wallet_key": province.wallet.key,
                                        "inventory": province.wallet.inventory,
                                        "city": province.user.city.name,
                                        "province": province.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                    for i in killhouse_limited_query:
                        for key, value in i.items():
                            killhouse_limited_dict[key] = value
                    if len(killhouse_limited_dict) > 0:
                        if len(values_item) == len(killhouse_limited_dict):

                            for i in KillHouseOperator.objects.filter(**killhouse_limited_dict):
                                killhouse_query_val.append(i)

                            if len(killhouse_query_val) > 0:
                                for killhouse in killhouse_query_val:
                                    killhouse_wallet = killhouse.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=killhouse_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount

                                    internal_dict = {
                                        "base_orde": killhouse.user.base_order,
                                        "fullname": killhouse.user.fullname,
                                        "id": killhouse.user.id,
                                        # "role": poultry.user.name,
                                        "mobile": killhouse.user.mobile,
                                        "national_id": killhouse.user.national_id,
                                        "wallet_key": killhouse.wallet.key,
                                        "inventory": killhouse.wallet.inventory,
                                        "city": killhouse.user.city.name,
                                        "province": killhouse.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                    for i in city_limited_query:
                        for key, value in i.items():
                            city_limited_dict[key] = value

                    if len(city_limited_dict) > 0:
                        if len(values_item) == len(city_limited_dict):

                            for i in CityOperator.objects.filter(**city_limited_dict):
                                city_query_val.append(i)

                            if len(city_query_val) > 0:
                                for city in city_query_val:
                                    city_wallet = city.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=city_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount

                                    internal_dict = {
                                        "base_orde": city.user.base_order,
                                        "fullname": city.user.fullname,
                                        "id": city.user.id,
                                        # "role": city.user.name,
                                        "mobile": city.user.mobile,
                                        "national_id": city.user.national_id,
                                        "wallet_key": city.wallet.key,
                                        "inventory": city.wallet.inventory,
                                        "city": city.user.city.name,
                                        "province": city.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                    for i in driver_limited_query:
                        for key, value in i.items():
                            driver_limited_dict[key] = value
                    if len(driver_limited_dict) > 0:
                        if len(values_item) == len(driver_limited_dict):

                            for i in KillHouseDriver.objects.filter(**driver_limited_dict):
                                driver_query_val.append(i)

                            if len(driver_query_val) > 0:
                                for driver in driver_query_val:
                                    driver_wallet = driver.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=driver_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount

                                    internal_dict = {
                                        "base_orde": driver.user.base_order,
                                        "fullname": driver.user.fullname,
                                        "id": driver.user.id,
                                        # "role": driver.user.name,
                                        "mobile": driver.user.mobile,
                                        "national_id": driver.user.national_id,
                                        "wallet_key": driver.wallet.key,
                                        "inventory": driver.wallet.inventory,
                                        "city": driver.user.city.name,
                                        "province": driver.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                    for i in inspector_limited_query:
                        for key, value in i.items():
                            inspector_limited_dict[key] = value
                    if len(inspector_limited_dict) > 0:
                        if len(values_item) == len(inspector_limited_dict):
                            for i in InspectorOperator.objects.filter(**inspector_limited_dict):
                                inspector_query_val.append(i)

                            if len(inspector_query_val) > 0:
                                for inspector in inspector_query_val:
                                    inspector_wallet = inspector.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=inspector_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount

                                    internal_dict = {
                                        "base_orde": inspector.user.base_order,
                                        "fullname": inspector.user.fullname,
                                        "id": inspector.user.id,
                                        # "role": inspector.user.name,
                                        "mobile": inspector.user.mobile,
                                        "national_id": inspector.user.national_id,
                                        "wallet_key": inspector.wallet.key,
                                        "inventory": inspector.wallet.inventory,
                                        "city": inspector.user.city.name,
                                        "province": inspector.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                    for i in vet_limited_query:
                        for key, value in i.items():
                            vet_limited_dict[key] = value
                    if len(vet_limited_dict) > 0:
                        if len(values_item) == len(vet_limited_dict):

                            for i in Vet.objects.filter(**vet_limited_dict):
                                vet_query_val.append(i)

                            if len(vet_query_val) > 0:
                                for vet in vet_query_val:
                                    vet_wallet = vet.wallet
                                    creditor = 0
                                    debtor = 0
                                    penalty = 0
                                    deposit = 0
                                    for i in Itransaction.objects.filter(wallet=vet_wallet):
                                        if i.transaction_type == 'creditor':
                                            creditor += i.transfer_amount
                                        elif i.transaction_type == 'debtor':
                                            debtor += i.transfer_amount
                                        elif i.transaction_type == 'penalty':
                                            penalty += i.transfer_amount
                                        elif i.transaction_type == 'deposit':
                                            deposit += i.transfer_amount

                                    internal_dict = {
                                        "base_orde": vet.user.base_order,
                                        "fullname": vet.user.fullname,
                                        "id": vet.user.id,
                                        # "role": vet.user.name,
                                        "mobile": vet.user.mobile,
                                        "national_id": vet.user.national_id,
                                        "wallet_key": vet.wallet.key,
                                        "inventory": vet.wallet.inventory,
                                        "city": vet.user.city.name,
                                        "province": vet.user.province.name,
                                        "creditor": creditor,
                                        "debtor": debtor,
                                        "penalty": penalty,
                                        "deposit": deposit,
                                        "depositable": (creditor + deposit) - (debtor + penalty)

                                    }
                                    total_list.append(internal_dict)

                return Response(total_list, status=status.HTTP_200_OK)


class FinancialTransactionViewset(viewsets.ModelViewSet):
    queryset = FinancialTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = FinancialTransactionSerializer

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

        wallet_receive = Wallet.objects.get(key=request.data['wallet_receive'])
        user = SystemUserProfile.objects.get(id=request.data['user_id'])
        user_system = SystemUserProfile.objects.get(user=request.user)
        request.data.pop('wallet_receive')
        request.data.pop('user_id')

        if 'image' in request.data.keys():
            images = request.data['image']
            request.data.pop('image')
        else:
            images = None
        image_list = []

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            finansial_transaction = serializer.create(validated_data=request.data)
            if images != None:
                for image in images:
                    image_list.append(send_image_to_server(image))

                finansial_transaction.image = image_list

            itransactions = Itransaction.objects.filter(file_id=0, wallet=wallet_receive).order_by(
                'create_date')
            if itransactions.count() > 0:
                itransactions = itransactions.last()
                payment_code = itransactions.payment_code + 1
            else:
                payment_code = int(user.base_order) + 1

            if finansial_transaction.type == 'deposit':

                # if user.id == user_system.id:
                new_transaction = Itransaction(
                    wallet=wallet_receive,
                    transfer_amount=finansial_transaction.cost,
                    transaction_type=finansial_transaction.type,
                    payment_code=payment_code,
                    state='waiting'
                )
            else:

                new_transaction = Itransaction(
                    wallet=wallet_receive,
                    transfer_amount=finansial_transaction.cost,
                    transaction_type=finansial_transaction.type,
                    payment_code=payment_code
                )
            new_transaction.save()
            finansial_transaction.itransaction = new_transaction
            finansial_transaction.save()
            new_object = self.serializer_class(finansial_transaction)
            return Response(new_object.data, status.HTTP_201_CREATED)

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

        if 'payment_code' in request.GET:
            transaction = Itransaction.objects.get(payment_code=int(request.GET['payment_code']))
            financial = FinancialTransaction.objects.get(itransaction=transaction)
            serializer = self.serializer_class(financial)

        else:

            query_list = []
            querys = FinancialTransaction.objects.filter(cost=0, trash=False)

            # for query in querys:
            #     query_list.append(query)

            serializer = self.serializer_class(querys)
        return Response(serializer.data, status.HTTP_200_OK)


class AdminViewset(viewsets.ModelViewSet):
    queryset = Admin.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AdminSerializer


class TypeCheckViewset(viewsets.ModelViewSet):
    queryset = Itransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ItransactionSerializer

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

        transaction = Itransaction.objects.get(key=request.data['transaction_key'])
        request.data.pop('transaction_key')
        state = request.data['state']
        request.data.pop('state')

        if state == 'accepted':
            transaction.state = 'pending'
            transaction.save()

        elif state == 'rejected':
            transaction.state = 'rejected'
            transaction.save()

        return Response(status=status.HTTP_200_OK)


class HourLimitViewset(viewsets.ModelViewSet):
    queryset = HourLimit.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = HourLimitSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            limit_hour = HourLimit.objects.all()
            if limit_hour.count() > 0:
                limit_hour = limit_hour.last()
                limit_hour.hour = request.data['hour']
                limit_hour.active = request.data['active']
                limit_hour.save()
            else:
                limit_hour = serializer.create(validated_data=request.data)

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        limit_hour = self.queryset.filter(trash=False).last()
        if limit_hour == None:
            limit_hour = HourLimit(hour=0)
            limit_hour.save()
        serializer = self.serializer_class(limit_hour)
        return Response(serializer.data, status.HTTP_200_OK)


class KillHouseHourLimitViewset(viewsets.ModelViewSet):
    queryset = KillHouseHourLimit.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillHouseHourLimitSerializer

    def create(self, request, *args, **kwargs):
        # refresh(request.user.id)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            limit_hour = KillHouseHourLimit.objects.all()
            if limit_hour.count() > 0:
                limit_hour = limit_hour.last()
                limit_hour.hour = request.data['hour']
                limit_hour.active = request.data['active']
                limit_hour.save()
            else:
                limit_hour = serializer.create(validated_data=request.data)

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        limit_hour = self.queryset.filter(trash=False).last()
        if limit_hour == None:
            limit_hour = KillHouseHourLimit(hour=0)
            limit_hour.save()
        serializer = self.serializer_class(limit_hour)
        return Response(serializer.data, status.HTTP_200_OK)


class SmsLicenseViewset(viewsets.ModelViewSet):
    queryset = SmsLicense.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SmsLicenseSerializer

    def create(self, request, *args, **kwargs):
        try:
            sms_license = SmsLicense.objects.latest('id')
        except SmsLicense.DoesNotExist:
            sms_license = None

        serializer = self.serializer_class(sms_license, data=request.data)
        if serializer.is_valid():
            serializer.save()
            status_code = status.HTTP_200_OK if sms_license else status.HTTP_201_CREATED
            return Response(serializer.data, status=status_code)
        else:
            return Response(serializer.errors)


class PoultryAllowCityProvinceViewset(viewsets.ModelViewSet):
    queryset = PoultryAllowCityProvince.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryAllowCityProvinceSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        poultries = Poultry.objects.filter(user=user)
        if poultries.count() > 0:
            for poultry in poultries:
                allow = PoultryAllowCityProvince.objects.filter(poultry=poultry)
                if allow.count() > 0:
                    allow = allow.last()
                    if request.data['city'] != None:
                        allow.city = request.data['city']
                    if request.data['province'] != None:
                        allow.province = request.data['province']
                    allow.save()
                else:
                    serializer = self.serializer_class(data=request.data)
                    if serializer.is_valid():
                        allow = serializer.create(validated_data=request.data)
                        allow.poultry = poultry
                        allow.save()
                        if allow.city == True:
                            # sms_allow_poultry_city_province_sms_sms = threading.Thread(
                            #     target=allow_poultry_city_province_sms,
                            #     args=(
                            #         poultry.user.mobile))
                            # sms_allow_poultry_city_province_sms_sms.start()

                            province_operator = ProvinceOperator.objects.filter(
                                user=SystemUserProfile.objects.get(role__name='ProvinceOperator',
                                                                   province=user.province))

                            if province_operator.count() > 0:
                                province_operator = province_operator.last()
                                sms_allow_poultry_city_province_sms_sms = threading.Thread(
                                    target=allow_poultry_city_province_sms,
                                    args=(
                                        province_operator.user.mobile, poultry.unit_name))
                                sms_allow_poultry_city_province_sms_sms.start()

                            sms_allow_poultry_city_for_poultry_sms_sms = threading.Thread(
                                target=allow_poultry_city_for_poultry_sms,
                                args=(
                                    poultry.user.mobile, poultry.unit_name))
                            sms_allow_poultry_city_for_poultry_sms_sms.start()
                        if allow.province == True:
                            province_operator = ProvinceOperator.objects.filter(
                                user=SystemUserProfile.objects.get(role__name='ProvinceOperator',
                                                                   province=user.province))

                            if province_operator.count() > 0:
                                province_operator = province_operator.last()
                                sms_allow_poultry_city_province_sms_sms = threading.Thread(
                                    target=allow_poultry_city_province_sms,
                                    args=(
                                        province_operator.user.mobile, poultry.unit_name))
                                sms_allow_poultry_city_province_sms_sms.start()

                                sms_allow_poultry_province_for_poultry_sms_sms = threading.Thread(
                                    target=allow_poultry_province_for_poultry_sms,
                                    args=(
                                        poultry.user.mobile, poultry.unit_name))
                                sms_allow_poultry_province_for_poultry_sms_sms.start()
            return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        poultries = Poultry.objects.filter(user=user)
        if poultries.count() > 0:
            poultries = poultries.last()
            allow = PoultryAllowCityProvince.objects.filter(poultry=poultries)
            serializer = self.serializer_class(allow, many=True)
            return Response(serializer.data, status.HTTP_200_OK)


class ProvinceAllowKillHouseRegisterCarViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseRegisterCar.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseRegisterCarSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        kill_house = KillHouse.objects.get(key=request.data['kill_house_key'])
        request.data.pop('kill_house_key')
        # for kill_house in kill_house_list:
        allow = ProvinceAllowKillHouseRegisterCar.objects.filter(kill_house=kill_house)
        if allow.count() > 0:
            allow = allow.last()
            allow.allow = request.data['allow']
            allow.save()

        else:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                allow = serializer.create(validated_data=request.data)
                allow.kill_house = kill_house
                allow.save()

        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)


def AllowKillHouseDirectBuying(allow_state, province):
    kill_houses = KillHouse.objects.filter(system_address__province__name=province, trash=False)
    for kill_house in kill_houses:
        allow = ProvinceAllowKillHouseDirectBuying.objects.filter(kill_house=kill_house).last()
        if allow:
            allow.allow = allow_state
            allow.save()
        else:
            allow = ProvinceAllowKillHouseDirectBuying(
                kill_house=kill_house,
                allow=allow_state,

            )
            allow.save()


class ProvinceAllowKillHouseDirectBuyingViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseDirectBuying.objects.all().order_by('id')
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseDirectBuyingSerializer

    def list(self, request, *args, **kwargs):
        if 'role' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            kill_house_direct = ProvinceAllowKillHouseDirectBuying.objects.get(trash=False, kill_house=kill_house)
            serializer = self.serializer_class(kill_house_direct)


        else:
            serializer = self.serializer_class(self.queryset, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        direct_buying = ProvinceAllowKillHouseDirectBuying.objects.get(key=request.data['direct_buying_key'],
                                                                       trash=False)
        request.data.pop('direct_buying_key')
        serializer = self.serializer_class(direct_buying)
        serializer.update(instance=direct_buying, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)
        # allow = request.data['allow']
        # request.data.pop('allow')
        # direct_buying.allow = allow
        # direct_buying.save()
        # return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)


class ProvinceAllowKillHouseDirectBuyingTotalViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseDirectBuyingTotal.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseDirectBuyingTotalSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        direct_buying_threading = threading.Thread(
            target=AllowKillHouseDirectBuying,
            args=(
                request.data['allow'],
                user.province.name))
        direct_buying_threading.start()
        direct_buying = ProvinceAllowKillHouseDirectBuyingTotal.objects.all()
        if direct_buying.count() > 0:
            direct_buying = direct_buying.last()
            direct_buying.allow = request.data['allow']
        else:
            direct_buying = ProvinceAllowKillHouseDirectBuyingTotal(
                allow=request.data['allow'],

            )
        direct_buying.save()

        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allow_state = False
        direct_buying = ProvinceAllowKillHouseDirectBuyingTotal.objects.all()
        if direct_buying.count() > 0:
            allow_state = direct_buying.last().allow

        return Response({"allow_state": allow_state}, status.HTTP_200_OK)


def AllowKillHouseRegisterguild(allow_state, province):
    kill_houses = KillHouse.objects.filter(system_address__province__name=province, trash=False)
    for kill_house in kill_houses:
        allow = ProvinceAllowKillHouseRegisterGuilds.objects.filter(kill_house=kill_house).last()
        if allow:
            allow.allow = allow_state
            allow.save()
        else:
            allow = ProvinceAllowKillHouseRegisterGuilds(
                kill_house=kill_house,
                allow=allow_state,

            )
            allow.save()


class ProvinceAllowKillHouseRegisterGuildsViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseRegisterGuilds.objects.all().order_by('id')
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseRegisterGuildsSerializer

    def update(self, request, *args, **kwargs):
        register_guilds = ProvinceAllowKillHouseRegisterGuilds.objects.get(key=request.data['register_guilds_key'],
                                                                           trash=False)
        request.data.pop('register_guilds_key')
        allow = request.data['allow']
        request.data.pop('allow')
        register_guilds.allow = allow
        register_guilds.save()
        return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)


class ProvinceAllowKillHouseRegisterGuildsTotalViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseRegisterGuildsTotal.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseRegisterGuildsTotalSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        register_guilds_threading = threading.Thread(
            target=AllowKillHouseRegisterguild,
            args=(
                request.data['allow'],
                user.province.name))
        register_guilds_threading.start()
        register_guilds = ProvinceAllowKillHouseRegisterGuildsTotal.objects.all()
        if register_guilds.count() > 0:
            register_guilds = register_guilds.last()
            register_guilds.allow = request.data['allow']
        else:
            register_guilds = ProvinceAllowKillHouseRegisterGuildsTotal(
                allow=request.data['allow'],

            )
        register_guilds.save()

        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        allow_state = False
        register_guilds = ProvinceAllowKillHouseRegisterGuildsTotal.objects.all()
        if register_guilds.count() > 0:
            allow_state = register_guilds.last().allow

        return Response({"allow_state": allow_state}, status.HTTP_200_OK)


def PoultryChooseKillHouse(allow_state, mandatory, province):
    poultries = Poultry.objects.filter(address__province__name=province, trash=False)
    for poultry in poultries:
        allow = ProvinceAllowPoultryChooseKillHouse.objects.filter(poultry=poultry)
        if allow.count() > 0:
            allow = allow.last()
            allow.allow = allow_state
            allow.mandatory = mandatory
            allow.save()

        else:
            allow = ProvinceAllowPoultryChooseKillHouse(
                poultry=poultry,
                allow=allow_state,

            )
            allow.save()


class ProvinceAllowPoultryChooseKillHouseViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowPoultryChooseKillHouse.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowPoultryChooseKillHouseSerializer

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

        poultry = Poultry.objects.get(key=request.data['poultry_key'], trash=False)
        request.data.pop('poultry_key')
        allow = request.data['allow']
        mandatory = request.data['mandatory']
        request.data.pop('allow')
        request.data.pop('mandatory')
        province_allow = ProvinceAllowPoultryChooseKillHouse.objects.filter(poultry=poultry, trash=False)
        if province_allow.count() > 0:
            province_allow = province_allow.last()
            province_allow.allow = allow
            province_allow.mandatory = mandatory
            province_allow.save()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)
        else:
            return Response({"result": "اجازه ای صادر نشده است !"}, status=status.HTTP_403_FORBIDDEN)


class ProvinceAllowPoultryChooseKillHouseTotalViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowPoultryChooseKillHouseTotal.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowPoultryChooseKillHouseTotalSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        PoultryChooseKillHouse_threading = threading.Thread(
            target=PoultryChooseKillHouse,
            args=(
                request.data['allow'],
                request.data['mandatory'],
                user.province.name))
        PoultryChooseKillHouse_threading.start()
        total_allow = ProvinceAllowPoultryChooseKillHouseTotal.objects.all()
        if total_allow.count() > 0:
            total_allow = total_allow.last()
            total_allow.allow = request.data['allow']
            total_allow.mandatory = request.data['mandatory']
        else:
            total_allow = ProvinceAllowPoultryChooseKillHouseTotal(
                allow=request.data['allow'],
                mandatory=request.data['mandatory']

            )
        total_allow.save()

        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        allow_state = False
        mandatory = False
        total_allow = ProvinceAllowPoultryChooseKillHouseTotal.objects.all()
        if total_allow.count() > 0:
            allow_state = total_allow.last().allow
            mandatory = total_allow.last().mandatory

        return Response({"allow_state": allow_state, "mandatory": mandatory}, status.HTTP_200_OK)


def PoultrySellFree(allow_state, province):
    poultries = Poultry.objects.filter(address__province__name=province, trash=False)
    for poultry in poultries:
        allow = ProvinceAllowPoultrySellFree.objects.filter(poultry=poultry)
        if allow.count() > 0:
            allow = allow.last()
            allow.allow = allow_state
            allow.save()

        else:
            allow = ProvinceAllowPoultrySellFree(
                poultry=poultry,
                allow=allow_state,

            )
            allow.save()


def KillHouseChooseSteward(steward, guilds, province):
    kill_houses = KillHouse.objects.filter(system_address__province__name=province, trash=False)
    for kill_house in kill_houses:
        choose = ProvinceAllowKillHouseChooseStewardGuilds.objects.filter(kill_house=kill_house).last()
        if choose:
            choose.steward = steward
            choose.guilds = guilds
            choose.save()

        else:
            choose = ProvinceAllowKillHouseChooseStewardGuilds(
                kill_house=kill_house,
                steward=steward,
                guilds=guilds,

            )
            choose.save()


class ProvinceAllowPoultrySellFreeViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowPoultrySellFree.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowPoultrySellFreeSerializer

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

        poultry = Poultry.objects.get(key=request.data['poultry_key'], trash=False)
        request.data.pop('poultry_key')
        allow = request.data['allow']
        request.data.pop('allow')
        province_allow = ProvinceAllowPoultrySellFree.objects.filter(poultry=poultry, trash=False)
        if province_allow.count() > 0:
            province_allow = province_allow.last()
            province_allow.allow = allow
            province_allow.save()
        else:
            province_allow = ProvinceAllowPoultrySellFree(
                poultry=poultry,
                allow=allow
            )
            province_allow.save()

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


def FreeSaleWithinprovinceThreadByWeight(weight, province):
    hatchings = PoultryHatching.objects.filter(poultry__address__province__name=province, archive=False,
                                               allow_hatching='pending', state='pending', trash=False)
    for hatching in hatchings:
        hatching.total_commitment = hatching.quantity * weight
        hatching.total_commitment_quantity = 0
        hatching.save()


def FreeSaleWithinprovinceThreadByPercent(percent, province):
    hatchings = PoultryHatching.objects.filter(poultry__address__province__name=province, archive=False,
                                               allow_hatching='pending', state='pending', trash=False)
    for hatching in hatchings:
        # hatching.total_commitment_quantity = hatching.quantity * (percent / 100)
        hatching.total_commitment_quantity = int((hatching.quantity - hatching.total_losses) * (percent / 100))
        hatching.total_free_commitment_quantity = (
                                                          hatching.quantity - hatching.total_losses) - hatching.total_commitment_quantity
        hatching.total_commitment = 0
        hatching.save()


def FreeCommitmentThread(province):
    hatchings = PoultryHatching.objects.filter(poultry__address__province__name=province, archive=False,
                                               allow_hatching='pending', state='pending', trash=False)
    for hatching in hatchings:
        hatching.total_free_commitment_quantity = hatching.quantity - hatching.total_losses
        hatching.total_commitment = 0
        hatching.total_commitment_quantity = 0
        hatching.commitment_type = "free"
        hatching.save()


class FreeSaleWithinprovinceViewset(viewsets.ModelViewSet):
    queryset = FreeSaleWithinprovince.objects.all()
    permission_classes = [AllowAny]
    serializer_class = FreeSaleWithinprovinceSerializer

    def list(self, request, *args, **kwargs):
        free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
        if not free_sale_province:
            free_sale_province = FreeSaleWithinprovince()
            free_sale_province.save()
        serializer = self.serializer_class(free_sale_province)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        free_sale = FreeSaleWithinprovince.objects.get(key=request.data['free_sale_key'], trash=False)
        request.data.pop('free_sale_key')
        if request.data['allow'] == True:
            approved_price = ApprovedPrice.objects.filter(trash=False).first()
            if approved_price.approved == False:
                return Response({"result": "برای فعال کردن تعهد دولتی ابتدا قیمت مصوب مرغ زنده را فعال کنید!"},
                                status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(free_sale)
        serializer.update(instance=free_sale, validated_data=request.data)
        if request.data['allow'] == True and 'type' in request.data.keys():
            if request.data['type'] == 'weight':
                FreeSaleWithinprovince_threading_weight = threading.Thread(
                    target=FreeSaleWithinprovinceThreadByWeight,
                    args=(
                        request.data['weight'],
                        user.province.name))
                FreeSaleWithinprovince_threading_weight.start()
            else:
                FreeSaleWithinprovince_threading_percent = threading.Thread(
                    target=FreeSaleWithinprovinceThreadByPercent,
                    args=(
                        request.data['percent'],
                        user.province.name))
                FreeSaleWithinprovince_threading_percent.start()

        else:
            FreeCommitmentThread_Threading = threading.Thread(
                target=FreeCommitmentThread,
                args=(user.province.name,))

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


class ProvinceAllowPoultrySellFreeTotalViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowPoultrySellFreeTotal.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowPoultrySellFreeTotalSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        PoultrySellFree_threading = threading.Thread(
            target=PoultrySellFree,
            args=(
                request.data['allow'],
                user.province.name))
        PoultrySellFree_threading.start()
        total_allow = ProvinceAllowPoultrySellFreeTotal.objects.all()
        if total_allow.count() > 0:
            total_allow = total_allow.last()
            total_allow.allow = request.data['allow']
        else:
            total_allow = ProvinceAllowPoultrySellFreeTotal(
                allow=request.data['allow']

            )
        total_allow.save()

        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        allow_state = False
        total_allow = ProvinceAllowPoultrySellFreeTotal.objects.all()
        if total_allow.count() > 0:
            allow_state = total_allow.last().allow

        return Response(allow_state, status.HTTP_200_OK)


def AutoAcceptMakeRequest(province_kill_request_list):
    allow = False
    if AutoMakeKillHouseRequest.objects.filter(allow=True).exists():
        allow = True
    province_kill_requests = ProvinceKillRequest.objects.filter(key__in=province_kill_request_list,
                                                                trash=False).select_related('killhouse_user',
                                                                                            'kill_request',
                                                                                            'province_request')

    for province_kill_request in province_kill_requests:
        kill_house_check = KillHouseCheckRequest(
            province_kill_request=province_kill_request,
            role="ProvinceOperator",
            state="accepted"

        )
        kill_house_check.save()
        province_kill_request.state = 'accepted'
        province_kill_request.save()
        if allow == True:
            user = province_kill_request.province_request.city_request_Poultry.poultry_request.poultry.user
            if province_kill_request.kill_request.slaughter_house != None:
                kill_house = province_kill_request.kill_request.slaughter_house
            else:
                kill_house = province_kill_request.kill_request.kill_house

            car = KillHouseADDCAR.objects.filter(kill_house=kill_house, trash=False).first()
            bar_code = KillHouseRequest.objects.filter(
                province_request__city_request_Poultry__poultry_request__poultry__user=user, trash=False).order_by(
                'create_date')
            if bar_code.count() > 0:
                if bar_code.last().bar_code != None:
                    bar_code_number = bar_code.last().bar_code + 1
            else:
                bar_code_number = int(
                    str(province_kill_request.province_request.city_request_Poultry.poultry_request.order_code) + '0001')
            if car:
                kill_house_request = KillHouseRequest(
                    killhouse_user=province_kill_request.killhouse_user,
                    kill_request=province_kill_request.kill_request,
                    province_request=province_kill_request.province_request,
                    province_kill_request=province_kill_request,
                    bar_code=bar_code_number,
                    quantity=province_kill_request.quantity,
                    capacity=province_kill_request.quantity,
                    add_car=car,
                    state='accepted',

                )
                kill_house_request.save()
                province_kill_request.quantity = 0
                province_kill_request.save()


class ProvinceAutoAllocationViewset(viewsets.ModelViewSet):
    queryset = ProvinceAutoAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAutoAllocationSerializer

    def create(self, request, *args, **kwargs):
        debt = False
        filter_list = request.data['filter_list']
        for first_item in filter_list:
            if 'minimum_allocation' in first_item:
                minimum_allocation = int(first_item['minimum_allocation'])
                del first_item['minimum_allocation']
            else:
                minimum_allocation = 0

            if 'no_debt' in first_item:
                debt = True
                del first_item['no_debt']

        filter_list_keys = []
        request.data.pop('filter_list')
        now = datetime.strptime(str(request.data['date']), '%Y-%m-%d')
        request.data.pop('date')

        for item in filter_list:
            filter_list_keys.extend(item.keys())
        if 'city' in filter_list_keys or 'kill_place' in filter_list_keys:
            pass
        else:
            return Response({"result": "باید یکی از پارامتر های شهر یا محل کشتار را انتخاب کنید"},
                            status=status.HTTP_403_FORBIDDEN)

        now = now + timedelta(hours=14, minutes=30, seconds=45)
        quantity_sum = 0
        allocation_order_code = ProvinceAutoAllocation.objects.filter(trash=False).order_by('id')
        allocation_order_code_number = allocation_order_code.last().allocation_order_code + 1 if allocation_order_code.count() > 0 else 1000
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        poultry_requests = PoultryRequest.objects.filter(
            trash=False,
            province_state='accepted',
            final_state='pending',
            send_date__year=now.year,
            send_date__month=now.month,
            send_date__day=now.day,
            remain_quantity__gt=0,
            poultry__address__province=user.province
        ).order_by('-quantity')

        quantity_sum = poultry_requests.aggregate(total_quantity=Sum('remain_quantity')).get('total_quantity', 0)
        if quantity_sum == None:
            return Response({"result": "تعداد درخواست کشتار ها صفر است"}, status=status.HTTP_403_FORBIDDEN)
        else:
            percentages = KillHousePercentage.objects.filter(trash=False,
                                                             kill_house__system_address__province=user.province,
                                                             percent__gt=0).order_by(
                '-percent')
            add_quantity = 0
            for kill_house_percentage in percentages:

                kill_request_quantity = (kill_house_percentage.percent / 100) * quantity_sum
                if kill_request_quantity.is_integer():
                    kill_request_quantity = (kill_house_percentage.percent / 100) * quantity_sum
                else:
                    kill_request_quantity = math.ceil((kill_house_percentage.percent / 100) * quantity_sum)

                kill_request = KillRequest(
                    kill_house=kill_house_percentage.kill_house,
                    kill_capacity=kill_request_quantity,
                    remain_quantity=kill_request_quantity,
                    recive_time='14 - 16',
                    province_state='accepted',
                    automatic=True,
                    recive_date=now
                )
                kill_request.save()

                if debt == True:
                    if KillHouseFactorToProvince.objects.filter(
                            province_factor__province_check_info__kill_house_assignment__kill_house_request__killhouse_user=kill_request.kill_house,
                            state='pending').exists():
                        kill_request.automatic_debt = True
                        kill_request.save()

                price = Pricing.objects.all()
                if price.count() > 0:
                    price = price.last()
                    factor = KillRequestFactor(
                        kill_request=kill_request,
                        amount=round(
                            (kill_request.kill_capacity * 2.7) * price.live_chicken_price,
                            0),
                        minimum_amount=round(
                            ((kill_request.kill_capacity * 2.7) * price.live_chicken_price) * (
                                    70 / 100),
                            0)

                    )
                    factor.save()
                    kill_request.factor_amount = factor.amount
                    kill_request.save()

                kill_house_daily_quota = KillHouseDailyQuota(
                    kill_house=kill_house_percentage.kill_house,
                    kill_request=kill_request,
                    percent=kill_house_percentage.percent,
                    quantity=kill_request_quantity,
                    remain_quantity=kill_request_quantity,
                )
                kill_house_daily_quota.save()
                if kill_house_percentage.kill_house_for_killer != None:
                    kill_request.slaughter_house = kill_house_percentage.kill_house_for_killer
                    kill_request.save()
                    kill_house_daily_quota.killer_kill_house = kill_house_percentage.kill_house_for_killer
                    kill_house_daily_quota.save()
            # if add_quantity > 0 :
            #     daily_quotas_lists = KillHouseDailyQuota.objects.filter(trash=False, create_date__day=now.day,
            #                                                             create_date__month=now.month,
            #                                                             create_date__year=now.year).order_by(
            #         '-quantity')
            #     for daily in daily_quotas_lists:
            #         daily_quta=math.ceil((daily.percent/100) * add_quantity)
            #         # if daily_quta.is_integer():
            #         #     daily_quta = daily_quta
            #         # else:
            #         #     daily_quta = math.ceil(daily_quta)
            #         daily.quantity += daily_quta
            #         daily.save()
            #         daily.kill_request.kill_capacity +=daily_quta
            #         daily.kill_request.remain_quantity +=daily_quta
            #         daily.kill_request.save()

        total_kill_house_daily_list = []
        for filter_key in filter_list_keys:
            daily_quotas_lists = KillHouseDailyQuota.objects.filter(trash=False, create_date__day=now.day,
                                                                    create_date__month=now.month,
                                                                    create_date__year=now.year).order_by(
                '-quantity')
            if filter_key == 'kill_place' or filter_key == 'city':

                if len(total_kill_house_daily_list) == 0:
                    for poultry_request in poultry_requests:
                        if poultry_request.remain_quantity == 0:
                            continue
                        for daily_quotas_list in daily_quotas_lists:
                            if daily_quotas_list.killer_kill_house != None:
                                city = daily_quotas_list.killer_kill_house.system_address.city
                                if city == poultry_request.poultry.address.city:
                                    if daily_quotas_list not in total_kill_house_daily_list:
                                        for daily_quotas_list_kill_house_internal in daily_quotas_lists:
                                            if daily_quotas_list_kill_house_internal.kill_house == daily_quotas_list.killer_kill_house:
                                                if daily_quotas_list_kill_house_internal not in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(
                                                        daily_quotas_list_kill_house_internal)
                                                    # break
                                        total_kill_house_daily_list.append(daily_quotas_list)
                                        for daily_quotas_list_first_internal in daily_quotas_lists:
                                            if daily_quotas_list_first_internal.killer_kill_house == daily_quotas_list.killer_kill_house:
                                                if not daily_quotas_list_first_internal in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(
                                                        daily_quotas_list_first_internal)
                                    else:
                                        continue
                            else:
                                if daily_quotas_list.kill_house.system_address.city == poultry_request.poultry.address.city:
                                    if daily_quotas_list not in total_kill_house_daily_list:
                                        total_kill_house_daily_list.append(daily_quotas_list)
                                        for daily_quotas_list_internal in daily_quotas_lists:
                                            if daily_quotas_list_internal.killer_kill_house == daily_quotas_list.killer_kill_house:
                                                if not daily_quotas_list_internal in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(daily_quotas_list_internal)
                                    else:
                                        continue
                    for daily_quotas_remain_list in daily_quotas_lists:
                        if daily_quotas_remain_list not in total_kill_house_daily_list:
                            total_kill_house_daily_list.append(daily_quotas_remain_list)



                else:
                    internal_kill_place_list = total_kill_house_daily_list
                    total_kill_house_daily_list = []
                    for poultry_request in poultry_requests:
                        if poultry_request.remain_quantity == 0:
                            continue

                        for internal_daily_quotas_list in internal_kill_place_list:
                            if internal_daily_quotas_list.killer_kill_house != None:
                                city = internal_daily_quotas_list.killer_kill_house.system_address.city
                                if city == poultry_request.poultry.address.city:
                                    if internal_daily_quotas_list not in total_kill_house_daily_list:
                                        for daily_quotas_list_kill_house_internal_second in internal_kill_place_list:
                                            if daily_quotas_list_kill_house_internal_second.kill_house == internal_daily_quotas_list.killer_kill_house:
                                                if daily_quotas_list_kill_house_internal_second not in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(
                                                        daily_quotas_list_kill_house_internal_second)
                                                # break
                                        total_kill_house_daily_list.append(internal_daily_quotas_list)
                                        for internal_daily_quotas_list_first in daily_quotas_lists:
                                            if internal_daily_quotas_list_first.killer_kill_house == internal_daily_quotas_list.killer_kill_house or internal_daily_quotas_list_first.kill_house == internal_daily_quotas_list.killer_kill_house:
                                                if not internal_daily_quotas_list_first in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(
                                                        internal_daily_quotas_list_first)
                                    else:
                                        continue
                            else:
                                if internal_daily_quotas_list.kill_house.system_address.city == poultry_request.poultry.address.city:
                                    if internal_daily_quotas_list not in total_kill_house_daily_list:
                                        total_kill_house_daily_list.append(internal_daily_quotas_list)
                                        for daily_quotas_list_internal_second in internal_kill_place_list:
                                            if daily_quotas_list_internal_second.killer_kill_house == internal_daily_quotas_list.killer_kill_house:
                                                if not daily_quotas_list_internal_second in total_kill_house_daily_list:
                                                    total_kill_house_daily_list.append(
                                                        daily_quotas_list_internal_second)
                                    else:
                                        continue

                    for internal_daily_quotas_remain_list in internal_kill_place_list:
                        if internal_daily_quotas_remain_list not in total_kill_house_daily_list:
                            total_kill_house_daily_list.append(internal_daily_quotas_remain_list)

            for poultry_request in poultry_requests:

                if poultry_request.remain_quantity == 0:
                    continue
                province_ckeck = ProvinceCheckOperatorRequest.objects.get(poultry_request=poultry_request)

                for kill_house_daily in total_kill_house_daily_list:
                    kill_request = KillRequest.objects.get(key=kill_house_daily.kill_request.key, trash=False)

                    if kill_request.remain_quantity == 0:
                        continue

                    if poultry_request.remain_quantity == 0:
                        continue
                    if kill_house_daily.killer_kill_house != None:
                        city = kill_house_daily.killer_kill_house.system_address.city
                    else:
                        city = kill_house_daily.kill_house.system_address.city

                    if city != poultry_request.poultry.address.city:
                        continue
                    if kill_request.remain_quantity > poultry_request.remain_quantity:
                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=poultry_request.remain_quantity,
                            main_quantity=poultry_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()
                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=poultry_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        kill_request.remain_quantity -= poultry_request.remain_quantity
                        kill_request.save()
                        poultry_request.remain_quantity = 0
                        poultry_request.save()
                        province_ckeck.quantity = 0
                        province_ckeck.save()
                    elif kill_request.remain_quantity == poultry_request.remain_quantity:

                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=poultry_request.remain_quantity,
                            main_quantity=poultry_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()
                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=poultry_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        kill_request.remain_quantity = 0
                        kill_request.save()
                        poultry_request.remain_quantity = 0
                        poultry_request.save()
                        province_ckeck.quantity = 0
                        province_ckeck.save()
                    else:
                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=kill_request.remain_quantity,
                            main_quantity=kill_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()

                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=kill_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        poultry_request.remain_quantity -= kill_request.remain_quantity
                        poultry_request.save()
                        province_ckeck.quantity -= kill_request.remain_quantity
                        province_ckeck.save()
                        kill_request.remain_quantity = 0
                        kill_request.save()

            for poultry_request in poultry_requests:

                if poultry_request.remain_quantity == 0:
                    continue
                province_ckeck = ProvinceCheckOperatorRequest.objects.get(poultry_request=poultry_request)

                for kill_house_daily in total_kill_house_daily_list:
                    kill_request = KillRequest.objects.get(key=kill_house_daily.kill_request.key, trash=False)

                    if kill_request.remain_quantity == 0:
                        continue

                    if poultry_request.remain_quantity == 0:
                        continue
                    if kill_request.remain_quantity > poultry_request.remain_quantity:
                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=poultry_request.remain_quantity,
                            main_quantity=poultry_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()
                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=poultry_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        kill_request.remain_quantity -= poultry_request.remain_quantity
                        kill_request.save()
                        poultry_request.remain_quantity = 0
                        poultry_request.save()
                        province_ckeck.quantity = 0
                        province_ckeck.save()
                    elif kill_request.remain_quantity == poultry_request.remain_quantity:

                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=poultry_request.remain_quantity,
                            main_quantity=poultry_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()
                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=poultry_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        kill_request.remain_quantity = 0
                        kill_request.save()
                        poultry_request.remain_quantity = 0
                        poultry_request.save()
                        province_ckeck.quantity = 0
                        province_ckeck.save()
                    else:
                        province_kill_request = ProvinceKillRequest(
                            killhouse_user=kill_request.kill_house,
                            dont_show_kill_house=True,
                            kill_request=kill_request,
                            province_request=province_ckeck,
                            quantity=kill_request.remain_quantity,
                            main_quantity=kill_request.remain_quantity,
                            automatic=True,

                        )
                        province_kill_request.save()

                        allocation = ProvinceAutoAllocation(
                            daily_quota=kill_house_daily,
                            poultry_request=poultry_request,
                            quantity=kill_request.remain_quantity,
                            allocation_order_code=allocation_order_code_number,
                            province_kill_request=province_kill_request,

                        )
                        allocation.save()
                        if minimum_allocation > 0 and allocation.quantity < minimum_allocation:
                            allocation.unauthorized_number = True
                            allocation.save()
                        poultry_request.remain_quantity -= kill_request.remain_quantity
                        poultry_request.save()
                        province_ckeck.quantity -= kill_request.remain_quantity
                        province_ckeck.save()
                        kill_request.remain_quantity = 0
                        kill_request.save()

        return Response({"result": "تخصیص اتوماتیک با موفقیت انجام شد."}, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        # refresh(request.user.id)
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        now = datetime.now().date()
        poultry_requests_list = []
        date1 = datetime.strptime(str(request.GET['date1']),
                                  '%Y-%m-%d').date() if 'date1' in request.GET else now
        date2 = datetime.strptime(str(request.GET['date2']),
                                  '%Y-%m-%d').date() if 'date2' in request.GET else now
        poultry_requests_lists = PoultryRequest.objects.filter(
            trash=False,
            province_state='accepted',
            final_state='pending',
            poultry__address__province=user.province
        ).order_by('-quantity')
        poultry_requests = [
            poultry_request_list for poultry_request_list in poultry_requests_lists
            if date1 <= poultry_request_list.send_date.date() <= date2
        ]
        if len(poultry_requests) > 0:
            if request.GET['state'] == 'temporary':

                for poultry_request in poultry_requests:
                    allocations_sum = 0
                    province_kill_requests = ProvinceKillRequest.objects.filter(
                        province_request__poultry_request=poultry_request, trash=False,
                        state__in=('pending', 'accepted'), automatic=False)
                    if province_kill_requests.count() > 0:
                        for province_kill_request in province_kill_requests:
                            allocations_sum += province_kill_request.main_quantity
                    poultry_request_dict = {
                        "poultry_user_fullname": poultry_request.poultry.user.fullname,
                        "poultry_key": poultry_request.key,
                        "poultry_mobile": poultry_request.poultry.user.mobile,
                        "poultry_name": poultry_request.poultry.unit_name,
                        "poultry_address": poultry_request.poultry.address.city.name,
                        "poultry_quantity": poultry_request.quantity,
                        "poultry_request_index_weight": poultry_request.Index_weight,
                        "poultry_request_weight": poultry_request.quantity * poultry_request.Index_weight,
                        "poultry_request_key": poultry_request.key,
                        "poultry_remain_quantity": poultry_request.remain_quantity,
                    }
                    allocations_list = []
                    allocations = ProvinceAutoAllocation.objects.filter(poultry_request=poultry_request,
                                                                        state='temporary', trash=False)
                    if allocations.count() > 0:

                        for allocation in allocations:
                            allocations_sum += allocation.quantity
                            if allocation.daily_quota.killer_kill_house != None:
                                Killing_place = allocation.daily_quota.killer_kill_house.name
                                buyer_address = allocation.daily_quota.killer_kill_house.system_address.city.name
                            else:
                                Killing_place = allocation.daily_quota.kill_house.name
                                buyer_address = allocation.daily_quota.kill_house.system_address.city.name
                            allocation_dict = {
                                "allocation_key": allocation.key,
                                "type": allocation.daily_quota.kill_house.killer,
                                "buyer_name": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
                                "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
                                "buyer_address": buyer_address,
                                "allocation_quantity": allocation.quantity,
                                "allocation_weight": allocation.quantity * poultry_request.Index_weight,
                                "allocation_percent": allocation.daily_quota.percent,
                                "unauthorized_number": allocation.unauthorized_number,
                                "Killing_place": Killing_place,
                                "debt": allocation.daily_quota.kill_request.automatic_debt,
                            }

                            allocations_list.append(allocation_dict)

                        poultry_request_dict.update({
                            "allocations": allocations_list,
                            "allocations_sum": allocations_sum,
                        })
                        poultry_requests_list.append(poultry_request_dict)
                return Response(poultry_requests_list, status=status.HTTP_200_OK)
            # return Response({"result": "تعدادی برای تخصیص وجود ندارد!"}, status=status.HTTP_200_OK)

            else:
                allocation_order_code_list = []
                final_allocation_list = []
                for poultry_request in poultry_requests:
                    allocations = ProvinceAutoAllocation.objects.filter(poultry_request=poultry_request,
                                                                        state='final_registration', trash=False)
                    if allocations.count() > 0:
                        for allocation in allocations:
                            if allocation.allocation_order_code in allocation_order_code_list:
                                pass
                            else:
                                allocation_order_code_list.append(allocation.allocation_order_code)

                if len(allocation_order_code_list) > 0:
                    for allocation_order_code in sorted(allocation_order_code_list):
                        poultry_requests_list = []
                        kill_house_list = []
                        poultry_list = []
                        allocated_quantity = 0
                        total_quantity = 0
                        internal_allocation_dict = {
                            "allocation_order_code": allocation_order_code,
                            "allocation_date": allocation_order_code,
                        }

                        for poultry_request in poultry_requests:
                            if poultry_request.poultry in poultry_list:
                                pass
                            else:
                                poultry_list.append(poultry_request.poultry)
                            allocations_sum = 0
                            total_quantity += poultry_request.quantity
                            province_kill_requests = ProvinceKillRequest.objects.filter(
                                province_request__poultry_request=poultry_request, trash=False,
                                state__in=('pending', 'accepted'), automatic=False)
                            if province_kill_requests.count() > 0:
                                for province_kill_request in province_kill_requests:
                                    allocations_sum += province_kill_request.main_quantity
                            poultry_request_dict = {
                                "poultry_user_fullname": poultry_request.poultry.user.fullname,
                                "poultry_mobile": poultry_request.poultry.user.mobile,
                                "poultry_name": poultry_request.poultry.unit_name,
                                "poultry_address": poultry_request.poultry.address.city.name,
                                "poultry_quantity": poultry_request.quantity,
                                "poultry_request_key": poultry_request.key,
                                "poultry_request_index_weight": poultry_request.Index_weight,
                                "poultry_request__weight": poultry_request.quantity * poultry_request.Index_weight,
                                "poultry_remain_quantity": poultry_request.remain_quantity,
                            }
                            allocations_list = []
                            allocations = ProvinceAutoAllocation.objects.filter(poultry_request=poultry_request,
                                                                                state='final_registration',
                                                                                allocation_order_code=allocation_order_code,
                                                                                trash=False)
                            if allocations.count() > 0:

                                for allocation in allocations:
                                    debt = False
                                    if allocation.daily_quota.kill_house in kill_house_list:
                                        pass
                                    else:
                                        kill_house_list.append(allocation.daily_quota.kill_house)
                                    allocation_date = str(allocation.create_date.date())
                                    allocations_sum += allocation.quantity
                                    if allocation.daily_quota.killer_kill_house != None:
                                        Killing_place = allocation.daily_quota.killer_kill_house.name
                                        buyer_address = allocation.daily_quota.killer_kill_house.system_address.city.name

                                    else:
                                        Killing_place = allocation.daily_quota.kill_house.name
                                        buyer_address = allocation.daily_quota.kill_house.system_address.city.name

                                    # if KillHouseFactorToProvince.objects.filter(
                                    #         province_factor__province_check_info__kill_house_assignment__kill_house_request__killhouse_user=allocation.daily_quota.kill_house,
                                    #         state='pending').exists():

                                    allocation_dict = {
                                        "allocation_key": allocation.key,
                                        "type": allocation.daily_quota.kill_house.killer,
                                        "buyer_name": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
                                        "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
                                        "buyer_address": buyer_address,
                                        "allocation_quantity": allocation.quantity,
                                        "allocation_weight": allocation.quantity * poultry_request.Index_weight,
                                        "allocation_percent": allocation.daily_quota.percent,
                                        "Killing_place": Killing_place,
                                        "debt": allocation.daily_quota.kill_request.automatic_debt,
                                        "unauthorized_number": allocation.unauthorized_number,
                                    }

                                    allocations_list.append(allocation_dict)

                                poultry_request_dict.update({
                                    "allocations": allocations_list,
                                    "allocations_sum": allocations_sum,
                                })
                                poultry_requests_list.append(poultry_request_dict)
                                allocated_quantity += allocations_sum
                        internal_allocation_dict.update({"allocations_list": poultry_requests_list,
                                                         "allocation_date": allocation.create_date,
                                                         "allocated_quantity": allocated_quantity,
                                                         "total_quantity": total_quantity,
                                                         "number_of_poultry": len(poultry_list),
                                                         "number_of_kill_house": len(kill_house_list)})
                        final_allocation_list.append(internal_allocation_dict)

                return Response(final_allocation_list, status=status.HTTP_200_OK)
        else:
            if request.GET['state'] == 'temporary':
                return Response({"result": "تعدادی برای تخصیص وجود ندارد!"}, status=status.HTTP_200_OK)
            else:
                return Response([], status=status.HTTP_200_OK)
                # return Response({"result": "تعدادی برای بایگانی وجود ندارد!"}, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        if 'allocation_list' in request.data.keys():

            allocation_lists = request.data['allocation_list']
            request.data.pop('allocation_list')
            daily_quota_objects = []
            allocation_objects = []
            for allocation_list in allocation_lists:
                allocation = ProvinceAutoAllocation.objects.get(key=allocation_list["allocationKey"], trash=False)
                poultry_request = PoultryRequest.objects.get(key=allocation.poultry_request.key, trash=False)
                province_check = ProvinceCheckOperatorRequest.objects.get(poultry_request=poultry_request)
                if allocation.quantity > allocation_list["allocationQuantity"]:
                    province_check.quantity += allocation.quantity - allocation_list["allocationQuantity"]
                    poultry_request.remain_quantity += allocation.quantity - allocation_list["allocationQuantity"]
                    province_check.save()
                    poultry_request.save()
                else:
                    province_check.quantity -= allocation_list["allocationQuantity"] - allocation.quantity
                    poultry_request.remain_quantity -= allocation_list["allocationQuantity"] - allocation.quantity
                    province_check.save()
                    poultry_request.save()

                allocation.quantity = allocation_list["allocationQuantity"]
                allocation.save()
                province_kill_request = ProvinceKillRequest.objects.get(
                    key=allocation.province_kill_request.key)
                province_kill_request.quantity = allocation_list["allocationQuantity"]
                province_kill_request.main_quantity = allocation_list["allocationQuantity"]
                province_kill_request.save()

                allocation_objects.append(allocation)
                daily_quota_objects.append(allocation.daily_quota)
            for daily_quota_object in daily_quota_objects:
                quantity = 0
                for allocation_object in allocation_objects:
                    if allocation_object.daily_quota == daily_quota_object:
                        quantity += allocation_object.quantity
                daily_quota_object.quantity = quantity
                daily_quota_object.save()
                kill_request = KillRequest.objects.get(key=daily_quota_object.kill_request.key, trash=False)
                kill_request.kill_capacity = quantity
                kill_request.remain_quantity = 0
                kill_request.save()

            return Response({"result": "با موفقیت ویرایش شد."}, status=status.HTTP_200_OK)
        elif 'allocation_delete_list' in request.data.keys():
            allocation_lists = request.data['allocation_delete_list']
            request.data.pop('allocation_delete_list')
            for allocation_list in allocation_lists:
                allocation = ProvinceAutoAllocation.objects.get(key=allocation_list["allocationKey"], trash=False)
                province_kill_request = ProvinceKillRequest.objects.get(
                    key=allocation.province_kill_request.key)
                province_check = ProvinceCheckOperatorRequest.objects.get(
                    key=province_kill_request.province_request.key)
                province_check.quantity += province_kill_request.main_quantity
                province_check.save()
                province_kill_request.trash = True
                province_kill_request.save()

                daily_object = KillHouseDailyQuota.objects.get(key=allocation.daily_quota.key, trash=False)
                poultry_request = PoultryRequest.objects.get(key=allocation.poultry_request.key)
                poultry_request.remain_quantity += allocation.quantity
                poultry_request.save()
                kill_request = KillRequest.objects.get(key=allocation.daily_quota.kill_request.key, trash=False)
                kill_request.trash = True
                kill_request.save()
                daily_object.trash = True
                daily_object.save()
                allocation.trash = True
                allocation.save()
            return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)
        elif 'final_registration_list' in request.data.keys():
            province_kill_requeest_list = []
            final_registration_list = request.data['final_registration_list']
            for allocation_list in final_registration_list:
                final_registration = ProvinceAutoAllocation.objects.get(key=allocation_list["allocationKey"],
                                                                        trash=False)
                province_kill_request = ProvinceKillRequest.objects.get(
                    key=final_registration.province_kill_request.key, trash=False)
                province_kill_request.dont_show_kill_house = False
                province_kill_request.save()
                final_registration.state = 'final_registration'
                final_registration.save()
                province_kill_requeest_list.append(province_kill_request.key)
            if AutoAcceptProvinceKillRequest.objects.filter(allow=True).exists():
                AutoAcceptMakeRequest_threading = threading.Thread(
                    target=AutoAcceptMakeRequest,
                    args=(
                        province_kill_requeest_list,
                    ))
                AutoAcceptMakeRequest_threading.start()
            return Response({"result": "ثبت نهایی با موفقیت انجام شد."})
        elif 'cancellation' in request.data.keys():
            cancellation_allocations_list = request.data['cancellation']
            daily_quota_list = []
            for delete_allocation in cancellation_allocations_list:

                allocation = ProvinceAutoAllocation.objects.get(key=delete_allocation["allocationKey"], trash=False)
                if allocation.daily_quota not in daily_quota_list:
                    daily_quota_list.append(allocation.daily_quota)
                province_kill_request = ProvinceKillRequest.objects.get(key=allocation.province_kill_request.key,
                                                                        trash=False)
                province_check = ProvinceCheckOperatorRequest.objects.get(
                    key=province_kill_request.province_request.key)
                province_check.quantity += province_kill_request.main_quantity
                province_check.save()
                poultry_request = PoultryRequest.objects.get(key=province_check.poultry_request.key, trash=False)
                poultry_request.remain_quantity += province_kill_request.main_quantity
                poultry_request.save()

                province_kill_request.delete()
                allocation.delete()

            for daily_quota_internal_list in daily_quota_list:
                daily_quota = KillHouseDailyQuota.objects.get(key=daily_quota_internal_list.key)
                kill_request = KillRequest.objects.get(key=daily_quota.kill_request.key, trash=False)
                factor = KillRequestFactor.objects.get(kill_request=kill_request, trash=False)
                factor.delete()
                kill_request.delete()
                daily_quota.delete()

            return Response({"result": "ثبت نهایی با موفقیت انجام شد."})

        else:
            allocation_lists = request.data['allocation_add_list']
            request.data.pop('allocation_add_list')

            for allocation_list in allocation_lists:

                poultry_request = PoultryRequest.objects.get(key=allocation_list["poultry_request_key"])
                province_check = ProvinceCheckOperatorRequest.objects.get(poultry_request=poultry_request, trash=False)
                kill_house_percentage = KillHousePercentage.objects.get(
                    kill_house__key=allocation_list["kill_house_key"])
                kill_request = KillRequest(
                    kill_house=kill_house_percentage.kill_house,
                    kill_capacity=int(allocation_list["quantity"]),
                    remain_quantity=0,
                    recive_time='14 - 16',
                    province_state='accepted',
                    automatic=True,
                    recive_date=datetime.now()
                )
                kill_request.save()
                price = Pricing.objects.all()
                if price.count() > 0:
                    price = price.last()
                    factor = KillRequestFactor(
                        kill_request=kill_request,
                        amount=round(
                            (kill_request.kill_capacity * 2.7) * price.live_chicken_price,
                            0),
                        minimum_amount=round(
                            ((kill_request.kill_capacity * 2.7) * price.live_chicken_price) * (
                                    70 / 100),
                            0)

                    )
                    factor.save()
                    kill_request.factor_amount = factor.amount
                    kill_request.save()
                kill_house_daily_quota = KillHouseDailyQuota(
                    kill_house=kill_house_percentage.kill_house,
                    kill_request=kill_request,
                    percent=kill_house_percentage.percent,
                    quantity=kill_request.kill_capacity,
                    remain_quantity=kill_request.kill_capacity,
                )
                kill_house_daily_quota.save()
                if kill_house_percentage.kill_house_for_killer != None:
                    kill_request.slaughter_house = kill_house_percentage.kill_house_for_killer
                    kill_request.save()
                    kill_house_daily_quota.killer_kill_house = kill_house_percentage.kill_house_for_killer
                    kill_house_daily_quota.save()
                poultry_request.remain_quantity -= int(allocation_list["quantity"])
                poultry_request.save()
                allocation_list = ProvinceAutoAllocation.objects.all()
                if allocation_list.count() > 0:
                    code = allocation_list.last().allocation_order_code
                else:
                    code = 1000

                province_kill_request = ProvinceKillRequest(
                    killhouse_user=kill_house_percentage.kill_house,
                    dont_show_kill_house=True,
                    kill_request=kill_request,
                    province_request=province_check,
                    quantity=kill_request.kill_capacity,
                    main_quantity=kill_request.kill_capacity,
                    automatic=True,

                )
                province_kill_request.save()
                province_check = ProvinceCheckOperatorRequest.objects.get(
                    key=province_kill_request.province_request.key)
                province_check.quantity -= province_kill_request.main_quantity
                province_check.save()

                allocation = ProvinceAutoAllocation(
                    daily_quota=kill_house_daily_quota,
                    poultry_request=poultry_request,
                    quantity=kill_request.kill_capacity,
                    allocation_order_code=code,
                    province_kill_request=province_kill_request

                )
                allocation.save()

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


#
# class ProvinceAutoAcceptAllocationProvinceKillRequestViewset(viewsets.ModelViewSet):
#     queryset = ProvinceKillRequest.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = ProvinceKillRequestSerializer
#
#
#
#
#     def create(self, request, *args, **kwargs):
#         date=datetime.now().date()
#         # allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related(
#         #     'poultry_request',
#         #     'province_kill_request',
#         #     'daily_quota__kill_house__kill_house_operator__user',
#         #     'daily_quota__killer_kill_house__kill_house_operator__user'
#         # )
#
#         poultry_requests = PoultryRequest.objects.filter(
#             poultry_request_auto_quantity_province__in=ProvinceAutoAllocation.objects.filter(
#                 trash=False,
#                 create_date__date=date
#             ).values('poultry_request_id')
#         ).distinct()
#
#
#
#         return Response(poultry_requests.query, status=status.HTTP_201_CREATED)


class AutoAcceptProvinceKillRequestViewset(viewsets.ModelViewSet):
    queryset = AutoAcceptProvinceKillRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AutoAcceptProvinceKillRequestSerializer

    def update(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        auto_accept = AutoAcceptProvinceKillRequest.objects.all().first()
        if serializer.is_valid():

            if auto_accept:
                serializer.update(instance=auto_accept, validated_data=request.data)
            else:
                serializer.create(validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        auto_accept = AutoAcceptProvinceKillRequest.objects.all().first()
        allow = False
        if auto_accept:
            allow = auto_accept.allow
        return Response(allow, status=status.HTTP_200_OK)


class AutoMakeKillHouseRequestViewset(viewsets.ModelViewSet):
    queryset = AutoMakeKillHouseRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AutoMakeKillHouseRequestSerializer

    def update(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        auto_accept = AutoMakeKillHouseRequest.objects.all().first()
        if serializer.is_valid():

            if auto_accept:
                serializer.update(instance=auto_accept, validated_data=request.data)
            else:
                serializer.create(validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        auto_accept = AutoMakeKillHouseRequest.objects.all().first()
        allow = False
        if auto_accept:
            allow = auto_accept.allow
        return Response(allow, status=status.HTTP_200_OK)


class KillHousePercentageOfLossesViewset(viewsets.ModelViewSet):
    queryset = KillHousePercentageOfLosses.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillHousePercentageOfLossesSerializer


class ProvinceAllowKillHouseChooseStewardGuildsViewset(viewsets.ModelViewSet):
    queryset = ProvinceAllowKillHouseChooseStewardGuilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceAllowKillHouseChooseStewardGuildsSerializer

    # def create(self, request, *args, **kwargs):
    #     user = SystemUserProfile.objects.get(user=request.user, trash=False)
    #     steward = False
    #     guilds = False
    #     kill_house_choose_threading = threading.Thread(
    #         target=KillHouseChooseSteward,
    #         args=(
    #             steward,
    #             # request.data['steward'],
    #             guilds,
    #             # request.data['guilds'],
    #             user.province.name))
    #     kill_house_choose_threading.start()
    #     return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        kill_house_choose_threading = threading.Thread(
            target=KillHouseChooseSteward,
            args=(
                request.data['steward'],
                request.data['guilds'],
                user.province.name))
        kill_house_choose_threading.start()
        return Response({"result": "عملیات با موفقیت ثبت شد."}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        if 'kill_house_key' in request.GET and request.GET['kill_house_key'] != None:
            kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'])
            queryset = ProvinceAllowKillHouseChooseStewardGuilds.objects.get(kill_house=kill_house)
            serializer = self.serializer_class(queryset)
        else:

            queryset = ProvinceAllowKillHouseChooseStewardGuilds.objects.all().order_by('id')
            serializer = self.serializer_class(queryset, many=True)
        return Response(serializer.data, status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        choose_steward_guilds = ProvinceAllowKillHouseChooseStewardGuilds.objects.get(
            key=request.data['choose_steward_guilds_key'])
        request.data.pop('choose_steward_guilds_key')
        serializer = self.serializer_class(choose_steward_guilds)
        serializer.update(instance=choose_steward_guilds, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


# class WagePaymentGateWayUrlViewset(viewsets.ModelViewSet):
#     queryset = WagePayment.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = WagePaymentSerializer
#
#     def create(self, request, *args, **kwargs):


class WagePaymentBasedOnWeightViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WagePaymentSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = WagePaymentFilterSet
    filterset_fields = [
        'tracking_code',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_info',

    ]

    def create(self, request, *args, **kwargs):
        now = datetime.now()
        total_amount = 0
        final_total_amount = 0
        exclusive = False
        slaughter_transaction_type = 'public'
        killer = False
        killer_kill_house = None
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        wage = ShareOfAllocation.objects.all().last()
        wage = wage.province_union if wage else 0
        role = request.data['role']
        request.data.pop('role')
        wallet = False
        kill_house_key = None
        if 'amount' in request.data.keys():
            wallet = True
            input_amout = request.data['amount']
            input_amount_with_tax = request.data['amount_with_tax']
            kill_house_key = request.data['kill_house_key']
            request.data.pop('amount')
            request.data.pop('amount_with_tax')
            request.data.pop('kill_house_key')
        kill_house_key = request.data['kill_house_key']
        request.data.pop('kill_house_key')

        kill_house = KillHouse.objects.filter(key=kill_house_key, trash=False).select_related(
            'kill_house_operator__user').first()
        kill_house_percentage = KillHousePercentage.objects.get(kill_house=kill_house, trash=False)
        if kill_house_percentage.kill_house_for_killer != None:
            killer = True
            if kill_house.type == 'exclusive':
                exclusive = True
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            wage_payment = serializer.create(validated_data=request.data)
            wage_payment.payer_info = user.fullname
            wage_payment.payer = {
                "role": role,
                "payer": user.fullname,
                "payment_type": wage_payment.payment_type,
                "tracking_code": wage_payment.tracking_code,
                "date": str(now)

            }

            if wallet == True:
                kill_house_user = kill_house.kill_house_operator.user
                creator = kill_house_user
                receiver = kill_house_user
                total_amount = input_amout
                wage_payment.total_amount_with_tax = input_amount_with_tax
                wage_payment.type = "wallet"
            else:

                total_amount = wage_payment.total_amount
                kill_house_user = kill_house.kill_house_operator.user
                creator = kill_house_user
                receiver = kill_house_user
                wage_payment.total_amount_with_tax = total_amount + (total_amount * (10 / 100))

            wage_payment.total_amount = total_amount
            wage_payment.save()

            payment_gate_way_percentage = PaymentGatewayPercentage.objects.get(trash=False)
            company = payment_gate_way_percentage.company / 100 if payment_gate_way_percentage.company > 0 else 0
            union = payment_gate_way_percentage.union / 100 if payment_gate_way_percentage.union > 0 else 0
            guilds = payment_gate_way_percentage.guilds / 100 if payment_gate_way_percentage.guilds > 0 else 0

            if user.province.name == 'لرستان':
                province_deposit_id = sha_deposit_id
                province_deposit_percent = union
                arta_api_deposit_id = arta_deposit_id
                arta_api_deposit_percent = company
                guilds_api_deposit_id = guilds_deposit_id
                guilds_api_deposit_percent = guilds
                gate_way_order_id = test_order_id


            elif user.province.name == 'آذربایجان شرقی':
                province_deposit_id = sha_deposit_id
                province_deposit_percent = union
                arta_api_deposit_id = arta_deposit_id
                arta_api_deposit_percent = company
                guilds_api_deposit_id = guilds_deposit_id
                guilds_api_deposit_percent = guilds
                gate_way_order_id = sha_order_id

            elif user.province.name == 'اردبیل':
                province_deposit_id = ar_deposit_id
                province_deposit_percent = union
                arta_api_deposit_id = arta_deposit_id
                arta_api_deposit_percent = company
                guilds_api_deposit_id = guilds_deposit_id
                guilds_api_deposit_percent = guilds
                gate_way_order_id = ar_order_id



            elif user.province.name == 'همدان':
                province_deposit_id = ha_deposit_id
                province_deposit_percent = union
                arta_api_deposit_id = arta_deposit_id
                arta_api_deposit_percent = company
                guilds_api_deposit_id = guilds_deposit_id
                guilds_api_deposit_percent = guilds
                gate_way_order_id = ha_order_id


            elif user.province.name == 'مركزی':
                province_deposit_id = ma_deposit_id
                province_deposit_percent = union
                arta_api_deposit_id = arta_deposit_id
                arta_api_deposit_percent = company
                guilds_api_deposit_id = guilds_deposit_id
                guilds_api_deposit_percent = guilds
                gate_way_order_id = ma_order_id

            order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
                                                      now.minute, now.second)
            # if user.province.name == 'مركزی':
            #     result = PaymentGateway(
            #         "{0},{1},0;{2},{3},0;".format(province_deposit_id, 100,
            #                                       arta_api_deposit_id,
            #                                       int(total_amount - 100)), int(total_amount),
            #         order_id)
            # else:

            if wallet == True:
                final_total_amount = input_amount_with_tax
            else:
                final_total_amount = total_amount + (total_amount * (10 / 100))
            if company > 0 and union > 0 and guilds > 0:
                result = PaymentGateway(
                    "{0},{1},0;{2},{3},0;{4},{5},0;".format(province_deposit_id,
                                                            int(final_total_amount * union),
                                                            arta_api_deposit_id,
                                                            int(final_total_amount * company),
                                                            guilds_api_deposit_id,
                                                            int(final_total_amount * guilds)),
                    int(final_total_amount),
                    order_id)
            elif company > 0 and union > 0 and guilds == 0:
                result = PaymentGateway(
                    "{0},{1},0;{2},{3},0;".format(province_deposit_id,
                                                  int(final_total_amount * union),
                                                  arta_api_deposit_id,
                                                  int(final_total_amount * company)),
                    int(final_total_amount),
                    order_id)

            elif company > 0 and union == 0 and guilds > 0:
                result = PaymentGateway(
                    "{0},{1},0;{2},{3},0;".format(

                        arta_api_deposit_id,
                        int(final_total_amount * company),
                        guilds_api_deposit_id,
                        int(final_total_amount * guilds)),
                    int(final_total_amount),
                    order_id)
            else:
                result = PaymentGateway(
                    "{0},{1},0;{2},{3},0;".format(province_deposit_id,
                                                  int(final_total_amount * union),
                                                  guilds_api_deposit_id,
                                                  int(final_total_amount * guilds)),
                    int(final_total_amount),
                    order_id)

            # result = PaymentGateway(
            #     "{0},{1},0;{2},{3},0;".format(sha_deposit_id, 10000, arta_deposit_id, 10000),20000, order_id)
            if '400' in result.keys():
                wage_payment.state = 'failed'
                wage_payment.message = result[400]
                wage_payment.save()
                if wallet == True:
                    transaction = ExternalTransaction(
                        amount=total_amount,
                        amount_with_tax=final_total_amount,
                        status="failed",
                        type="deposit",
                        transaction_type="wallet",
                        is_complete=False,
                        kill_house_user=kill_house_user,
                        creator=creator,
                        receiver=receiver,
                        creator_role='KillHouse',
                        receiver_role='KillHouse',
                        payer=kill_house_user.fullname,
                        message=result[400]

                    )
                    transaction.save()
                else:
                    transaction = ExternalTransaction(
                        amount=total_amount,
                        amount_with_tax=final_total_amount,
                        status="failed",
                        transaction_type="wage-gateway",
                        is_complete=False,
                        kill_house_user=kill_house_user,
                        creator=creator,
                        receiver=receiver,
                        creator_role='KillHouse',
                        receiver_role='ProvinceOperator',
                        payer=user.fullname,
                        message=result[400]

                    )
                    transaction.save()
                    return Response(result[400], status=status.HTTP_400_BAD_REQUEST)
            else:
                wage_payment.refId = result[200]
                wage_payment.orderId = order_id
                wage_payment.save()
                if wallet == True:
                    transaction = ExternalTransaction(
                        amount=total_amount,
                        amount_with_tax=final_total_amount,
                        status="pending",
                        type="deposit",
                        transaction_type="wallet",
                        is_complete=False,
                        kill_house_user=kill_house_user,
                        creator=creator,
                        receiver=receiver,
                        receiver_role='KillHouse',
                        creator_role='KillHouse',
                        payer=kill_house_user.fullname,
                        refId=result[200],
                        orderId=order_id

                    )
                    transaction.save()
                else:

                    transaction = ExternalTransaction(
                        amount=total_amount,
                        amount_with_tax=final_total_amount,
                        status="pending",
                        transaction_type="wage-gateway",
                        is_complete=False,
                        kill_house_user=kill_house_user,
                        creator=creator,
                        receiver=receiver,
                        receiver_role='KillHouse',
                        creator_role='ProvinceOperator',
                        payer=user.fullname,
                        refId=result[200],
                        orderId=order_id

                    )
                    transaction.save()
                    if killer == True:
                        parent_kill_house = kill_house_percentage.kill_house_for_killer
                        main_kill_house = kill_house_percentage.kill_house
                        if exclusive == True:
                            slaughter_transaction_type = 'exclusive'
                    else:
                        parent_kill_house = kill_house
                        main_kill_house = kill_house

                    slaughter_transaction = SlaughterHouseTransaction(
                        kill_house=main_kill_house,
                        parent_kill_house=parent_kill_house,
                        type=slaughter_transaction_type,
                        amount=wage_payment.total_amount,
                        amount_with_tax=wage_payment.total_amount_with_tax,
                        transaction=transaction.id,

                    )
                    slaughter_transaction.save()
                return Response({"refId": result[200]}, status=status.HTTP_201_CREATED)

            # return Response(serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        wage_payment_list = []

        if request.GET['state'] == 'failed':
            wage_payment = WagePayment.objects.filter(
                create_date__date__gte=date1,
                create_date__date__lte=date2,
                state='failed',
                trash=False).order_by('id')
        else:
            wage_payment = WagePayment.objects.filter(
                create_date__date__gte=date1,
                create_date__date__lte=date2,
                state='completed',
                trash=False).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(wage_payment)
        if page is not None:
            serializer = WagePaymentSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = WagePaymentSerializer(wage_payment, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


# class WagePaymentWithLinkViewset(viewsets.ModelViewSet):
#     queryset = WagePayment.objects.all()
#     permission_classes = [AllowAny]
#     serializer_class = WagePaymentSerializer
#
#     def create(self, request, *args, **kwargs):
#         link = True
#         zarinpal_accounts = ZarinPalAccounts.objects.filter(trash=False)
#         province_shaba_id = zarinpal_accounts.filter(en_name='union').first().account
#         arta_shaba_id = zarinpal_accounts.filter(en_name='company').first().account
#         guilds_shaba_id = zarinpal_accounts.filter(en_name='guilds').first().account
#         other_shaba_id = zarinpal_accounts.filter(en_name='other').first().account
#         now = datetime.now()
#         wages = []
#         amount = 0
#         poultry_requests = None
#         role = request.data['role']
#         request.data.pop('role')
#         payer = None
#         if 'order_codes' in request.data.keys():
#             if request.data['order_codes'] is not None:
#                 poultry_requests = PoultryRequest.objects.filter(order_code__in=request.data['order_codes'])
#             request.data.pop('order_codes')
#         user = SystemUserProfile.objects.get(key=request.data['user_key'], trash=False)
#         request.data.pop('user_key')
#         if role == 'Poultry':
#             payer = 'poultry'
#             payer_fullname = user.fullname
#             phone = user.mobile
#
#             # request.data.pop('user_key')
#         elif role == 'Buyer':
#             buyer = OutProvincePoultryRequestBuyer.objects.get(user=user, trash=False)
#             payer = 'buyer'
#             payer_fullname = user.fullname
#             phone = user.mobile
#
#
#         else:
#             parent_kill_house = None
#             if role == 'KillHouse':
#                 kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
#                 parent_kill_house = kill_house
#                 if kill_house.killer == True and kill_house.type == 'exclusive':
#                     percentage = KillHousePercentage.objects.filter(kill_house=kill_house, trash=False).first()
#                     parent_kill_house = percentage.kill_house_for_killer if percentage else kill_house
#
#                 payer = 'kill_house'
#                 phone = kill_house.kill_house_operator.user.mobile
#
#             else:
#                 chain_company = ChainCompany.objects.get(user=user, trash=False)
#                 payer = 'chain_company'
#                 phone = chain_company.user.mobile
#
#         serializer = self.serializer_class(data=request.data)
#         if serializer.is_valid():
#             wage_payment = serializer.create(validated_data=request.data)
#             beneficiary_accounts = CompanyBeneficiaryAccount.objects.filter(trash=False, percent__gt=0)
#             amount = int(wage_payment.total_amount)
#             wage_payment.payer_info = user.fullname
#             wage_payment.link_pay = True
#
#             wage_payment.payer = {
#                 "role": role,
#                 "payer": user.fullname,
#                 "payment_type": wage_payment.payment_type,
#                 "tracking_code": wage_payment.tracking_code,
#                 "date": str(now)
#
#             }
#             if payer == 'kill_house':
#
#                 if kill_house.share_debt_counting_wage == False:
#                     company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
#                     union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
#                     guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
#                     other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
#                 else:
#                     percent_data = get_kill_house_percent(kill_house)
#                     if percent_data:
#                         company = percent_data['company'] / 100 if percent_data['company'] > 0 else 0
#                         union = percent_data['union'] / 100 if percent_data['union'] > 0 else 0
#                         guilds = percent_data['guilds'] / 100 if percent_data['guilds'] > 0 else 0
#                         other = percent_data['vet'] / 100 if percent_data['vet'] > 0 else 0
#                     else:
#                         company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
#                         union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
#                         guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
#                         other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
#             else:
#                 wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
#                 percentage_of_wage_type = PercentageOfWageType.objects.filter(trash=False, wage_type=wage_type)
#                 company_share = percentage_of_wage_type.filter(share_type__en_name='company').first().percent
#                 union_share = percentage_of_wage_type.filter(share_type__en_name='union').first().percent
#                 guilds_share = percentage_of_wage_type.filter(share_type__en_name='guilds').first().percent
#                 other_share = percentage_of_wage_type.filter(share_type__en_name='other').first().percent
#
#                 company = (company_share) / 100 if company_share > 0 else 0
#                 union = union_share / 100 if union_share > 0 else 0
#                 guilds = guilds_share / 100 if guilds_share > 0 else 0
#                 other = other_share / 100 if other_share > 0 else 0
#
#             if user.province.name == 'همدان':
#                 gate_way_order_id = ha_order_id
#
#
#             elif user.province.name == 'مركزی':
#                 gate_way_order_id = ma_order_id
#
#
#             else:
#                 gate_way_order_id = test_order_id
#
#             order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
#                                                       now.minute, now.second)
#
#             guild_id = 0
#             other_id = 0
#             province_other_wage = 0
#             if province_shaba_id == guilds_shaba_id:
#                 guild_id = 1
#                 province_other_wage += (amount * guilds)
#             if province_shaba_id == other_shaba_id:
#                 other_id = 1
#                 province_other_wage += (amount * other)
#
#             if company > 0:
#                 company_total_amount = amount * company
#                 total_remain_amount = company_total_amount
#                 account_amount = 0
#                 if payer == 'kill_house':
#                     beneficiary_accounts = beneficiary_accounts.filter(in_province=True)
#                 else:
#                     beneficiary_accounts = beneficiary_accounts.filter(out_province=True)
#
#                 if beneficiary_accounts:
#                     for account in beneficiary_accounts:
#                         account_amount = int(company_total_amount * (account.percent / 100))
#                         total_remain_amount -= account_amount
#                         wages.append(
#                             {
#                                 "IBAN": account.shaba,
#                                 "Amount": account_amount,
#                             }
#
#                         )
#                     if total_remain_amount > 0:
#                         wages.append(
#                             {
#                                 "IBAN": arta_shaba_id,
#                                 "Amount": total_remain_amount,
#                             }
#
#                         )
#
#
#
#                 else:
#
#                     wages.append(
#                         {
#                             "IBAN": arta_shaba_id,
#                             "Amount": amount * company,
#                         }
#
#                     )
#
#             if union > 0:
#                 wages.append(
#                     {
#                         "IBAN": province_shaba_id,
#                         "Amount": (amount * union) + province_other_wage
#                     }
#
#                 )
#             if guild_id == 0 or (union == 0 and guild_id == 1):
#                 if guilds > 0:
#                     wages.append(
#                         {
#                             "IBAN": guilds_shaba_id,
#                             "Amount": (amount * guilds),
#                         }
#
#                     )
#             if other_id == 0 or (union == 0 and other_id == 1):
#                 if other > 0:
#                     wages.append(
#                         {
#                             "IBAN": other_shaba_id,
#                             "Amount": (amount * other),
#                         }
#
#                     )
#             result = PaymentGatewayZarinPal(amount, phone, order_id, link, wages)
#             if 500 in result.keys():
#                 wage_payment.state = 'failed'
#                 wage_payment.message = result[500]
#                 wage_payment.save()
#                 if payer == 'kill_house':
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         kill_house=kill_house,
#                         parent_kill_house=parent_kill_house,
#                         payer_fullname=kill_house.kill_house_operator.user.fullname,
#                         payer_mobile=kill_house.kill_house_operator.user.mobile,
#                         payer_type='kill_house',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         link_pay=True,
#                         orderId=order_id,
#                         message=result[500]
#                     )
#                     transaction.save()
#
#                 elif payer == 'poultry':
#
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         payer_type='poultry',
#                         poultry=poultry_requests.first().poultry,
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         user=user,
#                         payer_fullname=user.fullname,
#                         payer_mobile=user.mobile,
#                         link_pay=True,
#                         orderId=order_id,
#                         message=result[500]
#                     )
#                     transaction.save()
#                     if poultry_requests is not None:
#                         transaction.poultry_request.add(*poultry_requests)
#
#                 elif payer == 'buyer':
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         payer_type='buyer',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         user=user,
#                         out_province_poultry_request_buyer=buyer,
#                         payer_fullname=buyer.user.fullname,
#                         payer_mobile=buyer.user.mobile,
#                         link_pay=True,
#                         orderId=order_id,
#                         message=result[500]
#                     )
#                     transaction.save()
#                     if poultry_requests is not None:
#                         transaction.poultry_request.add(*poultry_requests)
#                 else:
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         chain_company=chain_company,
#                         payer_fullname=chain_company.user.fullname,
#                         payer_mobile=chain_company.user.mobile,
#                         payer_type='chain_company',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         link_pay=True,
#                         orderId=order_id,
#                         message=result[400]
#                     )
#                     transaction.save()
#
#                 return Response(result[500], status=status.HTTP_400_BAD_REQUEST)
#             else:
#                 wage_payment.authority = result[201]
#                 wage_payment.orderId = order_id
#                 wage_payment.save()
#                 if payer == 'kill_house':
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         transaction_type="wage-gateway-auto",
#                         kill_house=kill_house,
#                         parent_kill_house=parent_kill_house,
#                         payer_fullname=kill_house.kill_house_operator.user.fullname,
#                         payer_mobile=kill_house.kill_house_operator.user.mobile,
#                         payer_type='kill_house',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         link_pay=True,
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#
#                 elif payer == 'poultry':
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         transaction_type="wage-gateway-auto",
#                         payer_type='poultry',
#                         poultry=poultry_requests.first().poultry,
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         user=user,
#                         payer_fullname=user.fullname,
#                         payer_mobile=user.mobile,
#                         link_pay=True,
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#                     if poultry_requests is not None:
#                         transaction.poultry_request.add(*poultry_requests)
#
#
#                 elif payer == 'buyer':
#
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         transaction_type="wage-gateway-auto",
#                         payer_type='buyer',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         user=user,
#                         out_province_poultry_request_buyer=buyer,
#                         payer_fullname=buyer.user.fullname,
#                         payer_mobile=buyer.user.mobile,
#                         link_pay=True,
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#                     if poultry_requests is not None:
#                         transaction.poultry_request.add(*poultry_requests)
#
#
#                 else:
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         # is_complete=False,
#                         transaction_type="wage-gateway-auto",
#                         chain_company=chain_company,
#                         payer_fullname=chain_company.user.fullname,
#                         payer_mobile=chain_company.user.mobile,
#                         payer_type='chain_company',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         link_pay=True,
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#
#                 return Response({"token": result[201]}, status=status.HTTP_201_CREATED)
#
#                 # return Response(serializer.data, status=status.HTTP_201_CREATED)

class WagePaymentWithLinkViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [AllowAny]
    serializer_class = WagePaymentSerializer

    def create(self, request, *args, **kwargs):
        link = True
        zarinpal_accounts = ZarinPalAccounts.objects.filter(trash=False)
        province_shaba_id = zarinpal_accounts.filter(en_name='union').first().account
        arta_shaba_id = zarinpal_accounts.filter(en_name='company').first().account
        guilds_shaba_id = zarinpal_accounts.filter(en_name='guilds').first().account
        other_shaba_id = zarinpal_accounts.filter(en_name='other').first().account
        now = datetime.now()
        wages = []
        amount = 0
        poultry_requests = None
        role = request.data['role']
        request.data.pop('role')
        payer = None
        if 'order_codes' in request.data.keys():
            if request.data['order_codes'] is not None:
                poultry_requests = PoultryRequest.objects.filter(order_code__in=request.data['order_codes'])
            request.data.pop('order_codes')
        user = SystemUserProfile.objects.get(key=request.data['user_key'], trash=False)
        request.data.pop('user_key')
        if role == 'Poultry':
            payer = 'poultry'
            payer_fullname = user.fullname
            phone = user.mobile

            # request.data.pop('user_key')
        elif role == 'Buyer':
            buyer = OutProvincePoultryRequestBuyer.objects.get(user=user, trash=False)
            payer = 'buyer'
            payer_fullname = user.fullname
            phone = user.mobile


        else:
            parent_kill_house = None
            if role == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                parent_kill_house = kill_house
                if kill_house.killer == True and kill_house.type == 'exclusive':
                    percentage = KillHousePercentage.objects.filter(kill_house=kill_house, trash=False).first()
                    parent_kill_house = percentage.kill_house_for_killer if percentage else kill_house

                payer = 'kill_house'
                phone = kill_house.kill_house_operator.user.mobile

            else:
                chain_company = ChainCompany.objects.get(user=user, trash=False)
                payer = 'chain_company'
                phone = chain_company.user.mobile

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            wage_payment = serializer.create(validated_data=request.data)
            beneficiary_accounts = CompanyBeneficiaryAccount.objects.filter(trash=False, percent__gt=0)
            amount = int(wage_payment.total_amount)
            wage_payment.payer_info = user.fullname
            wage_payment.link_pay = True

            wage_payment.payer = {
                "role": role,
                "payer": user.fullname,
                "payment_type": wage_payment.payment_type,
                "tracking_code": wage_payment.tracking_code,
                "date": str(now)

            }
            if payer == 'kill_house':

                if kill_house.share_debt_counting_wage == False:
                    company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
                    union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
                    guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
                    other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
                else:
                    percent_data = get_kill_house_percent(kill_house)
                    if percent_data and (
                            percent_data['union'] or percent_data['company'] or percent_data['guilds'] or percent_data[
                        'vet']):
                        company = percent_data['company'] / 100 if percent_data['company'] > 0 else 0
                        union = percent_data['union'] / 100 if percent_data['union'] > 0 else 0
                        guilds = percent_data['guilds'] / 100 if percent_data['guilds'] > 0 else 0
                        other = percent_data['vet'] / 100 if percent_data['vet'] > 0 else 0
                    else:
                        company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
                        union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
                        guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
                        other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
            else:
                wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
                percentage_of_wage_type = PercentageOfWageType.objects.filter(trash=False, wage_type=wage_type)
                company_share = percentage_of_wage_type.filter(share_type__en_name='company').first().percent
                union_share = percentage_of_wage_type.filter(share_type__en_name='union').first().percent
                guilds_share = percentage_of_wage_type.filter(share_type__en_name='guilds').first().percent
                other_share = percentage_of_wage_type.filter(share_type__en_name='other').first().percent

                company = (company_share) / 100 if company_share > 0 else 0
                union = union_share / 100 if union_share > 0 else 0
                guilds = guilds_share / 100 if guilds_share > 0 else 0
                other = other_share / 100 if other_share > 0 else 0

            if user.province.name == 'همدان':
                gate_way_order_id = ha_order_id


            elif user.province.name == 'مركزی':
                gate_way_order_id = ma_order_id


            else:
                gate_way_order_id = test_order_id

            order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
                                                      now.minute, now.second)
            zero_counter = 0
            zero_wages = 0

            if arta_shaba_id == '-' and company > 0:
                zero_wages += amount * company

            if province_shaba_id == '-' and union > 0:
                zero_wages += amount * union

            if guilds_shaba_id == '-' and guilds > 0:
                zero_wages += amount * guilds

            if other_shaba_id == '-' and other > 0:
                zero_wages += amount * other

            if arta_shaba_id != '-' and company > 0:
                zero_counter += 1

            if province_shaba_id != '-' and union > 0:
                zero_counter += 1

            if guilds_shaba_id != '-' and guilds > 0:
                zero_counter += 1

            if other_shaba_id != '-' and other > 0:
                zero_counter += 1

            if zero_counter > 0 and zero_counter != zarinpal_accounts.count():
                zero_wages = zero_wages / (zarinpal_accounts.count() - zero_counter)

            guild_id = 0
            other_id = 0
            province_other_wage = 0
            if province_shaba_id == guilds_shaba_id:
                if guilds > 0:
                    guild_id = 1
                    province_other_wage += (amount * guilds) + zero_wages
            if province_shaba_id == other_shaba_id:
                if other > 0:
                    other_id = 1
                    province_other_wage += (amount * other) + zero_wages

            if arta_shaba_id != '-':
                if company > 0:
                    company_total_amount = (amount * company) + zero_wages
                    total_remain_amount = company_total_amount
                    account_amount = 0
                    if payer == 'kill_house':
                        beneficiary_accounts = beneficiary_accounts.filter(in_province=True)
                    else:
                        beneficiary_accounts = beneficiary_accounts.filter(out_province=True)

                    if beneficiary_accounts:
                        for account in beneficiary_accounts:
                            account_amount = int(company_total_amount * (account.percent / 100))
                            total_remain_amount -= account_amount

                            wages.append(
                                {
                                    "IBAN": account.shaba,
                                    "Amount": account_amount,
                                }

                            )
                        if total_remain_amount > 0:
                            wages.append(
                                {
                                    "IBAN": arta_shaba_id,
                                    "Amount": total_remain_amount,
                                }

                            )



                    else:
                        wages.append(
                            {
                                "IBAN": arta_shaba_id,
                                "Amount": (amount * company) + zero_wages,
                            }

                        )
            if province_shaba_id != '-':
                if union > 0:
                    wages.append(
                        {
                            "IBAN": province_shaba_id,
                            "Amount": (amount * union) + province_other_wage + zero_wages
                        }

                    )

            if guilds_shaba_id != '-':
                if guild_id == 0 or (union == 0 and guild_id == 1):
                    if guilds > 0:
                        wages.append(
                            {
                                "IBAN": guilds_shaba_id,
                                "Amount": (amount * guilds) + zero_wages,
                            }

                        )
            if other_shaba_id != '-':
                if other_id == 0 or (union == 0 and other_id == 1):
                    if other > 0:
                        wages.append(
                            {
                                "IBAN": other_shaba_id,
                                "Amount": (amount * other) + zero_wages,
                            }

                        )
            result = PaymentGatewayZarinPal(amount, phone, order_id, link, wages)
            if 500 in result.keys():
                wage_payment.state = 'failed'
                wage_payment.message = result[500]
                wage_payment.save()
                if payer == 'kill_house':
                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        kill_house=kill_house,
                        parent_kill_house=parent_kill_house,
                        payer_fullname=kill_house.kill_house_operator.user.fullname,
                        payer_mobile=kill_house.kill_house_operator.user.mobile,
                        payer_type='kill_house',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        link_pay=True,
                        orderId=order_id,
                        message=result[500]
                    )
                    transaction.save()

                elif payer == 'poultry':

                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        payer_type='poultry',
                        poultry=poultry_requests.first().poultry,
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        user=user,
                        payer_fullname=user.fullname,
                        payer_mobile=user.mobile,
                        link_pay=True,
                        orderId=order_id,
                        message=result[500]
                    )
                    transaction.save()
                    if poultry_requests is not None:
                        transaction.poultry_request.add(*poultry_requests)

                elif payer == 'buyer':
                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        payer_type='buyer',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        user=user,
                        out_province_poultry_request_buyer=buyer,
                        payer_fullname=buyer.user.fullname,
                        payer_mobile=buyer.user.mobile,
                        link_pay=True,
                        orderId=order_id,
                        message=result[500]
                    )
                    transaction.save()
                    if poultry_requests is not None:
                        transaction.poultry_request.add(*poultry_requests)
                else:
                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        chain_company=chain_company,
                        payer_fullname=chain_company.user.fullname,
                        payer_mobile=chain_company.user.mobile,
                        payer_type='chain_company',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        link_pay=True,
                        orderId=order_id,
                        message=result[400]
                    )
                    transaction.save()

                return Response(result[500], status=status.HTTP_400_BAD_REQUEST)
            else:
                wage_payment.authority = result[201]
                wage_payment.orderId = order_id
                wage_payment.save()
                if payer == 'kill_house':
                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        transaction_type="wage-gateway-auto",
                        kill_house=kill_house,
                        parent_kill_house=parent_kill_house,
                        payer_fullname=kill_house.kill_house_operator.user.fullname,
                        payer_mobile=kill_house.kill_house_operator.user.mobile,
                        payer_type='kill_house',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        link_pay=True,
                        orderId=order_id

                    )
                    transaction.save()

                elif payer == 'poultry':
                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        transaction_type="wage-gateway-auto",
                        payer_type='poultry',
                        poultry=poultry_requests.first().poultry,
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        user=user,
                        payer_fullname=user.fullname,
                        payer_mobile=user.mobile,
                        link_pay=True,
                        orderId=order_id

                    )
                    transaction.save()
                    if poultry_requests is not None:
                        transaction.poultry_request.add(*poultry_requests)


                elif payer == 'buyer':

                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        transaction_type="wage-gateway-auto",
                        payer_type='buyer',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        user=user,
                        out_province_poultry_request_buyer=buyer,
                        payer_fullname=buyer.user.fullname,
                        payer_mobile=buyer.user.mobile,
                        link_pay=True,
                        orderId=order_id

                    )
                    transaction.save()
                    if poultry_requests is not None:
                        transaction.poultry_request.add(*poultry_requests)


                else:
                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        # is_complete=False,
                        transaction_type="wage-gateway-auto",
                        chain_company=chain_company,
                        payer_fullname=chain_company.user.fullname,
                        payer_mobile=chain_company.user.mobile,
                        payer_type='chain_company',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        link_pay=True,
                        orderId=order_id

                    )
                    transaction.save()

                return Response({"token": result[201]}, status=status.HTTP_201_CREATED)

                # return Response(serializer.data, status=status.HTTP_201_CREATED)


# class WagePaymentTotalViewset(viewsets.ModelViewSet):
#     queryset = WagePayment.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = WagePaymentSerializer
#     filter_backends = [DjangoFilterBackend]
#     pagination_class = CustomPagination
#     filterset_class = WagePaymentFilterSet
#     filterset_fields = [
#         'tracking_code',
#         'refId',
#         'orderId',
#         'cardHolderPan',
#         'payer_info',
#
#     ]
#
#     def create(self, request, *args, **kwargs):
#         link = False
#         zarinpal_accounts = ZarinPalAccounts.objects.filter(trash=False)
#         beneficiary_accounts = CompanyBeneficiaryAccount.objects.filter(trash=False, percent__gt=0)
#         province_shaba_id = zarinpal_accounts.filter(en_name='union').first().account
#         arta_shaba_id = zarinpal_accounts.filter(en_name='company').first().account
#         guilds_shaba_id = zarinpal_accounts.filter(en_name='guilds').first().account
#         other_shaba_id = zarinpal_accounts.filter(en_name='other').first().account
#         now = datetime.now()
#         wages = []
#         amount = 0
#         user = SystemUserProfile.objects.get(user=request.user, trash=False)
#         payer = None
#         parent_kill_house = None
#         role = request.data['role']
#         request.data.pop('role')
#         if role == 'KillHouse':
#             kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
#             parent_kill_house = kill_house
#             if kill_house.killer == True and kill_house.type == 'exclusive':
#                 percentage = KillHousePercentage.objects.filter(kill_house=kill_house, trash=False).first()
#                 parent_kill_house = percentage.kill_house_for_killer if percentage else kill_house
#
#             payer = 'kill_house'
#             phone = kill_house.kill_house_operator.user.mobile
#         else:
#             chain_company = ChainCompany.objects.get(user=user, trash=False).first()
#             payer = 'chain_company'
#             phone = chain_company.user.mobile
#
#         serializer = self.serializer_class(data=request.data)
#         if serializer.is_valid():
#             wage_payment = serializer.create(validated_data=request.data)
#             amount = wage_payment.total_amount
#             wage_payment.payer_info = user.fullname
#             wage_payment.payer = {
#                 "role": role,
#                 "payer": user.fullname,
#                 "payment_type": wage_payment.payment_type,
#                 "tracking_code": wage_payment.tracking_code,
#                 "date": str(now)
#
#             }
#
#             if payer == 'kill_house':
#                 if kill_house.share_debt_counting_wage == False:
#
#                     company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
#                     union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
#                     guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
#                     other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
#
#                 else:
#                     percent_data = get_kill_house_percent(kill_house)
#                     if percent_data:
#                         company = percent_data['company'] / 100 if percent_data['company'] > 0 else 0
#                         union = percent_data['union'] / 100 if percent_data['union'] > 0 else 0
#                         guilds = percent_data['guilds'] / 100 if percent_data['guilds'] > 0 else 0
#                         other = percent_data['vet'] / 100 if percent_data['vet'] > 0 else 0
#                     else:
#                         company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
#                         union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
#                         guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
#                         other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0
#
#             else:
#
#                 payment_gate_way_percentage = PaymentGatewayPercentage.objects.get(trash=False)
#                 company = payment_gate_way_percentage.company / 100 if payment_gate_way_percentage.company > 0 else 0
#                 union = payment_gate_way_percentage.union / 100 if payment_gate_way_percentage.union > 0 else 0
#                 guilds = payment_gate_way_percentage.guilds / 100 if payment_gate_way_percentage.guilds > 0 else 0
#                 other = payment_gate_way_percentage.other / 100 if payment_gate_way_percentage.other > 0 else 0
#
#             if user.province.name == 'همدان':
#                 gate_way_order_id = ha_order_id
#
#
#             elif user.province.name == 'مركزی':
#                 gate_way_order_id = ma_order_id
#
#
#             else:
#                 gate_way_order_id = test_order_id
#
#             order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
#                                                       now.minute, now.second)
#             guild_id = 0
#             other_id = 0
#             province_other_wage = 0
#             if province_shaba_id == guilds_shaba_id:
#                 guild_id = 1
#                 province_other_wage += (amount * guilds)
#             if province_shaba_id == other_shaba_id:
#                 other_id = 1
#                 province_other_wage += (amount * other)
#
#             if company > 0:
#                 company_total_amount = amount * company
#                 total_remain_amount = company_total_amount
#                 account_amount = 0
#                 beneficiary_accounts = beneficiary_accounts.filter(in_province=True)
#                 if beneficiary_accounts:
#                     for account in beneficiary_accounts:
#                         account_amount = int(company_total_amount * (account.percent / 100))
#                         total_remain_amount -= account_amount
#                         wages.append(
#                             {
#                                 "IBAN": account.shaba,
#                                 "Amount": account_amount,
#                             }
#
#                         )
#                     if total_remain_amount > 0:
#                         wages.append(
#                             {
#                                 "IBAN": arta_shaba_id,
#                                 "Amount": total_remain_amount,
#                             }
#
#                         )
#
#
#
#                 else:
#
#                     wages.append(
#                         {
#                             "IBAN": arta_shaba_id,
#                             "Amount": amount * company,
#                         }
#
#                     )
#
#             if union > 0:
#                 wages.append(
#                     {
#                         "IBAN": province_shaba_id,
#                         "Amount": (amount * union) + province_other_wage
#                     }
#
#                 )
#             if guild_id == 0 or (union == 0 and guild_id == 1):
#                 if guilds > 0:
#                     wages.append(
#                         {
#                             "IBAN": guilds_shaba_id,
#                             "Amount": (amount * guilds),
#                         }
#
#                     )
#             if other_id == 0 or (union == 0 and other_id == 1):
#                 if other > 0:
#                     wages.append(
#                         {
#                             "IBAN": other_shaba_id,
#                             "Amount": (amount * other),
#                         }
#
#                     )
#             result = PaymentGatewayZarinPal(amount, phone, order_id, link, wages)
#             if 500 in result.keys():
#                 wage_payment.state = 'failed'
#                 wage_payment.message = result[500]
#                 wage_payment.save()
#                 if payer == 'kill_house':
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         kill_house=kill_house,
#                         parent_kill_house=parent_kill_house,
#                         payer_fullname=kill_house.kill_house_operator.user.fullname,
#                         payer_mobile=kill_house.kill_house_operator.user.mobile,
#                         payer_type='kill_house',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         orderId=order_id,
#                         message=result[500]
#                     )
#                     transaction.save()
#                 else:
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="failed",
#                         transaction_type="wage-gateway-auto",
#                         chain_company=chain_company,
#                         payer_fullname=chain_company.user.fullname,
#                         payer_mobile=chain_company.user.mobile,
#                         payer_type='chain_company',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         orderId=order_id,
#                         message=result[400]
#                     )
#                     transaction.save()
#
#                 return Response(result[500], status=status.HTTP_400_BAD_REQUEST)
#             else:
#                 wage_payment.authority = result[201]
#                 wage_payment.orderId = order_id
#                 wage_payment.save()
#                 if payer == 'kill_house':
#
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         transaction_type="wage-gateway-auto",
#                         kill_house=kill_house,
#                         parent_kill_house=parent_kill_house,
#                         payer_fullname=kill_house.kill_house_operator.user.fullname,
#                         payer_mobile=kill_house.kill_house_operator.user.mobile,
#                         payer_type='kill_house',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#                 else:
#                     transaction = InternalTransaction(
#                         amount=amount,
#                         status="pending",
#                         # is_complete=False,
#                         transaction_type="wage-gateway-auto",
#                         chain_company=chain_company,
#                         payer_fullname=chain_company.user.fullname,
#                         payer_mobile=chain_company.user.mobile,
#                         payer_type='chain_company',
#                         union_share=amount * union,
#                         union_account=province_shaba_id,
#                         company_share=amount * company,
#                         company_account=arta_shaba_id,
#                         guilds_share=amount * guilds,
#                         guilds_account=guilds_shaba_id,
#                         other_share=amount * other,
#                         other_account=other_shaba_id,
#                         date=now,
#                         authority=result[201],
#                         orderId=order_id
#
#                     )
#                     transaction.save()
#
#                 return Response({"token": result[201]}, status=status.HTTP_201_CREATED)
#
#                 # return Response(serializer.data, status=status.HTTP_201_CREATED)

class WagePaymentTotalViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WagePaymentSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = WagePaymentFilterSet
    filterset_fields = [
        'tracking_code',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_info',

    ]

    def create(self, request, *args, **kwargs):
        link = False
        zarinpal_accounts = ZarinPalAccounts.objects.filter(trash=False)
        beneficiary_accounts = CompanyBeneficiaryAccount.objects.filter(trash=False, percent__gt=0)
        province_shaba_id = zarinpal_accounts.filter(en_name='union').first().account
        arta_shaba_id = zarinpal_accounts.filter(en_name='company').first().account
        guilds_shaba_id = zarinpal_accounts.filter(en_name='guilds').first().account
        other_shaba_id = zarinpal_accounts.filter(en_name='other').first().account
        now = datetime.now()
        wages = []
        amount = 0
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        payer = None
        parent_kill_house = None
        role = request.data['role']
        request.data.pop('role')
        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            parent_kill_house = kill_house
            if kill_house.killer == True and kill_house.type == 'exclusive':
                percentage = KillHousePercentage.objects.filter(kill_house=kill_house, trash=False).first()
                parent_kill_house = percentage.kill_house_for_killer if percentage else kill_house

            payer = 'kill_house'
            phone = kill_house.kill_house_operator.user.mobile
        else:
            chain_company = ChainCompany.objects.get(user=user, trash=False).first()
            payer = 'chain_company'
            phone = chain_company.user.mobile

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            wage_payment = serializer.create(validated_data=request.data)
            amount = wage_payment.total_amount
            wage_payment.payer_info = user.fullname
            wage_payment.payer = {
                "role": role,
                "payer": user.fullname,
                "payment_type": wage_payment.payment_type,
                "tracking_code": wage_payment.tracking_code,
                "date": str(now)

            }

            if payer == 'kill_house':
                if kill_house.share_debt_counting_wage == False:

                    company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
                    union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
                    guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
                    other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0

                else:
                    percent_data = get_kill_house_percent(kill_house)
                    if percent_data and (
                            percent_data['union'] or percent_data['company'] or percent_data['guilds'] or percent_data[
                        'vet']):
                        company = percent_data['company'] / 100 if percent_data['company'] > 0 else 0
                        union = percent_data['union'] / 100 if percent_data['union'] > 0 else 0
                        guilds = percent_data['guilds'] / 100 if percent_data['guilds'] > 0 else 0
                        other = percent_data['vet'] / 100 if percent_data['vet'] > 0 else 0
                    else:
                        company = kill_house.company_gateway_percent / 100 if kill_house.company_gateway_percent > 0 else 0
                        union = kill_house.union_gateway_percent / 100 if kill_house.union_gateway_percent > 0 else 0
                        guilds = kill_house.guilds_gateway_percent / 100 if kill_house.guilds_gateway_percent > 0 else 0
                        other = kill_house.other_gateway_percent / 100 if kill_house.other_gateway_percent > 0 else 0

            else:

                payment_gate_way_percentage = PaymentGatewayPercentage.objects.get(trash=False)
                company = payment_gate_way_percentage.company / 100 if payment_gate_way_percentage.company > 0 else 0
                union = payment_gate_way_percentage.union / 100 if payment_gate_way_percentage.union > 0 else 0
                guilds = payment_gate_way_percentage.guilds / 100 if payment_gate_way_percentage.guilds > 0 else 0
                other = payment_gate_way_percentage.other / 100 if payment_gate_way_percentage.other > 0 else 0

            if user.province.name == 'همدان':
                gate_way_order_id = ha_order_id


            elif user.province.name == 'مركزی':
                gate_way_order_id = ma_order_id


            else:
                gate_way_order_id = test_order_id

            order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
                                                      now.minute, now.second)

            zero_counter = 0
            zero_wages = 0

            if arta_shaba_id == '-' and company > 0:
                zero_wages += amount * company

            if province_shaba_id == '-' and union > 0:
                zero_wages += amount * union

            if guilds_shaba_id == '-' and guilds > 0:
                zero_wages += amount * guilds

            if other_shaba_id == '-' and other > 0:
                zero_wages += amount * other

            if arta_shaba_id != '-' and company > 0:
                zero_counter += 1

            if province_shaba_id != '-' and union > 0:
                zero_counter += 1

            if guilds_shaba_id != '-' and guilds > 0:
                zero_counter += 1

            if other_shaba_id != '-' and other > 0:
                zero_counter += 1

            if zero_counter > 0 and zero_counter != zarinpal_accounts.count():
                zero_wages = zero_wages / (zarinpal_accounts.count() - zero_counter)

            guild_id = 0
            other_id = 0
            province_other_wage = 0
            if province_shaba_id == guilds_shaba_id:
                if guilds > 0:
                    guild_id = 1
                    province_other_wage += (amount * guilds) + zero_wages
            if province_shaba_id == other_shaba_id:
                if other > 0:
                    other_id = 1
                    province_other_wage += (amount * other) + zero_wages

            if arta_shaba_id != '-':

                if company > 0:
                    company_total_amount = (amount * company) + zero_wages
                    total_remain_amount = company_total_amount
                    account_amount = 0
                    beneficiary_accounts = beneficiary_accounts.filter(in_province=True)
                    if beneficiary_accounts:
                        for account in beneficiary_accounts:
                            account_amount = int(company_total_amount * (account.percent / 100))
                            total_remain_amount -= account_amount
                            wages.append(
                                {
                                    "IBAN": account.shaba,
                                    "Amount": account_amount,
                                }

                            )
                        if total_remain_amount > 0:
                            wages.append(
                                {
                                    "IBAN": arta_shaba_id,
                                    "Amount": total_remain_amount,
                                }

                            )



                    else:

                        wages.append(
                            {
                                "IBAN": arta_shaba_id,
                                "Amount": (amount * company) + zero_wages,
                            }

                        )

            if province_shaba_id != '-':

                if union > 0:
                    wages.append(
                        {
                            "IBAN": province_shaba_id,
                            "Amount": (amount * union) + province_other_wage + zero_wages
                        }

                    )

            if guilds_shaba_id != '-':

                if guild_id == 0 or (union == 0 and guild_id == 1):
                    if guilds > 0:
                        wages.append(
                            {
                                "IBAN": guilds_shaba_id,
                                "Amount": (amount * guilds) + zero_wages,
                            }

                        )
            if other_shaba_id != '-':
                if other_id == 0 or (union == 0 and other_id == 1):
                    if other > 0:
                        wages.append(
                            {
                                "IBAN": other_shaba_id,
                                "Amount": (amount * other) + zero_wages,
                            }

                        )
            result = PaymentGatewayZarinPal(amount, phone, order_id, link, wages)
            if 500 in result.keys():
                wage_payment.state = 'failed'
                wage_payment.message = result[500]
                wage_payment.save()
                if payer == 'kill_house':
                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        kill_house=kill_house,
                        parent_kill_house=parent_kill_house,
                        payer_fullname=kill_house.kill_house_operator.user.fullname,
                        payer_mobile=kill_house.kill_house_operator.user.mobile,
                        payer_type='kill_house',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        orderId=order_id,
                        message=result[500]
                    )
                    transaction.save()
                else:
                    transaction = InternalTransaction(
                        amount=amount,
                        status="failed",
                        transaction_type="wage-gateway-auto",
                        chain_company=chain_company,
                        payer_fullname=chain_company.user.fullname,
                        payer_mobile=chain_company.user.mobile,
                        payer_type='chain_company',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        orderId=order_id,
                        message=result[400]
                    )
                    transaction.save()

                return Response(result[500], status=status.HTTP_400_BAD_REQUEST)
            else:
                wage_payment.authority = result[201]
                wage_payment.orderId = order_id
                wage_payment.save()
                if payer == 'kill_house':

                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        transaction_type="wage-gateway-auto",
                        kill_house=kill_house,
                        parent_kill_house=parent_kill_house,
                        payer_fullname=kill_house.kill_house_operator.user.fullname,
                        payer_mobile=kill_house.kill_house_operator.user.mobile,
                        payer_type='kill_house',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        orderId=order_id

                    )
                    transaction.save()
                else:
                    transaction = InternalTransaction(
                        amount=amount,
                        status="pending",
                        # is_complete=False,
                        transaction_type="wage-gateway-auto",
                        chain_company=chain_company,
                        payer_fullname=chain_company.user.fullname,
                        payer_mobile=chain_company.user.mobile,
                        payer_type='chain_company',
                        union_share=(amount * union) + zero_wages if province_shaba_id != '-' and union > 0 else 0,
                        union_account=province_shaba_id,
                        company_share=(amount * company) + zero_wages if arta_shaba_id != '-' and company > 0 else 0,
                        company_account=arta_shaba_id,
                        guilds_share=(amount * guilds) + zero_wages if guilds_shaba_id != '-' and guilds > 0 else 0,
                        guilds_account=guilds_shaba_id,
                        other_share=(amount * other) + zero_wages if other_shaba_id != '-' and other > 0 else 0,
                        other_account=other_shaba_id,
                        date=now,
                        authority=result[201],
                        orderId=order_id

                    )
                    transaction.save()

                return Response({"token": result[201]}, status=status.HTTP_201_CREATED)

                # return Response(serializer.data, status=status.HTTP_201_CREATED)


class WagePaymentViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WagePaymentSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = WagePaymentFilterSet
    filterset_fields = [
        'tracking_code',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_info',

    ]

    def create(self, request, *args, **kwargs):
        now = datetime.now()
        total_amount = 0
        final_total_amount = 0
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        wage = ShareOfAllocation.objects.all().last()
        wage = wage.province_union if wage else 0
        role = request.data['role']
        request.data.pop('role')
        wallet = False
        kill_house_key = None
        if 'amount' in request.data.keys():
            wallet = True
            input_amout = request.data['amount']
            input_amount_with_tax = request.data['amount_with_tax']
            kill_house_key = request.data['kill_house_key']
            request.data.pop('amount')
            request.data.pop('amount_with_tax')
            request.data.pop('kill_house_key')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            wage_payment = serializer.create(validated_data=request.data)
            wage_payment.payer_info = user.fullname
            wage_payment.payer = {
                "role": role,
                "payer": user.fullname,
                "payment_type": wage_payment.payment_type,
                "tracking_code": wage_payment.tracking_code,
                "date": str(now)

            }
            if request.data['payment_type'] == 'manual':
                for province_kill_request in wage_payment.province_kill_request:
                    kill_request = ProvinceKillRequest.objects.filter(key=province_kill_request).select_related(
                        'province_request__poultry_request').last()
                    kill_request.wage_pay = True
                    kill_request.depositor = {
                        "role": role,
                        "payer": user.fullname,
                        "date": str(now),
                        "payment_type": wage_payment.payment_type,
                        "tracking_code": wage_payment.tracking_code,
                        "refId": 0,
                        "orderId": 0,
                        "total_amount": kill_request.total_killed_weight * kill_request.wage
                    }
                    kill_request.save()

                    total_amount += kill_request.depositor['total_amount']
                kill_house = KillHouse.objects.filter(
                    key=kill_request.kill_request.kill_house.key).select_related(
                    'kill_house_operator__user').first()
                kill_house_user = kill_house.kill_house_operator.user
                creator = kill_house.kill_house_operator.user if role == 'KillHouse' else user
                receiver = user if role == 'KillHouse' else SystemUserProfile.objects.filter(
                    role__name='ProvinceOperator',
                    province=user.province).first()
                wage_payment.total_amount = total_amount
                wage_payment.state = "completed"
                wage_payment.save()
                transaction = ExternalTransaction(
                    amount=total_amount,
                    status="completed",
                    transaction_type="wage-manual",
                    is_complete=True,
                    saleReferenceId=wage_payment.tracking_code,
                    kill_house_user=kill_house_user,
                    creator=creator,
                    receiver=receiver,
                    creator_role='KillHouse',
                    receiver_role='ProvinceOperator',
                    payer=user.fullname

                )
                transaction.save()

                return Response(serializer.data, status=status.HTTP_201_CREATED)
            # return Response(serializer.errors)

            else:
                if wallet == True:

                    kill_house = KillHouse.objects.filter(key=kill_house_key, trash=False).select_related(
                        'kill_house_operator__user').first()
                    kill_house_user = kill_house.kill_house_operator.user
                    creator = kill_house_user
                    receiver = kill_house_user
                    total_amount = input_amout
                    wage_payment.total_amount_with_tax = input_amount_with_tax
                    wage_payment.type = "wallet"
                else:

                    for province_kill_request in wage_payment.province_kill_request:
                        kill_request = ProvinceKillRequest.objects.filter(key=province_kill_request).select_related(
                            'province_request__poultry_request').last()
                        # kill_request.wage_pay = True
                        kill_request.depositor = {
                            "role": role,
                            "payer": user.fullname,
                            "date": str(now),
                            "payment_type": wage_payment.payment_type,
                            "total_amount": kill_request.total_killed_weight * kill_request.wage
                        }
                        kill_request.save()

                        total_amount += kill_request.depositor['total_amount']
                    kill_house = KillHouse.objects.filter(
                        key=kill_request.kill_request.kill_house.key).select_related(
                        'kill_house_operator__user').first()
                    kill_house_user = kill_house.kill_house_operator.user
                    creator = kill_house.kill_house_operator.user if role == 'KillHouse' else user
                    receiver = user if role == 'KillHouse' else SystemUserProfile.objects.filter(
                        role__name='ProvinceOperator',
                        province=user.province).first()
                    wage_payment.total_amount_with_tax = total_amount + (total_amount * (10 / 100))

                wage_payment.total_amount = total_amount
                wage_payment.save()

                payment_gate_way_percentage = PaymentGatewayPercentage.objects.get(trash=False)
                company = payment_gate_way_percentage.company / 100 if payment_gate_way_percentage.company > 0 else 0
                union = payment_gate_way_percentage.union / 100 if payment_gate_way_percentage.union > 0 else 0
                guilds = payment_gate_way_percentage.guilds / 100 if payment_gate_way_percentage.guilds > 0 else 0

                if user.province.name == 'لرستان':
                    province_deposit_id = sha_deposit_id
                    province_deposit_percent = union
                    arta_api_deposit_id = arta_deposit_id
                    arta_api_deposit_percent = company
                    guilds_api_deposit_id = guilds_deposit_id
                    guilds_api_deposit_percent = guilds
                    gate_way_order_id = test_order_id


                elif user.province.name == 'آذربایجان شرقی':
                    province_deposit_id = sha_deposit_id
                    province_deposit_percent = union
                    arta_api_deposit_id = arta_deposit_id
                    arta_api_deposit_percent = company
                    guilds_api_deposit_id = guilds_deposit_id
                    guilds_api_deposit_percent = guilds
                    gate_way_order_id = sha_order_id

                elif user.province.name == 'اردبیل':
                    province_deposit_id = ar_deposit_id
                    province_deposit_percent = union
                    arta_api_deposit_id = arta_deposit_id
                    arta_api_deposit_percent = company
                    guilds_api_deposit_id = guilds_deposit_id
                    guilds_api_deposit_percent = guilds
                    gate_way_order_id = ar_order_id



                elif user.province.name == 'همدان':
                    province_deposit_id = ha_deposit_id
                    province_deposit_percent = union
                    arta_api_deposit_id = arta_deposit_id
                    arta_api_deposit_percent = company
                    guilds_api_deposit_id = guilds_deposit_id
                    guilds_api_deposit_percent = guilds
                    gate_way_order_id = ha_order_id


                elif user.province.name == 'مركزی':
                    province_deposit_id = ma_deposit_id
                    province_deposit_percent = union
                    arta_api_deposit_id = arta_deposit_id
                    arta_api_deposit_percent = company
                    guilds_api_deposit_id = guilds_deposit_id
                    guilds_api_deposit_percent = guilds
                    gate_way_order_id = ma_order_id

                order_id = "{0}{1}{2}{3}{4}{5}{6}".format(gate_way_order_id, now.year, now.month, now.day, now.hour,
                                                          now.minute, now.second)
                # if user.province.name == 'مركزی':
                #     result = PaymentGateway(
                #         "{0},{1},0;{2},{3},0;".format(province_deposit_id, 100,
                #                                       arta_api_deposit_id,
                #                                       int(total_amount - 100)), int(total_amount),
                #         order_id)
                # else:

                if wallet == True:
                    final_total_amount = input_amount_with_tax
                else:
                    final_total_amount = total_amount + (total_amount * (10 / 100))
                if company > 0 and union > 0 and guilds > 0:
                    result = PaymentGateway(
                        "{0},{1},0;{2},{3},0;{4},{5},0;".format(province_deposit_id,
                                                                int(final_total_amount * union),
                                                                arta_api_deposit_id,
                                                                int(final_total_amount * company),
                                                                guilds_api_deposit_id,
                                                                int(final_total_amount * guilds)),
                        int(final_total_amount),
                        order_id)
                elif company > 0 and union > 0 and guilds == 0:
                    result = PaymentGateway(
                        "{0},{1},0;{2},{3},0;".format(province_deposit_id,
                                                      int(final_total_amount * union),
                                                      arta_api_deposit_id,
                                                      int(final_total_amount * company)),
                        int(final_total_amount),
                        order_id)

                elif company > 0 and union == 0 and guilds > 0:
                    result = PaymentGateway(
                        "{0},{1},0;{2},{3},0;".format(

                            arta_api_deposit_id,
                            int(final_total_amount * company),
                            guilds_api_deposit_id,
                            int(final_total_amount * guilds)),
                        int(final_total_amount),
                        order_id)
                else:
                    result = PaymentGateway(
                        "{0},{1},0;{2},{3},0;".format(province_deposit_id,
                                                      int(final_total_amount * union),
                                                      guilds_api_deposit_id,
                                                      int(final_total_amount * guilds)),
                        int(final_total_amount),
                        order_id)

                # result = PaymentGateway(
                #     "{0},{1},0;{2},{3},0;".format(sha_deposit_id, 10000, arta_deposit_id, 10000),20000, order_id)
                if '400' in result.keys():
                    wage_payment.state = 'failed'
                    wage_payment.message = result[400]
                    wage_payment.save()
                    if wallet == True:
                        transaction = ExternalTransaction(
                            amount=total_amount,
                            amount_with_tax=final_total_amount,
                            status="failed",
                            type="deposit",
                            transaction_type="wallet",
                            is_complete=False,
                            kill_house_user=kill_house_user,
                            creator=creator,
                            receiver=receiver,
                            creator_role='KillHouse',
                            receiver_role='KillHouse',
                            payer=kill_house_user.fullname,
                            message=result[400]

                        )
                        transaction.save()
                    else:
                        transaction = ExternalTransaction(
                            amount=total_amount,
                            amount_with_tax=final_total_amount,
                            status="failed",
                            transaction_type="wage-gateway",
                            is_complete=False,
                            kill_house_user=kill_house_user,
                            creator=creator,
                            receiver=receiver,
                            creator_role='KillHouse',
                            receiver_role='ProvinceOperator',
                            payer=user.fullname,
                            message=result[400]

                        )
                        transaction.save()
                        return Response(result[400], status=status.HTTP_400_BAD_REQUEST)
                else:
                    wage_payment.refId = result[200]
                    wage_payment.orderId = order_id
                    wage_payment.save()
                    if wallet == True:
                        transaction = ExternalTransaction(
                            amount=total_amount,
                            amount_with_tax=final_total_amount,
                            status="pending",
                            type="deposit",
                            transaction_type="wallet",
                            is_complete=False,
                            kill_house_user=kill_house_user,
                            creator=creator,
                            receiver=receiver,
                            receiver_role='KillHouse',
                            creator_role='KillHouse',
                            payer=kill_house_user.fullname,
                            refId=result[200],
                            orderId=order_id

                        )
                        transaction.save()
                    else:

                        transaction = ExternalTransaction(
                            amount=total_amount,
                            amount_with_tax=final_total_amount,
                            status="pending",
                            transaction_type="wage-gateway",
                            is_complete=False,
                            kill_house_user=kill_house_user,
                            creator=creator,
                            receiver=receiver,
                            receiver_role='KillHouse',
                            creator_role='ProvinceOperator',
                            payer=user.fullname,
                            refId=result[200],
                            orderId=order_id

                        )
                        transaction.save()
                    return Response({"refId": result[200]}, status=status.HTTP_201_CREATED)

                # return Response(serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        wage_payment_list = []

        if request.GET['state'] == 'failed':
            wage_payment = WagePayment.objects.filter(
                create_date__date__gte=date1,
                create_date__date__lte=date2,
                state='failed',
                trash=False).order_by('id')
        else:
            wage_payment = WagePayment.objects.filter(
                create_date__date__gte=date1,
                create_date__date__lte=date2,
                state='completed',
                trash=False).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(wage_payment)
        if page is not None:
            serializer = WagePaymentSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = WagePaymentSerializer(wage_payment, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class WagePaymentFinalStepViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [AllowAny]
    serializer_class = WagePaymentSerializer

    def create(self, request, *args, **kwargs):
        ref_id = request.data['refId']
        wage_payment = WagePayment.objects.get(refId=ref_id, trash=False, state='pending')
        transaction = InternalTransaction.objects.get(refId=ref_id, trash=False, status='pending')

        if 'error' in request.data.keys():
            wage_payment.state = "failed"
            wage_payment.message = request.data['error']
            wage_payment.save()
            transaction.status = "failed"
            transaction.message = request.data['error']
            transaction.save()

            return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
        else:
            now = datetime.now()
            wage_payment.payer['date'] = str(now)
            wage_payment.payer['tracking_code'] = request.data['saleReferenceId']
            wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
            wage_payment.refId = request.data['refId']
            wage_payment.orderId = request.data['saleOrderId']
            wage_payment.cardHolderPan = request.data['cardHolderPan']
            wage_payment.tracking_code = request.data['saleReferenceId']
            wage_payment.state = "completed"
            wage_payment.save()
            transaction.refId = request.data['refId']
            transaction.orderId = request.data['saleOrderId']
            transaction.cardHolderPan = request.data['cardHolderPan']
            transaction.saleReferenceId = request.data['saleReferenceId']
            transaction.status = "completed"
            transaction.save()
            text = []
            killer = ''

            if transaction.kill_house is not None:
                user = transaction.kill_house.name
                mobile = transaction.kill_house.kill_house_operator.user.mobile
                killer = 'کشتارگاه' if transaction.kill_house.killer == False else 'کشتارکن'

            else:
                user = transaction.chain_company.name
                mobile = transaction.chain_company.user.mobile
            from_date = jdatetime.date.fromgregorian(
                year=transaction.date.year,
                month=transaction.date.month,
                day=transaction.date.day
            ).strftime('%Y-%m-%d')
            reversed_date = reversed(from_date.split("-"))
            separate = "-"
            date = separate.join(reversed_date)
            province = transaction.kill_house.kill_house_operator.user.province.name
            if transaction.union_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.union_share,
                    'mobile': UNION_NUMBER,
                    'province': province,
                    'killer': killer

                })
            if transaction.company_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.company_share,
                    'mobile': COMPANY_NUMBER,
                    'province': province,
                    'killer': killer

                })
            if transaction.guilds_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.guilds_share,
                    'mobile': GUILD_NUMBER,
                    'province': province,
                    'killer': killer

                })
            text_for_company = [{
                'payer': user,
                'date': date,
                'share': transaction.amount,
                'mobile': COMPANY_NUMBER,
                'province': province,
                'killer': killer

            }]
            transaction_for_eata(request, transaction)
            send_sms_for_company = threading.Thread(target=transaction_sms_threading_for_company,
                                                    args=(text_for_company))
            send_sms_for_kill_house = threading.Thread(target=transaction_sms_threading_appreciation,
                                                       args=(user, mobile))
            send_sms = threading.Thread(target=transaction_sms_threading, args=(text))
            send_sms.start()
            send_sms_for_company.start()
            send_sms_for_kill_house.start()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

    # def create(self, request, *args, **kwargs):
    #     ref_id = request.data['refId']
    #     wage_payment = WagePayment.objects.get(refId=ref_id, trash=False, state='pending')
    #     transaction = ExternalTransaction.objects.get(refId=ref_id, trash=False, status='pending')
    #
    #     if 'error' in request.data.keys():
    #         wage_payment.state = "failed"
    #         wage_payment.message = request.data['error']
    #         wage_payment.save()
    #         transaction.status = "failed"
    #         transaction.message = request.data['error']
    #         transaction.save()
    #
    #         return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
    #     else:
    #         now = datetime.now()
    #         wage_payment.payer['date'] = str(now)
    #         wage_payment.payer['tracking_code'] = request.data['saleReferenceId']
    #         wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
    #         if wage_payment.type == None:
    #
    #             for province_kill_request in wage_payment.province_kill_request:
    #                 province_kill_request = ProvinceKillRequest.objects.filter(
    #                     key=province_kill_request).select_related(
    #                     'province_request__poultry_request').last()
    #                 province_kill_request.wage_pay = True
    #                 province_kill_request.depositor['tracking_code'] = request.data['saleReferenceId']
    #                 province_kill_request.depositor['orderId'] = request.data['saleOrderId']
    #                 province_kill_request.depositor['refId'] = request.data['refId']
    #                 province_kill_request.depositor[
    #                     'total_amount'] = province_kill_request.total_killed_weight * province_kill_request.wage
    #                 # province_kill_request.depositor['total_amount'] = request.data['finalAmount']
    #                 province_kill_request.depositor['date'] = str(now)
    #                 province_kill_request.depositor['cardHolderPan'] = request.data['cardHolderPan']
    #                 province_kill_request.save()
    #
    #         wage_payment.total_amount_with_tax = request.data['finalAmount']
    #         wage_payment.refId = request.data['refId']
    #         wage_payment.orderId = request.data['saleOrderId']
    #         wage_payment.cardHolderPan = request.data['cardHolderPan']
    #         wage_payment.tracking_code = request.data['saleReferenceId']
    #         wage_payment.state = "completed"
    #         wage_payment.save()
    #         transaction.amount_with_tax = request.data['finalAmount']
    #         transaction.refId = request.data['refId']
    #         transaction.orderId = request.data['saleOrderId']
    #         transaction.cardHolderPan = request.data['cardHolderPan']
    #         transaction.saleReferenceId = request.data['saleReferenceId']
    #         transaction.status = "completed"
    #         transaction.save()
    #
    #         return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)


class WagePaymentWithLinkFinalStepViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [AllowAny]
    serializer_class = WagePaymentSerializer

    def create(self, request, *args, **kwargs):
        authority = request.data['authority']
        wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
        # wage_payment = WagePayment.objects.get(authority=authority, trash=False, state='pending')
        transaction = InternalTransaction.objects.get(authority=authority, trash=False, status='pending')

        if 'error' in request.data.keys():
            # wage_payment.state = "failed"
            # wage_payment.message = request.data['error']
            # wage_payment.save()
            transaction.status = "failed"
            transaction.message = request.data['error']
            transaction.save()

            return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
        else:
            now = datetime.now()
            # wage_payment.payer['date'] = str(now)
            # wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
            # wage_payment.refId = request.data['refId']
            # wage_payment.cardHolderPan = request.data['cardHolderPan']
            # wage_payment.state = "completed"
            # wage_payment.save()
            transaction.refId = request.data['refId']
            transaction.cardHolderPan = request.data['cardHolderPan']
            transaction.status = "completed"
            transaction.save()
            text = []

            if transaction.payer_type == 'poultry':
                # if transaction.poultry_request is not None:
                #     poultry_requests = PoultryRequest.objects.filter(id=transaction.poultry_request.id,trash=False)
                #
                #
                # else:
                # poultry_requests = PoultryRequest.objects.filter(payer_type='poultry',
                #                                                  poultry__user=transaction.user,
                #                                                  out_province_request_cancel=False, out=True,
                #                                                  has_wage=True,
                #                                                  province_state='accepted', wage_pay=False, trash=False)
                poultry_requests = transaction.poultry_request.all()
                for poultry_request in poultry_requests:
                    if poultry_request.has_wage == True and poultry_request.wage_pay == False:
                        # hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
                        # if hatching.left_over >= poultry_request.quantity:
                        #     hatching.out_province_killed_weight += int(
                        #         poultry_request.quantity * poultry_request.Index_weight)
                        #     hatching.out_province_killed_quantity += poultry_request.quantity
                        #     hatching.save()
                        # else:
                        #     different_quantity = poultry_request.quantity - hatching.left_over
                        #     hatching.out_province_killed_weight += int(
                        #         hatching.left_over * poultry_request.Index_weight)
                        #     hatching.out_province_killed_quantity += hatching.left_over
                        #     hatching.extra_killed_quantity += different_quantity
                        #     hatching.save()
                        poultry_request.wage_pay = True
                        poultry_request.save()
                        if wage_type and wage_type.status == True:
                            province_operator = ProvinceOperator.objects.filter(trash=False).last()

                            vet = VetFarm.objects.filter(trash=False, poultry=poultry_request.poultry).first()
                            vet_number = vet.vet.user.mobile if vet else None
                            province_operator_mobile = province_operator.user.mobile
                            date_str = poultry_request.send_date
                            send_date = datetime.strptime(str(date_str), '%Y-%m-%d %H:%M:%S').date()
                            send_date = jdatetime.datetime.fromgregorian(year=send_date.year, month=send_date.month,
                                                                         day=send_date.day).strftime('%Y-%m-%d')
                            date_list = reversed(send_date.split('-'))
                            separate = "-"
                            send_date = separate.join(date_list)
                            poultry_fullname = poultry_request.poultry.unit_name
                            quantity = poultry_request.quantity
                            chicken_breed = poultry_request.chicken_breed
                            order_code = poultry_request.order_code
                            sms_operator_out_poultry_request_sms = threading.Thread(
                                target=operator_out_poultry_request_sms,
                                args=(
                                    province_operator_mobile,
                                    poultry_fullname,
                                    quantity, chicken_breed,
                                    order_code, send_date,
                                    poultry_request.free_sale_in_province,
                                    poultry_request.amount,
                                    vet_number
                                ))
                            sms_operator_out_poultry_request_sms.start()
                vet_farm = VetFarm.objects.filter(trash=False, poultry__in=poultry_requests.values_list('poultry',
                                                                                                        flat=True).distinct()).first()
                bot_eitaa_out_province_live_bar(request, poultry_requests, vet_farm)
            if transaction.payer_type == 'buyer':
                buyer = OutProvincePoultryRequestBuyer.objects.get(user=transaction.user, trash=False)
                poultry_requests = transaction.poultry_request.all()
                # poultry_requests = PoultryRequest.objects.filter(out_province_poultry_request_buyer=buyer,
                #                                                  payer_type='buyer', out_province_request_cancel=False,
                #                                                  out=True, has_wage=True,
                #                                                  province_state='accepted', wage_pay=False, trash=False)
                for poultry_request in poultry_requests:
                    if poultry_request.has_wage == True and poultry_request.wage_pay == False:
                        # hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
                        # if hatching.left_over >= poultry_request.quantity:
                        #     hatching.out_province_killed_weight += int(
                        #         poultry_request.quantity * poultry_request.Index_weight)
                        #     hatching.out_province_killed_quantity += poultry_request.quantity
                        #     hatching.save()
                        # else:
                        #     different_quantity = poultry_request.quantity - hatching.left_over
                        #     hatching.out_province_killed_weight += int(
                        #         hatching.left_over * poultry_request.Index_weight)
                        #     hatching.out_province_killed_quantity += hatching.left_over
                        #     hatching.extra_killed_quantity += different_quantity
                        #     hatching.save()
                        poultry_request.wage_pay = True
                        poultry_request.save()

                        if wage_type and wage_type.status == True:
                            province_operator = ProvinceOperator.objects.filter(trash=False).last()

                            vet = VetFarm.objects.filter(trash=False, poultry=poultry_request.poultry).first()
                            vet_number = vet.vet.user.mobile if vet else None
                            province_operator_mobile = province_operator.user.mobile
                            date_str = poultry_request.send_date
                            send_date = datetime.strptime(str(date_str), '%Y-%m-%d %H:%M:%S').date()
                            send_date = jdatetime.datetime.fromgregorian(year=send_date.year, month=send_date.month,
                                                                         day=send_date.day).strftime('%Y-%m-%d')
                            date_list = reversed(send_date.split('-'))
                            separate = "-"
                            send_date = separate.join(date_list)
                            poultry_fullname = poultry_request.poultry.unit_name
                            quantity = poultry_request.quantity
                            chicken_breed = poultry_request.chicken_breed
                            order_code = poultry_request.order_code
                            sms_operator_out_poultry_request_sms = threading.Thread(
                                target=operator_out_poultry_request_sms,
                                args=(
                                    province_operator_mobile,
                                    poultry_fullname,
                                    quantity, chicken_breed,
                                    order_code, send_date,
                                    poultry_request.free_sale_in_province,
                                    poultry_request.amount,
                                    vet_number
                                ))
                            sms_operator_out_poultry_request_sms.start()
                vet_farm = VetFarm.objects.filter(trash=False, poultry__in=poultry_requests.values_list('poultry',
                                                                                                        flat=True).distinct()).first()

                bot_eitaa_out_province_live_bar(request, poultry_requests, vet_farm)
            killer = ''
            if transaction.kill_house is not None:
                user = transaction.kill_house.name
                mobile = transaction.kill_house.kill_house_operator.user.mobile
                killer = 'کشتارگاه' if transaction.kill_house.killer == False else 'کشتارکن'
                province = transaction.kill_house.kill_house_operator.user.province.name
            elif transaction.out_province_poultry_request_buyer is not None:
                buyer = OutProvincePoultryRequestBuyer.objects.get(user=transaction.user, trash=False)
                user = buyer.user.fullname
                mobile = buyer.user.mobile
                province = buyer.province




            # elif transaction.poultry_request is not None:
            #     poultry_request = PoultryRequest.objects.get(key=transaction.poultry_request.key, trash=False)
            #     poultry_request.wage_pay = True
            #     poultry_request.save()
            #     update_out_province_hatching(poultry_request.hatching)
            #
            #     user = transaction.poultry_request.poultry.unit_name if transaction.poultry_request.payer_type == 'poultry' else transaction.poultry_request.payer_fullname
            #     mobile = transaction.poultry_request.poultry.user.mobile if transaction.poultry_request.payer_type == 'poultry' else \
            #         transaction.poultry_request.buyer['mobile']

            elif transaction.chain_company is not None:
                user = transaction.chain_company.name
                mobile = transaction.chain_company.user.mobile
                province = transaction.chain_company.user.province.name

            else:
                user = transaction.user.fullname
                mobile = transaction.user.mobile
                province = transaction.user.province.name

            from_date = jdatetime.date.fromgregorian(
                year=transaction.date.year,
                month=transaction.date.month,
                day=transaction.date.day
            ).strftime('%Y-%m-%d')
            reversed_date = reversed(from_date.split("-"))
            separate = "-"
            date = separate.join(reversed_date)
            if transaction.union_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.union_share,
                    'mobile': UNION_NUMBER,
                    'province': province,
                    'killer': killer

                })
            if transaction.company_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.company_share,
                    'mobile': COMPANY_NUMBER,
                    'province': province,
                    'killer': killer

                })
            if transaction.guilds_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.guilds_share,
                    'mobile': GUILD_NUMBER,
                    'province': province,
                    'killer': killer

                })
            text_for_company = [{
                'payer': user,
                'date': date,
                'share': transaction.amount,
                'mobile': COMPANY_NUMBER,
                'province': province,
                'killer': killer

            }]
            transaction_for_eata(request, transaction)
            if transaction.kill_house is not None:
                send_sms_for_zir_bakhs = threading.Thread(target=transaction_sms_threading_in_province,
                                                          args=(text))
                send_sms_for_zir_bakhs.start()

            send_sms_for_company = threading.Thread(target=transaction_sms_threading_for_company,
                                                    args=(text_for_company))
            send_sms_for_kill_house = threading.Thread(target=transaction_sms_threading_appreciation,
                                                       args=(user, mobile))
            send_sms = threading.Thread(target=transaction_sms_threading, args=(text))
            send_sms.start()
            send_sms_for_company.start()
            send_sms_for_kill_house.start()

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

    # def create(self, request, *args, **kwargs):
    #     ref_id = request.data['refId']
    #     wage_payment = WagePayment.objects.get(refId=ref_id, trash=False, state='pending')
    #     transaction = ExternalTransaction.objects.get(refId=ref_id, trash=False, status='pending')
    #
    #     if 'error' in request.data.keys():
    #         wage_payment.state = "failed"
    #         wage_payment.message = request.data['error']
    #         wage_payment.save()
    #         transaction.status = "failed"
    #         transaction.message = request.data['error']
    #         transaction.save()
    #
    #         return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
    #     else:
    #         now = datetime.now()
    #         wage_payment.payer['date'] = str(now)
    #         wage_payment.payer['tracking_code'] = request.data['saleReferenceId']
    #         wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
    #         if wage_payment.type == None:
    #
    #             for province_kill_request in wage_payment.province_kill_request:
    #                 province_kill_request = ProvinceKillRequest.objects.filter(
    #                     key=province_kill_request).select_related(
    #                     'province_request__poultry_request').last()
    #                 province_kill_request.wage_pay = True
    #                 province_kill_request.depositor['tracking_code'] = request.data['saleReferenceId']
    #                 province_kill_request.depositor['orderId'] = request.data['saleOrderId']
    #                 province_kill_request.depositor['refId'] = request.data['refId']
    #                 province_kill_request.depositor[
    #                     'total_amount'] = province_kill_request.total_killed_weight * province_kill_request.wage
    #                 # province_kill_request.depositor['total_amount'] = request.data['finalAmount']
    #                 province_kill_request.depositor['date'] = str(now)
    #                 province_kill_request.depositor['cardHolderPan'] = request.data['cardHolderPan']
    #                 province_kill_request.save()
    #
    #         wage_payment.total_amount_with_tax = request.data['finalAmount']
    #         wage_payment.refId = request.data['refId']
    #         wage_payment.orderId = request.data['saleOrderId']
    #         wage_payment.cardHolderPan = request.data['cardHolderPan']
    #         wage_payment.tracking_code = request.data['saleReferenceId']
    #         wage_payment.state = "completed"
    #         wage_payment.save()
    #         transaction.amount_with_tax = request.data['finalAmount']
    #         transaction.refId = request.data['refId']
    #         transaction.orderId = request.data['saleOrderId']
    #         transaction.cardHolderPan = request.data['cardHolderPan']
    #         transaction.saleReferenceId = request.data['saleReferenceId']
    #         transaction.status = "completed"
    #         transaction.save()
    #
    #         return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)


class WagePaymentFinalStepZarinPalViewset(viewsets.ModelViewSet):
    queryset = WagePayment.objects.all()
    permission_classes = [AllowAny]
    serializer_class = WagePaymentSerializer

    def create(self, request, *args, **kwargs):
        authority = request.data['authority']
        # wage_payment = WagePayment.objects.get(authority=authority, trash=False, state='pending')
        transaction = InternalTransaction.objects.get(authority=authority, trash=False, status='pending')
        # ref_id = request.data['refId']
        # wage_payment = WagePayment.objects.get(refId=ref_id, trash=False, state='pending')
        # transaction = InternalTransaction.objects.get(refId=ref_id, trash=False, status='pending')

        if 'error' in request.data.keys():
            # wage_payment.state = "failed"
            # wage_payment.message = request.data['error']
            # wage_payment.save()
            # transaction.status = "failed"
            transaction.message = request.data['error']
            transaction.save()

            return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
        else:
            now = datetime.now()
            # wage_payment.payer['date'] = str(now)
            # wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
            # wage_payment.refId = request.data['refId']
            # wage_payment.cardHolderPan = request.data['cardHolderPan']
            # wage_payment.state = "completed"
            # wage_payment.save()
            transaction.refId = request.data['refId']
            transaction.cardHolderPan = request.data['cardHolderPan']
            transaction.status = "completed"
            transaction.save()
            text = []
            killer = ''

            if transaction.kill_house is not None:
                user = transaction.kill_house.name
                mobile = transaction.kill_house.kill_house_operator.user.mobile
                killer = 'کشتارگاه' if transaction.kill_house.killer == False else 'کشتارکن'
            else:
                user = transaction.chain_company.name
                mobile = transaction.chain_company.user.mobile
            from_date = jdatetime.date.fromgregorian(
                year=transaction.date.year,
                month=transaction.date.month,
                day=transaction.date.day
            ).strftime('%Y-%m-%d')
            reversed_date = reversed(from_date.split("-"))
            separate = "-"
            date = separate.join(reversed_date)
            province = transaction.kill_house.kill_house_operator.user.province.name

            if transaction.union_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.union_share,
                    'mobile': UNION_NUMBER,
                    'province': province,
                    'killer': killer
                })
            if transaction.company_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.company_share,
                    'mobile': COMPANY_NUMBER,
                    'province': province,
                    'killer': killer

                })
            if transaction.guilds_share > 0:
                text.append({
                    'payer': user,
                    'date': date,
                    'share': transaction.guilds_share,
                    'mobile': GUILD_NUMBER,
                    'province': province,
                    'killer': killer

                })
            text_for_company = [{
                'payer': user,
                'date': date,
                'share': transaction.amount,
                'mobile': COMPANY_NUMBER,
                'province': province,
                'killer': killer

            }]
            transaction_for_eata(request, transaction)
            send_sms_for_company = threading.Thread(target=transaction_sms_threading_for_company,
                                                    args=(text_for_company))
            send_sms_for_kill_house = threading.Thread(target=transaction_sms_threading_appreciation,
                                                       args=(user, mobile))
            send_sms = threading.Thread(target=transaction_sms_threading, args=(text))
            send_sms.start()
            send_sms_for_company.start()
            send_sms_for_kill_house.start()
            return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)

    # def create(self, request, *args, **kwargs):
    #     ref_id = request.data['refId']
    #     wage_payment = WagePayment.objects.get(refId=ref_id, trash=False, state='pending')
    #     transaction = ExternalTransaction.objects.get(refId=ref_id, trash=False, status='pending')
    #
    #     if 'error' in request.data.keys():
    #         wage_payment.state = "failed"
    #         wage_payment.message = request.data['error']
    #         wage_payment.save()
    #         transaction.status = "failed"
    #         transaction.message = request.data['error']
    #         transaction.save()
    #
    #         return Response({"result": "با خطا مواجه شد"}, status=status.HTTP_200_OK)
    #     else:
    #         now = datetime.now()
    #         wage_payment.payer['date'] = str(now)
    #         wage_payment.payer['tracking_code'] = request.data['saleReferenceId']
    #         wage_payment.payer['cardHolderPan'] = request.data['cardHolderPan']
    #         if wage_payment.type == None:
    #
    #             for province_kill_request in wage_payment.province_kill_request:
    #                 province_kill_request = ProvinceKillRequest.objects.filter(
    #                     key=province_kill_request).select_related(
    #                     'province_request__poultry_request').last()
    #                 province_kill_request.wage_pay = True
    #                 province_kill_request.depositor['tracking_code'] = request.data['saleReferenceId']
    #                 province_kill_request.depositor['orderId'] = request.data['saleOrderId']
    #                 province_kill_request.depositor['refId'] = request.data['refId']
    #                 province_kill_request.depositor[
    #                     'total_amount'] = province_kill_request.total_killed_weight * province_kill_request.wage
    #                 # province_kill_request.depositor['total_amount'] = request.data['finalAmount']
    #                 province_kill_request.depositor['date'] = str(now)
    #                 province_kill_request.depositor['cardHolderPan'] = request.data['cardHolderPan']
    #                 province_kill_request.save()
    #
    #         wage_payment.total_amount_with_tax = request.data['finalAmount']
    #         wage_payment.refId = request.data['refId']
    #         wage_payment.orderId = request.data['saleOrderId']
    #         wage_payment.cardHolderPan = request.data['cardHolderPan']
    #         wage_payment.tracking_code = request.data['saleReferenceId']
    #         wage_payment.state = "completed"
    #         wage_payment.save()
    #         transaction.amount_with_tax = request.data['finalAmount']
    #         transaction.refId = request.data['refId']
    #         transaction.orderId = request.data['saleOrderId']
    #         transaction.cardHolderPan = request.data['cardHolderPan']
    #         transaction.saleReferenceId = request.data['saleReferenceId']
    #         transaction.status = "completed"
    #         transaction.save()
    #
    #         return Response({"result": "با موفقیت انجام شد"}, status=status.HTTP_200_OK)


class ObservatoryViewSet(viewsets.ModelViewSet):
    queryset = Observatory.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ObservatorySerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            observatory = user.observatory_user.all()

            # send to serializer
            serializer = self.serializer_class(observatory[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class POSTransactionsViewSet(viewsets.ModelViewSet):
    queryset = POSTransactions.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSTransactionsSerializer

    def create(self, request, *args, **kwargs):
        pos = POSMachine.objects.get(pos_id=request.data['posid'], trash=False)
        pos.Lat = request.data['lot']
        pos.Long = request.data['lng']
        pos.save()
        guild = Guilds.objects.get(key=pos.guild.key, trash=False)
        guilds_ware_house = GuildsWareHouse.objects.filter(guilds=guild).first()
        if 'paid' in request.data.keys():
            if request.data['paid'] == False:

                serializer = self.serializer_class(data=request.data)
                if serializer.is_valid():
                    transaction = serializer.create(validated_data=request.data)
                    transaction.guild = guild
                    transaction.user = guild.user
                    transaction.registered = True
                    transaction.save()
                    serializer = self.serializer_class(transaction)
                    return Response(serializer.data, status=status.HTTP_200_OK)
                return Response(self.serializer_class.errors, status=status.HTTP_400_BAD_REQUEST)
            else:
                if request.data['checkout'] == False:
                    serializer = self.serializer_class(data=request.data)
                    if serializer.is_valid():
                        transaction = serializer.create(validated_data=request.data)
                        transaction.guild = guild
                        transaction.user = guild.user
                        transaction.registered = True
                        transaction.save()
                else:
                    transaction = POSTransactions.objects.get(resnum=request.data['resnum'])
                    serializer = self.serializer_class(transaction)
                    serializer.update(instance=transaction, validated_data=request.data)
                products = request.data['product']
                for product in products:
                    if product['name'] == 'مرغ گرم':
                        guild_product = Product.objects.get(name=product['name'], guild=guild, trash=False)
                        guild_product.sale_weight += product['cur_qty'] / 1000
                        guild_product.remain_weight -= product['cur_qty'] / 1000
                        guild_product.save()
                        guilds_ware_house.allocated_total_weight_of_carcasses += product['cur_qty'] / 1000
                        guilds_ware_house.remain_total_weight_of_carcasses -= product['cur_qty'] / 1000
                        guilds_ware_house.save()
                serializer = self.serializer_class(transaction)
                return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        # pos = POSMachine.objects.get(pos_id=request.GET['posid'], trash=False)
        guild = Guilds.objects.get(key=request.GET['guild_key'], trash=False)
        transactions = POSTransactions.objects.filter(guild=guild).order_by('-create_date')
        serializer = self.serializer_class(transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosVersionViewSet(viewsets.ModelViewSet):
    queryset = PosVersion.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosVersiontSerializer

    def create(self, request, *args, **kwargs):
        pos_version = PosVersion.objects.filter(trash=False).first()
        if not pos_version:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_version = serializer.create(validated_data=request.data)
                return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            serializer = self.serializer_class(pos_version)
            serializer.update(instance=pos_version, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        pos_version = PosVersion.objects.filter(trash=False).first()
        serializer = self.serializer_class(pos_version)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosItemViewSet(viewsets.ModelViewSet):
    queryset = PosItem.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosItemSerializer

    def create(self, request, *args, **kwargs):
        try:
            pos_item = PosItem.objects.get(name=request.data['name'], trash=False)
            serializer = self.serializer_class(pos_item)
            serializer.update(instance=pos_item, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)
        except:

            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_version = serializer.create(validated_data=request.data)
                return Response(serializer.data, status=status.HTTP_201_CREATED)


class GuildRoomViewSet(viewsets.ModelViewSet):
    queryset = GuildRoom.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildRoomSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            guild_room = user.guild_room_user.all()

            # send to serializer
            serializer = self.serializer_class(guild_room[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class POSMachineForServerViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSMachineForServerSerializer

    def list(self, request, *args, **kwargs):
        guild = Guilds.objects.get(key=request.GET['guild_key'], trash=False)
        pos_machine = POSMachine.objects.filter(guild=guild, trash=False)
        serializer = self.serializer_class(pos_machine, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class POSMachineForInspectionViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSMachineForInspectionSerializer

    def list(self, request, *args, **kwargs):
        pos_machine = POSMachine.objects.filter(trash=False)
        serializer = self.serializer_class(pos_machine, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


def register_information_in_server(pos_machine, guild_key, server):
    u = "https://pos.rasadyar.com/api/async/pos?id={}&shop={}&server={}".format(
        pos_machine, guild_key, server)

    url = u.format()

    payload = {}
    headers = {"Content-Type": "application/x-www-form-urlencoded"}

    response = requests.request("GET", url, headers=headers, data=payload)
    if response.json()['code'] == 200:
        pos = POSMachine.objects.get(pos_id=pos_machine, trash=False)
        pos.server_register = True
        pos.save()


class POSMachineViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSMachineSerializer

    def create(self, request, *args, **kwargs):
        import string
        import random
        server = None
        guild = None
        kill_house = None
        if 'serial' in request.data.keys() and request.data['serial'] is not None:
            exist_pos = POSMachine.objects.filter(serial=request.data['serial'], trash=False).first()
            if exist_pos:
                exist_pos.serial = ""
                exist_pos.password = None
                exist_pos.save()
                # return Response({"result": "شماره سریال دستگاه وارد شده قبلا استفاده شده است! "},
                #                 status=status.HTTP_403_FORBIDDEN)
            if 'password' in request.data.keys() and request.data['password'] is None:
                return Response({"result": "کلمه عبور مدیریتی را وارد کنید! "},
                                status=status.HTTP_403_FORBIDDEN)

        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if user.province.name == 'مرکزی':
            server = 'markazi'
        elif user.province.name == 'همدان':
            server = 'hamedan'
        else:
            server = 'test'
        company = PosCompany.objects.get(user=user, trash=False)
        if 'guild_key' in request.data.keys():
            guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')
        else:
            kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
            request.data.pop('kill_house_key')

        while (True):
            res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
            res = base_pos_id + res
            if not POSMachine.objects.filter(pos_id=res).exists():
                break

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            pos_machine = serializer.create(validated_data=request.data)
            pos_machine.pos_id = res
            if kill_house is not None:
                pos_machine.user = kill_house.kill_house_operator.user
                pos_machine.kill_house = kill_house
            else:
                pos_machine.user = guild.user
                pos_machine.guild = guild
                guild.has_pos = True
                guild.save()
            pos_machine.pos_company = company
            pos_machine.save()

            # register_information_in_server_threading = threading.Thread(
            #     target=register_information_in_server,
            #     args=(
            #         pos_machine.pos_id, guild.key, server))
            # register_information_in_server_threading.start()
            return Response({"result": "باموفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        if 'pos_id' in request.data.keys():
            pos = POSMachine.objects.get(
                pos_id=request.data['pos_id'])
            timestamp_date = request.data['timestamp_date']
            pos_date = datetime.fromtimestamp(timestamp_date)
            request.data.pop('timestamp_date')
            pos.last_check = pos_date
            pos.save()
        else:
            pos = POSMachine.objects.get(
                key=request.data['pos_key'])
            request.data.pop('pos_key')
        serializer = self.serializer_class(pos)
        serializer.update(instance=pos, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class FinalPOSMachineViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [AllowAny]
    serializer_class = NewPOSMachineSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = POSMachineFilterSet
    filterset_fields = [
        'pos_id',
        'serial',
        'password',
        'pos_company__name',
        'user__first_name',
        'user__last_name',
        'user__fullname',
        'user__mobile',
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
    ]

    def create(self, request, *args, **kwargs):
        import string
        import random
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        company = PosCompany.objects.get(user=user, trash=False)
        if 'serial' in request.data.keys() and request.data['serial'] is not None:
            exist_pos = POSMachine.objects.filter(serial=request.data['serial'], trash=False).first()
            if exist_pos:
                exist_pos.serial = ""
                exist_pos.password = None
                exist_pos.save()
                # return Response({"result": "شماره سریال دستگاه وارد شده قبلا استفاده شده است! "},
                #                 status=status.HTTP_403_FORBIDDEN)
            if 'password' in request.data.keys() and request.data['password'] is None:
                return Response({"result": "کلمه عبور مدیریتی را وارد کنید! "},
                                status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            pos_machine = serializer.create(validated_data=request.data)
            pos_machine.pos_company = company
            pos_machine.save()
            return Response({"result": "باموفقیت ثبت شد!"}, status=status.HTTP_201_CREATED)

    def update(self, request, *args, **kwargs):
        pos_machine = POSMachine.objects.get(key=request.data['key'], trash=False)
        owner_type = request.data.get('owner_type')
        if owner_type:
            if owner_type == 'kill_house':
                kill_house = KillHouse.objects.get(key=request.data['owner_key'])
                pos_machine.kill_house = kill_house
                pos_machine.guild = None
                pos_machine.steward = None
                pos_machine.user = kill_house.kill_house_operator.user

            else:
                guild_steward = Guilds.objects.get(key=request.data['owner_key'])
                pos_machine.guild = guild_steward
                pos_machine.user = guild_steward.user
                pos_machine.kill_house = None
                pos_machine.steward = None

            if not pos_machine.pos_id:
                while (True):
                    res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
                    res = base_pos_id + res
                    if not POSMachine.objects.filter(pos_id=res).exists():
                        break
                pos_machine.pos_id = res
            pos_machine.save()
            request.data.pop('owner_type')
            request.data.pop('owner_key')
        serializer = self.serializer_class(pos_machine)
        serializer.update(instance=pos_machine, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if role == 'PosCompany':
            company = PosCompany.objects.get(user=user, trash=False)
            pos_machines = POSMachine.objects.filter(pos_company=company, trash=False).order_by('-create_date')

        else:
            pos_machines = POSMachine.objects.filter(trash=False, cooperative__isnull=True).order_by('-create_date')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(pos_machines)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(pos_machines, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


# class UserPOSMachineViewSet(viewsets.ModelViewSet):
#     queryset = POSMachine.objects.all()
#
#     def get_serializer_class(self):
#         if self.action in ['list', 'retrieve']:
#             return POSMachineReadSerializer
#         return POSMachineTransferSerializer
#
#     @action(detail=True, methods=['post'])
#     def transfer(self, request, pk=None):
#         pos = self.get_object()
#         serializer = self.get_serializer(
#             data=request.data,
#             context={'pos': pos, 'request': request}
#         )
#         serializer.is_valid(raise_exception=True)
#         serializer.save()
#         return Response({"detail": "انتقال با موفقیت انجام شد"})

class UserPOSMachineViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = UserPOSMachineSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = POSMachineFilterSet
    filterset_fields = [
        'pos_id',
        'serial',
        'receiver_number',
        'terminal_number',
        'pos_unique_id',
        'password',
        'pos_company__name',
        'user__first_name',
        'user__last_name',
        'user__fullname',
        'user__mobile',
        'owner__first_name',
        'owner__last_name',
        'owner__fullname',
        'owner__mobile',
        'current_user__first_name',
        'current_user__last_name',
        'current_user__fullname',
        'current_user__mobile',
        'current_representative__first_name',
        'current_representative__last_name',
        'current_representative__mobile',
        'current_representative__city',
    ]

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        pos_filter = {
            'trash': False
        }
        if role in ('KillHouse', 'Steward', 'Guilds'):
            user = SystemUserProfile.objects.get(trash=False, user=request.user)
            pos_filter['owner'] = user

        pos = POSMachine.objects.filter(**pos_filter).order_by('id')
        if 'search' in request.GET:
            pos_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=pos
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=pos)
                            pos_list = ps.filter()
                    pos = [] if len(pos_list) == 0 else pos_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(pos)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(pos, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        performed_by = SystemUserProfile.objects.get(user=request.user, trash=False)
        pos_machine = POSMachine.objects.get(key=request.data['key'], trash=False)
        recipient_type = request.data.pop('recipient_type', None)
        recipient = request.data.pop('recipient_key', None)
        if recipient_type in ('owner', 'current_user'):
            recipient = SystemUserProfile.objects.get(key=recipient, trash=False)
        else:
            recipient = Representative.objects.get(key=recipient, trash=False)
        serializer = self.serializer_class(POSTransferService.transfer(
            pos_machine,
            recipient_type,
            recipient,
            performed_by
        ))
        return Response(serializer.data, status=status.HTTP_200_OK)


class POSMachineForLiveStackViewSet(viewsets.ModelViewSet):
    queryset = POSMachine.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = POSMachineForLiveStockSerializer

    def list(self, request, *args, **kwargs):
        if 'cooperative_key' in request.GET:
            cooperative = Cooperative.objects.get(key=request.GET['cooperative_key'], trash=False)
            pos = POSMachine.objects.filter(trash=False, cooperative=cooperative).order_by('id')

        else:
            pos = POSMachine.objects.filter(trash=False).order_by('id')

        serializer = self.serializer_class(pos, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class POSDeviceSessionViewSet(viewsets.ModelViewSet):
    queryset = POSDeviceSession.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSDeviceSessionSerializer

    def create(self, request, *args, **kwargs):
        password = None

        validator = PosDeviceValidator(request)

        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        device_mac = request.headers.get('device-mac')
        device_name = request.headers.get('device-name')
        device_sdk = request.headers.get('device-sdk')
        device_serial = request.headers.get('device-serial')
        device_provider = request.headers.get('device-provider')
        device_version = request.headers.get('device-version')
        device_lng = request.headers.get('device-lng')
        device_lot = request.headers.get('device-lot')

        client_ip = get_client_ip(request)
        pos = None
        if not device_mac or not device_provider or not device_version:
            return Response({"result": "مقادیر ارسالی صحیح نمیباشد!"}, status=status.HTTP_403_FORBIDDEN)

        if 'pos' in request.data and 'password' in request.data:
            password = request.data['password']
            pos = POSMachine.objects.filter(pos_id=request.data['pos'], trash=False).first()
            request.data.pop('password')
            request.data.pop('pos')
        if not pos and device_serial and device_serial != 'unknown':
            pos = POSMachine.objects.filter(serial=device_serial, trash=False).first()
            password = pos.password if pos else None

        if not pos:
            return Response({"result": "کد پذیرنده نامعتبر میباشد!"}, status=status.HTTP_403_FORBIDDEN)

        if not pos.active:
            return Response({"result": "این پذیرنده توسط مدیریت مسدود شده است!"}, status=status.HTTP_403_FORBIDDEN)
        if pos.pos_company.en_name != device_provider and not pos.multi_device:
            return Response({"result": f"کد پذیرنده برای  {pos.pos_company.name} تعریف شده است"},
                            status=status.HTTP_403_FORBIDDEN)
        body_data = {
            "mac": device_mac,
            "name": device_name,
            "sdk": device_sdk,
            "serial": device_serial,
            "version": device_version,
            "lng": device_lng,
            "lot": device_lot,
            "ip": client_ip,
            "password": password,
            "session_create_date": datetime.now(),
            "session_last_seen_date": datetime.now(),
        }

        pos_session = POSDeviceSession.objects.filter(pos=pos, trash=False)

        if pos_session:
            curent_session = pos_session.filter(mac=device_mac).first()
            if curent_session:
                serializer = self.serializer_class(curent_session)
                serializer.update(instance=curent_session, validated_data=body_data)
                return Response({"result": "خوش آمدید", "pos_id": pos.pos_id, "pos_password": password,
                                 'fullname': pos.user.fullname, 'mobile': pos.user.mobile},
                                status=status.HTTP_200_OK)
            elif not pos.multi_device:
                return Response({"result": "کد پذیرنده توسط دستگاه دیگری درحال استفاده میباشد!"},
                                status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=body_data)
        if serializer.is_valid():
            pos_session = serializer.create(validated_data=body_data)
            pos_session.pos = pos
            pos_session.password = password
            pos_session.save()
            return Response(
                {"result": "خوش آمدید", "pos_id": pos.pos_id, "pos_password": password, 'fullname': pos.user.fullname,
                 'mobile': pos.user.mobile},
                status=status.HTTP_200_OK)
        return Response(serializer.errors)

    def update(self, request, *args, **kwargs):
        if 'pos_id' in request.data.keys():
            pos = POSMachine.objects.get(
                pos_id=request.data['pos_id'])
            timestamp_date = request.data['timestamp_date']
            pos_date = datetime.fromtimestamp(timestamp_date)
            request.data.pop('timestamp_date')
            pos.last_check = pos_date
            pos.save()
        else:
            pos = POSMachine.objects.get(
                key=request.data['pos_key'])
            request.data.pop('pos_key')
        serializer = self.serializer_class(pos)
        serializer.update(instance=pos, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class POSDeviceSessionForInspectionViewSet(viewsets.ModelViewSet):
    queryset = POSDeviceSession.objects.all()
    permission_classes = [AllowAny]
    serializer_class = POSDeviceSessionForInspectionSerializer

    def list(self, request, *args, **kwargs):
        pos_devices = POSDeviceSession.objects.filter(
            trash=False,
            lng__gt=0,
            lot__gt=0,
            pos__guild__isnull=False
        ).select_related(
            'pos',
            'pos__guild',
            'pos__user'
        ).values(
            'lng', 'lot', 'pos__guild__guilds_name', 'key',
            'pos__user__national_code', 'pos__user__national_id'
        ).order_by('id')

        result = [
            {
                'key': item['key'],
                'lat': item['lot'],
                'lng': item['lng'],
                'guilds_name': item['pos__guild__guilds_name'],
                'national_code': item['pos__user__national_code'],
                'national_id': item['pos__user__national_id']
            }
            for item in pos_devices
        ]

        return Response(result, status=status.HTTP_200_OK)
    
    def destroy(self, request, pk=None, *args, **kwargs):
        pos_session = POSDeviceSession.objects.get(key=request.GET['session_key'], trash=False)
        pos_session.trash = True
        pos_session.save()

        return Response({"result": "موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class PosDeviceVersionViewSet(viewsets.ModelViewSet):
    queryset = PosDeviceVersion.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosDeviceVersionSerializer

    def create(self, request, *args, **kwargs):
        if 'provider' not in request.data.keys() or request.data['provider'] == "":
            return Response({"result": "invalid input"}, status=status.HTTP_403_FORBIDDEN)

        else:
            company = PosCompany.objects.get(en_name=request.data['provider'])
            request.data.pop('provider')
        if 'code' not in request.data.keys() or request.data['code'] == "":
            return Response({"result": "invalid input"}, status=status.HTTP_403_FORBIDDEN)
        pos_version = PosDeviceVersion.objects.filter(company=company, code=request.data['code']).first()
        if pos_version:
            serializer = self.serializer_class(pos_version)
            serializer.update(instance=pos_version, validated_data=request.data)
        else:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_version = serializer.create(validated_data=request.data)
                pos_version.company = company
                pos_version.save()
        return Response({"result": "done!"}, status=status.HTTP_200_OK)


class ColdHouseViewSet(viewsets.ModelViewSet):
    queryset = ColdHouse.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ColdHouseSerializer

    def create(self, request, *args, **kwargs):
        steward = None
        kill_house = None
        if 'steward_key' in request.data.keys():
            steward = Guilds.objects.get(key=request.data['steward_key'], trash=False)
            request.data.pop('steward_key')
        else:
            kill_house = KillHouse.objects.get(key=request.data['kill_house_key'], trash=False)
            request.data.pop('kill_house_key')

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            cold_house = serializer.create(validated_data=request.data)
            if steward:
                cold_house.steward = steward
            else:
                cold_house.kill_house = kill_house
            cold_house.save()
            serializer = self.serializer_class(cold_house)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if 'total' in request.GET:
            cold_houses = ColdHouse.objects.all()
            serializer = self.serializer_class(cold_houses, many=True)
        else:
            if request.GET['role'] == 'KillHouse':
                if 'dashboard' in request.GET:
                    # kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                    cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)
                    serializer = ColdHouseSerializer(cold_house)


                elif 'allocation' in request.GET:
                    kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                    cold_house = ColdHouse.objects.filter(trash=False).order_by('kill_house').exclude(
                        kill_house=kill_house)

                    serializer = ColdHouseSerializer(cold_house, many=True)

                else:
                    kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                    cold_house = ColdHouse.objects.filter(trash=False).order_by('kill_house')

                    # cold_house = ColdHouse.objects.filter(
                    #     Q(kill_house=kill_house) | Q(steward__isnull=False), trash=False).order_by(
                    #     'kill_house')
                    serializer = ColdHouseSerializer(cold_house, many=True)
            else:
                # live_stock_support = LiveStockSupport.objects.get(user=user, trash=False)
                cold_house = ColdHouse.objects.filter(live_stock_support__isnull=False, trash=False).first()
                serializer = ColdHouseSerializer(cold_house)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        cold_house = ColdHouse.objects.get(key=request.data['cold_house_key'], trash=False)
        request.data.pop('cold_house_key')
        serializer = self.serializer_class(cold_house)
        serializer.update(instance=cold_house, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalColdHouseDashboardForRolesViewSet(viewsets.ModelViewSet):
    queryset = ColdHouse.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ColdHouseSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        if request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            cold_houses = ColdHouse.objects.filter(kill_house=kill_house, trash=False)
        else:
            steward = Guilds.objects.get(user=user, trash=False)
            cold_houses = ColdHouse.objects.filter(steward=steward, 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

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

        return Response(result, status=status.HTTP_200_OK)


class ColdHouseForProvinceViewSet(viewsets.ModelViewSet):
    queryset = ColdHouse.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ColdHouseSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = ColdHouseFilterSet
    filterset_fields = [
        'name',
        'province',
        'city',
        'steward__user__first_name',
        'steward__user__last_name',
        'steward__user__fullname',
        'steward__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
    ]

    def list(self, request, *args, **kwargs):
        type = request.GET.get('type')
        if type == 'KillHouse':
            kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)
            cold_houses = ColdHouse.objects.filter(kill_house=kill_house, trash=False).order_by('id')
        else:
            steward = Guilds.objects.get(key=request.GET['steward_key'], trash=False)
            cold_houses = ColdHouse.objects.filter(steward=steward, trash=False).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(cold_houses)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(cold_houses, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ColdHouseTotalDashboardViewSet(viewsets.ModelViewSet):
    queryset = ColdHouse.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ColdHouseSerializer

    def list(self, request, *args, **kwargs):
        cold_houses = ColdHouse.objects.filter(trash=False)
        kill_house_cold_houses = cold_houses.filter(kill_house__isnull=False)
        steward_cold_houses = cold_houses.filter(steward__isnull=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

        result = {
            "total_cold_houses": len(cold_houses),
            "total_kill_house_cold_house": len(kill_house_cold_houses),
            "total_steward_cold_house": len(steward_cold_houses),
            "total_input_weight": total_input_weight,
            "total_allocated_weight": total_allocated_weight,
            "total_remain_weight": total_remain_weight,
        }

        return Response(result, status=status.HTTP_200_OK)


class ColdHouseDashboardViewSet(viewsets.ModelViewSet):
    queryset = ColdHouse.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ColdHouseSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        cold_house = ColdHouse.objects.get(key=request.GET['cold_house_key'], trash=False)

        # if request.GET['role'] == 'KillHouse':
        #     # kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
        #     # cold_house = ColdHouse.objects.get(kill_house=kill_house, trash=False)
        #
        # else:
        #     cold_house = ColdHouse.objects.filter(live_stock_support__isnull=False, trash=False).first()

        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            allocations = StewardAllocation.objects.filter(Q(to_cold_house=cold_house) | Q(other_cold_house=cold_house),
                                                           trash=False, to_cold_house=cold_house, date__date__gte=date1,
                                                           date__date__lte=date2,
                                                           receiver_state__in=('pending', 'accepted'))


        else:

            allocations = StewardAllocation.objects.filter(trash=False, to_cold_house=cold_house,
                                                           receiver_state__in=('pending', 'accepted'))

        input_bars = allocations.filter(
            Q(kill_house__isnull=False, to_cold_house=cold_house) | Q(
                kill_house__isnull=True, other_cold_house=cold_house),
            receiver_state='accepted')
        output_bars = allocations.filter(
            Q(to_steward__isnull=False) | Q(to_guilds__isnull=False) | Q(other_cold_house__isnull=False),
            kill_house__isnull=True, to_cold_house=cold_house)

        total_input_bars_weight = input_bars.aggregate(
            total=Sum('real_weight_of_carcasses'))['total'] or 0
        total_output_bars_weight = output_bars.aggregate(
            total=Sum('real_weight_of_carcasses'))['total'] or 0

        result = {
            "total_input_bars": len(input_bars),
            "total_input_bars_weight": total_input_bars_weight,
            "total_output_bars": len(output_bars),
            "total_output_bars_weight": total_output_bars_weight,
        }

        return Response(result, status=status.HTTP_200_OK)


class CheckColdHouseAllocationsViewSet(viewsets.ModelViewSet):
    queryset = ColdHouseAllocations.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ColdHouseAllocationsSerializer

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        allocation = ColdHouseAllocations.objects.get(key=request.data['allocation_key'], trash=False)
        cold_house = ColdHouse.objects.get(key=allocation.cold_house.key, trash=False)
        role = request.data['role']
        request.data.pop('allocation_key')
        request.data.pop('role')
        ware_house = KillHouseWareHouse.objects.get(key=allocation.kill_house_ware_house.key, trash=False)
        kill_house_request = KillHouseRequest.objects.get(key=allocation.kill_house_request.key, trash=False)

        if request.data['state'] == 'accepted':

            if request.data['accepted_weight'] > kill_house_request.ware_house_accepted_real_weight or request.data[
                'accepted_quantity'] > kill_house_request.ware_house_accepted_real_quantity:
                return Response({"result": "حجم بار کمتر از مقدار وارد شده است!"},
                                status=status.HTTP_403_FORBIDDEN)

            if request.data['accepted_quantity'] > allocation.quantity:
                diffrent_quantity = request.data['accepted_quantity'] - allocation.quantity
                diffrent_weight = request.data['accepted_weight'] - allocation.weight
                if diffrent_quantity > ware_house.remain_total_number_of_carcasses and diffrent_weight > ware_house.remain_total_weight_of_carcasses:
                    return Response({"result": "موجودی انبار کمتر از مقدار وارد شده است!"},
                                    status=status.HTTP_403_FORBIDDEN)
                else:
                    allocation.accepted_quantity = request.data['accepted_quantity']
                    allocation.accepted_weight = request.data['accepted_weight']
                    allocation.save()
                    ware_house.allocated_total_number_of_carcasses += diffrent_quantity
                    ware_house.freezing_quantity += diffrent_quantity
                    ware_house.allocated_total_weight_of_carcasses += diffrent_weight
                    ware_house.freezing_weight += diffrent_weight
                    ware_house.save()
            else:
                diffrent_quantity = allocation.quantity - request.data['accepted_quantity']
                diffrent_weight = allocation.weight - request.data['accepted_weight']
                allocation.accepted_quantity = request.data['accepted_quantity']
                allocation.accepted_weight = request.data['accepted_weight']
                allocation.save()
                ware_house.allocated_total_number_of_carcasses -= diffrent_quantity
                ware_house.freezing_quantity -= diffrent_quantity
                ware_house.allocated_total_weight_of_carcasses -= diffrent_weight
                ware_house.freezing_weight -= diffrent_weight
                ware_house.save()
            cold_house.total_quantity += allocation.accepted_quantity
            cold_house.total_weight += allocation.accepted_weight
            cold_house.save()

        allocation.reviewer = {
            "role": role,
            "fullname": user.fullname,
            "mobile": user.mobile,
            "date": str(datetime.now()),
        }
        allocation.save()
        serializer = self.serializer_class(allocation)
        serializer.update(instance=allocation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)
        # return Response({"result": "با موفقیت انجام شد!"}, status=status.HTTP_200_OK)


class ColdHouseAllocationsViewSet(viewsets.ModelViewSet):
    queryset = ColdHouseAllocations.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ColdHouseAllocationsSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = ColdHouseAllocationsFilterSet
    filterset_fields = [
        'name',
        'cold_house__live_stock_support__user__first_name',
        'cold_house__live_stock_support__user__last_name',
        'cold_house__live_stock_support__user__fullname',
        'cold_house__live_stock_support__user__mobile',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'kill_house__name',
    ]

    def create(self, request, *args, **kwargs):
        now = datetime.now().date()
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        kill_house = KillHouse.objects.get(key=product.kill_house.key, trash=False)
        cold_house = ColdHouse.objects.get(key=request.data['cold_house_key'], trash=False)
        # kill_house_ware_house = KillHouseWareHouse.objects.get(key=request.data['ware_house_key'], trash=False)
        date = datetime.now().date()
        # date = datetime.strptime(str(request.data['date']), '%Y-%m-%d').date()
        # request.data.pop('date')
        request.data.pop('product_key')
        request.data.pop('cold_house_key')
        # request.data.pop('ware_house_key')
        if OperationLimitation.objects.all().first().kill_house_freezing_limitation == True:

            if now != date:
                return Response({"result": "به علت مغایرت تاریخ امکان انجماد وجود ندارد!"},
                                status=status.HTTP_403_FORBIDDEN)

        # if request.data['weight'] > kill_house_request.ware_house_accepted_real_weight or request.data[
        #     'quantity'] > kill_house_request.ware_house_accepted_real_quantity:
        #     return Response({"result": "موجودی بار کمتر از مقدار وارد شده است!"},
        #                     status=status.HTTP_403_FORBIDDEN)
        # if request.data['weight'] > kill_house_ware_house.remain_total_weight_of_carcasses or request.data[
        #     'quantity'] > kill_house_ware_house.remain_total_number_of_carcasses:
        #     return Response({"result": "موجودی انبار کمتر از مقدار وارد شده است!"},
        #                     status=status.HTTP_403_FORBIDDEN)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            allocation = serializer.create(validated_data=request.data)
            allocation.cold_house = cold_house
            allocation.product = product
            allocation.kill_house = kill_house
            allocation.date = datetime(year=date.year, month=date.month, day=date.day, hour=10, minute=1, second=1)
            allocation.allocation_type = 'governmental'
            allocation.real_weight = allocation.weight
            allocation.real_quantity = allocation.quantity
            allocation.save()
            kill_house_cold_house_allocations_product_warehousing(product)
            # allocation.kill_house_request = kill_house_request
            # allocation.kill_house_ware_house = kill_house_ware_house
            # kill_house_ware_house.allocated_total_weight_of_carcasses += request.data['weight']
            # kill_house_ware_house.allocated_total_number_of_carcasses += request.data['quantity']
            # kill_house_ware_house.save()
            # kill_house_request.freezing = True
            # kill_house_request.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        if request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            allocations = ColdHouseAllocations.objects.filter(kill_house=kill_house,
                                                              date__date__gte=date1, date__date__lte=date2,
                                                              trash=False).order_by('id')
        else:
            allocations = ColdHouseAllocations.objects.filter(date__date__gte=date1, date__date__lte=date2,
                                                              trash=False).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(allocations)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(allocations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        allocation = ColdHouseAllocations.objects.get(key=request.data['allocation_key'],
                                                      trash=False)
        product = allocation.product
        # kill_house_request = KillHouseRequest.objects.get(key=allocation.kill_house_request.key, trash=False)

        if allocation.state != 'pending':
            return Response({"result": " به علت تایید تخصیص امکان ویرایش وجود ندارد!"},
                            status=status.HTTP_403_FORBIDDEN)
        # ware_house = KillHouseWareHouse.objects.get(key=allocation.kill_house_ware_house.key, trash=False)
        if request.data['quantity'] > allocation.quantity or request.data['weight'] > allocation.weight:
            # diffrent_quantity = request.data['quantity'] - allocation.quantity
            # diffrent_weight = request.data['weight'] - allocation.weight
            # if request.data['weight'] > kill_house_request.ware_house_accepted_real_weight or request.data[
            #     'quantity'] > kill_house_request.ware_house_accepted_real_quantity:
            #     return Response({"result": "موجودی بار کمتر از مقدار وارد شده است!"},
            #                     status=status.HTTP_403_FORBIDDEN)
            # if diffrent_quantity > ware_house.remain_total_number_of_carcasses or diffrent_weight > ware_house.remain_total_weight_of_carcasses:
            #     return Response({"result": "موجودی انبار کمتر از مقدار وارد شده است!"},
            #                     status=status.HTTP_403_FORBIDDEN)
            # else:
            allocation.quantity = request.data['quantity']
            allocation.weight = request.data['weight']
            allocation.save()
            # ware_house.allocated_total_number_of_carcasses += diffrent_quantity
            # ware_house.freezing_quantity += diffrent_quantity
            # ware_house.allocated_total_weight_of_carcasses += diffrent_weight
            # ware_house.freezing_weight += diffrent_weight
            # ware_house.save()
        else:
            diffrent_quantity = allocation.quantity - request.data['quantity']
            diffrent_weight = allocation.weight - request.data['weight']
            allocation.quantity = request.data['quantity']
            allocation.weight = request.data['weight']
            allocation.save()
            # ware_house.allocated_total_number_of_carcasses -= diffrent_quantity
            # ware_house.freezing_quantity -= diffrent_quantity
            # ware_house.allocated_total_weight_of_carcasses -= diffrent_weight
            # ware_house.freezing_weight -= diffrent_weight
            # ware_house.save()

        allocation.real_quantity = request.data['quantity']
        allocation.real_weight = request.data['weight']
        allocation.save()
        kill_house_cold_house_allocations_product_warehousing(product)

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

    def destroy(self, request, pk=None, *args, **kwargs):
        allocation = ColdHouseAllocations.objects.get(key=request.GET["allocation_key"])
        product = allocation.product
        if allocation.state != 'pending':
            return Response({"result": " به علت تایید تخصیص امکان حذف وجود ندارد!"}, status=status.HTTP_403_FORBIDDEN)
        # ware_house = KillHouseWareHouse.objects.get(key=allocation.kill_house_ware_house.key)
        # ware_house.allocated_total_number_of_carcasses -= allocation.quantity
        # ware_house.allocated_total_weight_of_carcasses -= allocation.weight
        # ware_house.freezing_quantity -= allocation.quantity
        # ware_house.freezing_weight -= allocation.weight
        # ware_house.save()
        allocation.trash = True
        allocation.save()
        kill_house_cold_house_allocations_product_warehousing(product)

        return Response({"result": "با موفقیت حذف شد"}, status=status.HTTP_200_OK)


class OperationLimitationViewset(viewsets.ModelViewSet):
    queryset = OperationLimitation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = OperationLimitationSerializer

    def list(self, request, *args, **kwargs):
        operation_limitation = OperationLimitation.objects.filter(trash=False).first()

        serializer = self.serializer_class(operation_limitation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        operation_limitation = OperationLimitation.objects.filter(trash=False).first()
        serializer = self.serializer_class(operation_limitation)
        serializer.update(instance=operation_limitation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ApprovedPriceViewset(viewsets.ModelViewSet):
    queryset = ApprovedPrice.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ApprovedPriceSerializer

    def list(self, request, *args, **kwargs):
        approved_price = ApprovedPrice.objects.filter(trash=False).first()

        serializer = self.serializer_class(approved_price)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        approved_price = ApprovedPrice.objects.filter(trash=False).first()
        serializer = self.serializer_class(approved_price)
        serializer.update(instance=approved_price, validated_data=request.data)
        if request.data['approved'] == False:
            price = BroadcastPrice.objects.filter(trash=False).first()
            price.allow = False
            price.save()
            free_sale_province = FreeSaleWithinprovince.objects.filter(trash=False).first()
            free_sale_province.allow = False
            free_sale_province.save()
            FreeCommitmentThread_Threading = threading.Thread(
                target=FreeCommitmentThread,
                args=(user.province.name,))

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


class AnnouncementsViewset(viewsets.ModelViewSet):
    queryset = Announcements.objects.all()
    permission_classes = [AllowAny]
    serializer_class = AnnouncementsSerializer

    def list(self, request, *args, **kwargs):
        if 'total' in request.GET:
            announcement = Announcements.objects.filter(trash=False).order_by('id')
            serializer = self.serializer_class(announcement, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            announcement = Announcements.objects.get(role=request.GET['role'], trash=False)

            serializer = self.serializer_class(announcement)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        announcement = Announcements.objects.get(key=request.data['key'], trash=False)
        serializer = self.serializer_class(announcement)
        serializer.update(instance=announcement, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ChickenAgeRangeViewset(viewsets.ModelViewSet):
    queryset = ChickenAgeRange.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ChickenAgeRangeSerializer

    def list(self, request, *args, **kwargs):
        age_range = ChickenAgeRange.objects.filter(trash=False).first()

        serializer = self.serializer_class(age_range)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        age_range = ChickenAgeRange.objects.filter(trash=False).first()
        serializer = self.serializer_class(age_range)
        serializer.update(instance=age_range, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TimeRangeViewset(viewsets.ModelViewSet):
    queryset = TimeRange.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TimeRangeSerializer

    def list(self, request, *args, **kwargs):
        time_range = TimeRange.objects.filter(trash=False).first()

        serializer = self.serializer_class(time_range)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        time_range = TimeRange.objects.filter(trash=False).first()
        serializer = self.serializer_class(time_range)
        serializer.update(instance=time_range, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class SystemWalletViewset(viewsets.ModelViewSet):
    queryset = SystemWallet.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SystemWalletSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.GET['type'] == 'self':
            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                try:
                    wallet = SystemWallet.objects.get(kill_house=kill_house, trash=False)
                except:
                    wallet = SystemWallet(kill_house=kill_house)
                    wallet.save()

            serializer = self.serializer_class(wallet)
            return Response(serializer.data, status=status.HTTP_200_OK)


class PaymentGatewayPercentageViewset(viewsets.ModelViewSet):
    queryset = PaymentGatewayPercentage.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PaymentGatewayPercentageSerializer

    def list(self, request, *args, **kwargs):
        percentage = PaymentGatewayPercentage.objects.filter(trash=False).first()

        serializer = self.serializer_class(percentage)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        percentage = PaymentGatewayPercentage.objects.filter(trash=False).first()
        serializer = self.serializer_class(percentage)
        serializer.update(instance=percentage, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalPaymentGatewayPercentageViewset(viewsets.ModelViewSet):
    queryset = TotalPaymentGatewayPercentage.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TotalPaymentGatewayPercentageSerializer

    def list(self, request, *args, **kwargs):
        percentage = TotalPaymentGatewayPercentage.objects.filter(trash=False).first()

        serializer = self.serializer_class(percentage)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        percentage = TotalPaymentGatewayPercentage.objects.filter(trash=False).first()
        serializer = self.serializer_class(percentage)
        serializer.update(instance=percentage, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ShareTypeViewset(viewsets.ModelViewSet):
    queryset = ShareType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ShareTypeSerializer

    def create(self, request, *args, **kwargs):
        if ShareType.objects.filter(name=request.data['name'], trash=False).exists():
            return Response({"result": "سهامدار وارد شده وجود دارد!"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            share_type = serializer.create(validated_data=request.data)
            wage_types = WageType.objects.filter(trash=False)
            for wage_type in wage_types:
                percentage = PercentageOfWageType(
                    wage_type=wage_type,
                    share_type=share_type,
                )
                percentage.save()

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)


class WageTypeViewset(viewsets.ModelViewSet):
    queryset = WageType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WageTypeSerializer

    def list(self, request, *args, **kwargs):
        wage_types = WageType.objects.filter(trash=False).order_by('id')

        serializer = self.serializer_class(wage_types, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        wage_type = WageType.objects.get(key=request.data['key'], trash=False)
        percentages = request.data['percentages']
        request.data.pop('percentages')
        for percentage in percentages:
            wage_percentage = PercentageOfWageType.objects.get(share_type__name=percentage['name'], wage_type=wage_type,
                                                               trash=False)
            wage_percentage.percent = percentage['percent']
            wage_percentage.save()
        serializer = self.serializer_class(wage_type)
        serializer.update(instance=wage_type, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PoultryOutProvinceWageTypeViewset(viewsets.ModelViewSet):
    queryset = WageType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WageTypeForPoultryOutProvinceRequestSerializer

    def list(self, request, *args, **kwargs):
        wage_type = WageType.objects.get(en_name='poultry-sell-out-province', trash=False)
        serializer = self.serializer_class(wage_type)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PercentageOfWageTypeViewset(viewsets.ModelViewSet):
    queryset = PercentageOfWageType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PercentageOfWageTypeSerializer


class SubSectorPercentageOfWageTypeViewset(viewsets.ModelViewSet):
    queryset = SubSectorPercentageOfWageType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SubSectorPercentageOfWageTypeSerializer

    def list(self, request, *args, **kwargs):
        if request.GET['type'] == 'city':

            sub_sector_wage_type = SubSectorPercentageOfWageType.objects.filter(city=True, trash=False).order_by('id')
        else:
            sub_sector_wage_type = SubSectorPercentageOfWageType.objects.filter(trash=False).order_by('id')

        serializer = self.serializer_class(sub_sector_wage_type, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        sub_sector_wage_type = SubSectorPercentageOfWageType.objects.get(key=request.data['sub_sector_wage_type_key'],
                                                                         trash=False)
        request.data.pop('sub_sector_wage_type_key')
        serializer = self.serializer_class(sub_sector_wage_type)
        serializer.update(instance=sub_sector_wage_type, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalWageInformationViewset(viewsets.ModelViewSet):
    queryset = TotalWageInformation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TotalWageInformationSerializer

    def list(self, request, *args, **kwargs):
        try:
            total_wage = TotalWageInformation.objects.get(trash=False)
        except:
            total_wage = TotalWageInformation()
            total_wage.save()

        serializer = self.serializer_class(total_wage, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class ParentCompanyTotalWageInformationViewset(viewsets.ModelViewSet):
    queryset = TotalWageInformation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ParentCompanyTotalWageInformationSerializer

    def list(self, request, *args, **kwargs):
        try:
            total_wage = TotalWageInformation.objects.get(trash=False)
        except:
            total_wage = TotalWageInformation()
            total_wage.save()

        serializer = self.serializer_class(total_wage, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class InternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = InternalTransactionSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = InternalTransactionFilterSet
    filterset_fields = [
        'saleReferenceId',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_fullname',
        'payer_mobile',
        'user__fullname',
        'user__first_name',
        'user__last_name',
        'user__mobile',
        'kill_house__name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__mobile',
        'parent_kill_house__name',
        'parent_kill_house__kill_house_operator__user__fullname',
        'parent_kill_house__kill_house_operator__user__first_name',
        'parent_kill_house__kill_house_operator__user__last_name',
        'parent_kill_house__kill_house_operator__user__mobile',

    ]

    def create(self, request, *args, **kwargs):
        kill_house = KillHouse.objects.get(key=request.data['kill_house_key'])
        parent_kill_house = kill_house
        if kill_house.killer == True and kill_house.type == 'exclusive':
            percentage = KillHousePercentage.objects.filter(kill_house=kill_house, trash=False).first()
            parent_kill_house = percentage.kill_house_for_killer if percentage else kill_house
        image = request.data['image']
        request.data.pop('image')
        request.data.pop('kill_house_key')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            transaction = serializer.create(validated_data=request.data)
            transaction.payer_type = 'kill_house'
            transaction.status = 'completed'
            transaction.kill_house = kill_house
            transaction.parent_kill_house = parent_kill_house
            transaction.payer_fullname = kill_house.kill_house_operator.user.fullname
            transaction.payer_mobile = kill_house.kill_house_operator.user.mobile
            transaction.date = datetime.now()
            if image != "":
                transaction.image = send_image_to_server(image)

            transaction.save()
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        transactions_list = []
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                # kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)

                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).order_by('-date')

            elif request.GET['role'] == 'ChainCompany':
                chain_company = ChainCompany.objects.get(user=user, trash=False)
                # chain_company = ChainCompany.objects.get(key=request.GET['chain_company_key'], trash=False)

                transactions = InternalTransaction.objects.filter(
                    chain_company=chain_company,
                    date__date__gte=date1,
                    date__date__lte=date2,
                    status='completed',
                    trash=False).order_by('-date')

            else:
                if 'kill_house_key' in request.GET:
                    kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)

                    if request.GET['role'] == 'ProvinceOperator':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            date__date__gte=date1,
                            date__date__lte=date2,
                            union_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Company':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            date__date__gte=date1,
                            date__date__lte=date2,
                            company_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Guilds':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            date__date__gte=date1,
                            date__date__lte=date2,
                            guilds_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')

                    elif request.GET['role'] == 'SuperAdmin':
                        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).exclude(union_share=0, company_share=0, guilds_share=0).order_by('id')

                    else:
                        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).order_by('-date')

                else:
                    chain_company = ChainCompany.objects.get(key=request.GET['chain_company_key'], trash=False)
                    if request.GET['role'] == 'ProvinceOperator':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            date__date__gte=date1,
                            date__date__lte=date2,
                            union_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Company':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            date__date__gte=date1,
                            date__date__lte=date2,
                            company_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Guilds':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            date__date__gte=date1,
                            date__date__lte=date2,
                            guilds_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')

                    elif request.GET['role'] == 'SuperAdmin':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            date__date__gte=date1,
                            date__date__lte=date2,
                            status='completed',
                            trash=False).exclude(union_share=0, company_share=0, guilds_share=0).order_by('-date')

                    else:
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            date__date__gte=date1,
                            date__date__lte=date2,
                            status='completed',
                            trash=False).order_by('-date')

        else:

            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
                # kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)

                transactions = InternalTransaction.objects.filter(
                    Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                    status='completed',
                    trash=False).order_by('id')

            elif request.GET['role'] == 'ChainCompany':
                chain_company = ChainCompany.objects.get(user=user, trash=False)
                # chain_company = ChainCompany.objects.get(key=request.GET['chain_company_key'], trash=False)

                transactions = InternalTransaction.objects.filter(
                    chain_company=chain_company,
                    status='completed',
                    trash=False).order_by('-date')

            else:
                if 'kill_house_key' in request.GET:
                    kill_house = KillHouse.objects.get(key=request.GET['kill_house_key'], trash=False)

                    if request.GET['role'] == 'ProvinceOperator':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            union_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Company':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            company_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')

                    elif request.GET['role'] == 'Guilds':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            guilds_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')

                    elif request.GET['role'] == 'SuperAdmin':
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            status='completed',
                            trash=False).exclude(union_share=0, company_share=0, guilds_share=0).order_by('id')

                    else:
                        transactions = InternalTransaction.objects.filter(
                            Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                            status='completed',
                            trash=False).order_by('-date')

                else:
                    chain_company = ChainCompany.objects.get(key=request.GET['chain_company_key'], trash=False)
                    if request.GET['role'] == 'ProvinceOperator':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            union_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Company':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            company_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')
                    elif request.GET['role'] == 'Guilds':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            guilds_share__gt=0,
                            status='completed',
                            trash=False).order_by('-date')

                    elif request.GET['role'] == 'SuperAdmin':
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            status='completed',
                            trash=False).exclude(union_share=0, company_share=0, guilds_share=0).order_by('id')
                    else:
                        transactions = InternalTransaction.objects.filter(
                            chain_company=chain_company,
                            status='completed',
                            trash=False).order_by('-date')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        transaction = InternalTransaction.objects.get(key=request.data['transaction_key'], trash=False)
        request.data.pop('transaction_key')
        if 'image' in request.data.keys():
            image = request.data['image']
            request.data.pop('image')

            if image != "":
                transaction.image = send_image_to_server(image)
                transaction.save()
        serializer = self.serializer_class(transaction)
        serializer.update(instance=transaction, validated_data=request.data)
        return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        transaction = InternalTransaction.objects.get(key=request.GET['transaction_key'], trash=False)
        transaction.trash = True
        transaction.save()

        return Response({"result": "موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class PoultryRequestInternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryOutRequestInternalTransactionSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = InternalTransactionFilterSet
    filterset_fields = [
        'saleReferenceId',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_fullname',
        'payer_mobile',
        'user__fullname',
        'user__first_name',
        'user__last_name',
        'user__mobile',
        'poultry__user__fullname',
        'poultry__user__first_name',
        'poultry__user__last_name',
        'poultry__user__mobile',
        'out_province_poultry_request_buyer__user__fullname',
        'out_province_poultry_request_buyer__user__first_name',
        'out_province_poultry_request_buyer__user__last_name',
        'out_province_poultry_request_buyer__user__mobile',

    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        transactions_list = []
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        if request.GET['type'] == 'poultry':
            transactions = InternalTransaction.objects.filter(
                payer_type='poultry',
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                trash=False).order_by('-date')

        else:
            transactions = InternalTransaction.objects.filter(
                payer_type='buyer',
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                trash=False).order_by('-date')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class TotalDashboardPoultryRequestInternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryOutRequestInternalTransactionSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user)
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        transactions = InternalTransaction.objects.filter(Q(payer_type='poultry') | Q(payer_type='buyer'),
                                                          date__date__gte=date1,
                                                          date__date__lte=date2,
                                                          status='completed',
                                                          trash=False).order_by('date')
        poultry_transactions = transactions.filter(payer_type='poultry')
        buyer_transactions = transactions.filter(payer_type='buyer')
        total_transactions_amount = transactions.aggregate(total=Sum('amount'))[
                                        'total'] or 0
        poultries = len(poultry_transactions.values_list('poultry', flat=True).distinct())
        buyers = len(buyer_transactions.values_list('out_province_poultry_request_buyer', flat=True).distinct())
        poultry_transactions_total_amount = poultry_transactions.aggregate(total=Sum('amount'))[
                                                'total'] or 0
        buyer_transactions_total_amount = buyer_transactions.aggregate(total=Sum('amount'))[
                                              'total'] or 0

        transaction_info_dict = {
            "total_number_of_transactions": len(transactions),
            "total_amount_of_transactions": total_transactions_amount,
            "total_number_of_payers": poultries + buyers,
            "total_number_of_poultries": poultries,
            "total_amount_of_poultries": poultry_transactions_total_amount,
            "total_number_of_buyers": buyers,
            "total_amount_of_buyers": buyer_transactions_total_amount,
        }
        return Response(transaction_info_dict, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def get_gate_way_payer_info(request):
    first_char = request.GET['user_gate_way_id'][0]
    if len(request.GET['user_gate_way_id']) > 7:
        user_gate_way_id = request.GET['user_gate_way_id'][1:7]
        order_code = request.GET['user_gate_way_id'][7:]
    else:
        user_gate_way_id = request.GET['user_gate_way_id'][1:]
        order_code = None
    if first_char == 'p':
        role = 'Poultry'
    elif first_char == 'b':
        role = 'Buyer'
    elif first_char == 'k':
        role = 'KillHouse'
    else:
        role = 'ChainCompany'

    try:
        user = SystemUserProfile.objects.get(user_gate_way_id=user_gate_way_id, trash=False)
    except:
        return Response({"result": "توکن کاربر معتبر نمیباشد!"}, status=status.HTTP_403_FORBIDDEN)

    if role == 'Poultry':
        total_unpaid_wage = 0
        # poultry = Poultry.objects.get(user=user, trash=False)
        if order_code is not None:
            poultry_requests = PoultryRequest.objects.filter(order_code=order_code, poultry__user=user,
                                                             payer_type='poultry',
                                                             out_province_request_cancel=False, out=True, has_wage=True,
                                                             province_state='accepted', wage_pay=False, trash=False)
        else:
            poultry_requests = PoultryRequest.objects.filter(poultry__user=user, payer_type='poultry',
                                                             out_province_request_cancel=False, out=True, has_wage=True,
                                                             province_state='accepted', wage_pay=False, trash=False)

        total_quantity = poultry_requests.aggregate(total=Sum('quantity'))[
                             'total'] or 0
        total_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                           'total'] or 0
        total_unpaid_wage += poultry_requests.aggregate(total=Sum('total_wage_amount'))[
                                 'total'] or 0
        return Response(
            {
                "role": role,
                "user_key": user.key,
                "poultry": None,
                "order_code": [order_code],
                "fullname": user.fullname,
                "mobile": user.mobile,
                "city": user.city.name,
                "province": user.province.name,
                "number_of_requests": len(poultry_requests),
                "total_quantity": total_quantity,
                "total_weight": total_weight,
                "total_amount": total_unpaid_wage,
            },
            status=status.HTTP_200_OK

        )

    elif role == 'Buyer':
        total_unpaid_wage = 0
        now = datetime.now().date()
        buyer = OutProvincePoultryRequestBuyer.objects.get(user=user, trash=False)
        poultry_requests = PoultryRequest.objects.filter(out_province_poultry_request_buyer=buyer, payer_type='buyer',
                                                         out_province_request_cancel=False,
                                                         send_date__date=now,
                                                         out=True, has_wage=True,
                                                         province_state='accepted', wage_pay=False, trash=False)
        total_quantity = poultry_requests.aggregate(total=Sum('quantity'))[
                             'total'] or 0
        total_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                           'total'] or 0

        total_unpaid_wage += poultry_requests.aggregate(total=Sum('total_wage_amount'))[
                                 'total'] or 0
        order_codes = poultry_requests.values_list('order_code', flat=True)
        return Response(
            {
                "role": role,
                "user_key": user.key,
                "order_code": order_codes,
                "fullname": user.fullname,
                "mobile": user.mobile,
                "city": user.city.name,
                "province": user.province.name,
                "number_of_requests": len(poultry_requests),
                "total_quantity": total_quantity,
                "total_weight": total_weight,
                "total_amount": total_unpaid_wage
            },
            status=status.HTTP_200_OK

        )
    # elif role == 'KillHouse':
    #     total_unpaid_wage = 0
    #     total_paid_wage = 0
    #     real_free_sale_wage = 0
    #     kill_house_kill_requests_wage = 0
    #     # wage_type = WageType.objects.filter(en_name='province-kill-request').first()
    #     # total_check_wage = wage_type.amount
    #     kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
    #     total_unpaid_wage = get_finance_info(kill_house)['total_price']
    #
    #     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 Response(
    #         {
    #             "role": role,
    #             "user_key": user.key,
    #             "name": kill_house.name,
    #             "fullname": user.fullname,
    #             "mobile": user.mobile,
    #             "city": user.city.name,
    #             "province": user.province.name,
    #             "total_amount": total_unpaid_wage - (total_paid_wage + kill_house.off)
    #         },
    #         status=status.HTTP_200_OK
    #
    #     )
    elif role == 'KillHouse':
        total_unpaid_wage = 0
        total_paid_wage = 0
        real_free_sale_wage = 0
        kill_house_kill_requests_wage = 0
        # wage_type = WageType.objects.filter(en_name='province-kill-request').first()
        # total_check_wage = wage_type.amount
        kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
        total_unpaid_wage = get_finance_info(kill_house)['total_price']
        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 Response(
            {
                "role": role,
                "user_key": user.key,
                "name": kill_house.name,
                "fullname": user.fullname,
                "mobile": user.mobile,
                "city": user.city.name,
                "province": user.province.name,
                "total_amount": total_unpaid_wage - (total_paid_wage + kill_house.off)
            },
            status=status.HTTP_200_OK

        )

    else:
        total_unpaid_wage = 0
        total_paid_wage = 0
        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_unpaid_wage += chain_allocations_total_wage
        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 Response(
            {
                "role": role,
                "user_key": user.key,
                "name": chain_company.name,
                "fullname": user.fullname,
                "mobile": user.mobile,
                "city": user.city.name,
                "province": user.province.name,
                "total_amount": total_unpaid_wage - total_paid_wage
            },
            status=status.HTTP_200_OK

        )

    # if 'order_code' in request.GET:
    #     poultry_request = PoultryRequest.objects.get(order_code=request.GET['order_code'], trash=False)
    #     role = 'Poultry'
    #     fullname = poultry_request.poultry.user.fullname if poultry_request.payer_type == 'poultry' else \
    #         poultry_request.buyer['firstName'] + " " + poultry_request.buyer[
    #             'lastName']
    #     return Response(
    #         {
    #             "role": role,
    #             "order_code": poultry_request.order_code,
    #             "poultry": poultry_request.poultry.unit_name,
    #             "fullname": fullname,
    #             "mobile": poultry_request.poultry.user.mobile,
    #             "city": poultry_request.poultry.user.city.name,
    #             "province": poultry_request.poultry.user.province.name,
    #             "total_amount": poultry_request.total_wage_amount
    #         },
    #         status=status.HTTP_200_OK
    #
    #     )
    # else:
    #
    #     total_unpaid_wage = 0
    #     total_paid_wage = 0
    #     role = None
    #     try:
    #         user = SystemUserProfile.objects.get(user_gate_way_id=request.GET['user_gate_way_id'], trash=False)
    #     except:
    #         return Response({"result": "توکن کاربر معتبر نمیباشد!"}, status=status.HTTP_403_FORBIDDEN)
    #
    #     kill_house_role = Group.objects.get(name='KillHouse')
    #     if kill_house_role in user.role.all():
    #         role = 'KillHouse'
    #         kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
    #         province_kill_requests = ProvinceKillRequest.objects.filter(killhouse_user=kill_house,
    #                                                                     state__in=('pending', 'accepted'), trash=False,
    #                                                                     return_to_province=False,
    #                                                                     first_car_allocated_quantity=0,
    #                                                                     archive_wage=False,
    #                                                                     )
    #         kill_house_requests = KillHouseRequest.objects.filter(
    #             Q(Q(killer=kill_house) & Q(killhouse_user=kill_house)) | Q(
    #                 Q(killer__isnull=True) & Q(killhouse_user=kill_house)) | Q(
    #                 Q(killer__isnull=True) | Q(killer=kill_house)),
    #             # killhouse_user=kill_house,
    #             archive_wage=False,
    #             trash=False
    #         )
    #
    #         kill_house_requests = kill_house_requests.filter(Q(killer=kill_house) | Q(killhouse_user=kill_house))
    #
    #         free_bars = KillHouseFreeBarInformation.objects.filter(kill_house=kill_house, archive_wage=False,
    #                                                                trash=False)
    #
    #         total_unpaid_wage += province_kill_requests.aggregate(total=Sum('total_wage_amount'))[
    #                                  'total'] or 0
    #         total_unpaid_wage += free_bars.aggregate(total=Sum('total_wage_amount'))[
    #                                  'total'] or 0
    #         total_unpaid_wage += \
    #             kill_house_requests.aggregate(total=Sum(F('accepted_real_weight') * F('province_kill_request__wage')))[
    #                 'total'] or 0
    #         slaughter_transactions = InternalTransaction.objects.filter(
    #             kill_house=kill_house, status='completed',
    #             trash=False)
    #
    #         total_paid_wage += slaughter_transactions.aggregate(total=Sum('amount'))[
    #                                'total'] or 0
    #
    #         return Response(
    #             {
    #                 "role": role,
    #                 "user_key": user.key,
    #                 "name": kill_house.name,
    #                 "fullname": user.fullname,
    #                 "mobile": user.mobile,
    #                 "city": user.city.name,
    #                 "province": user.province.name,
    #                 "total_amount": total_unpaid_wage - total_paid_wage
    #             },
    #             status=status.HTTP_200_OK
    #
    #         )
    #     else:
    #         role = 'ChainCompany'
    #         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_unpaid_wage += chain_allocations_total_wage
    #         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 Response(
    #             {
    #                 "role": role,
    #                 "user_key": user.key,
    #                 "name": chain_company.name,
    #                 "fullname": user.fullname,
    #                 "mobile": user.mobile,
    #                 "city": user.city.name,
    #                 "province": user.province.name,
    #                 "total_amount": total_unpaid_wage - total_paid_wage
    #             },
    #             status=status.HTTP_200_OK
    #
    #         )


class TotalInternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = InternalTransactionSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = InternalTransactionFilterSet
    filterset_fields = [
        'saleReferenceId',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_fullname',
        'payer_mobile',
        'user__fullname',
        'user__first_name',
        'user__last_name',
        'user__mobile',
        'kill_house__name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__mobile',
        'parent_kill_house__name',
        'parent_kill_house__kill_house_operator__user__fullname',
        'parent_kill_house__kill_house_operator__user__first_name',
        'parent_kill_house__kill_house_operator__user__last_name',
        'parent_kill_house__kill_house_operator__user__mobile'

    ]

    def list(self, request, *args, **kwargs):
        transactions_list = []
        # todo: موقت دکتر گفته بزارمش روی کشتارگاه ها
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            transactions = InternalTransaction.objects.filter(
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed', payer_type='kill_house',
                trash=False).order_by('-date')
        else:
            transactions = InternalTransaction.objects.filter(
                status='completed', payer_type='kill_house',
                trash=False).order_by('-date')

        # if request.GET['role'] == 'ProvinceOperator':
        #     transactions = transactions.filter(union_share__gt=0)
        # elif request.GET['role'] == 'Company':
        #     transactions = transactions.filter(company_share__gt=0)
        # elif request.GET['role'] == 'Guilds':
        #     transactions = transactions.filter(guilds_share__gt=0)
        # elif request.GET['role'] == 'SuperAdmin':
        #     transactions = transactions.filter().exclude(guilds_share=0, company_share=0, union_share=0)
        # else:
        #     pass

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class ParentCompanyTotalInternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [AllowAny]
    serializer_class = InternalTransactionSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = InternalTransactionFilterSet
    filterset_fields = [
        'saleReferenceId',
        'refId',
        'orderId',
        'cardHolderPan',
        'payer_fullname',
        'payer_mobile',
        'user__fullname',
        'user__first_name',
        'user__last_name',
        'user__mobile',
        'kill_house__name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__mobile',
        'parent_kill_house__name',
        'parent_kill_house__kill_house_operator__user__fullname',
        'parent_kill_house__kill_house_operator__user__first_name',
        'parent_kill_house__kill_house_operator__user__last_name',
        'parent_kill_house__kill_house_operator__user__mobile'

    ]

    def list(self, request, *args, **kwargs):
        transactions_list = []
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            transactions = InternalTransaction.objects.filter(
                date__date__gte=date1,
                date__date__lte=date2,
                status='completed',
                trash=False).order_by('-date')
        else:
            transactions = InternalTransaction.objects.filter(
                status='completed',
                trash=False).order_by('-date')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class PayersInternalTransactionViewset(viewsets.ModelViewSet):
    queryset = InternalTransaction.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = InternalTransactionSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = InternalTransactionFilterSet
    filterset_fields = [
        'saleReferenceId',
        'refId',
        'orderId',
        'cardHolderPan',

    ]

    def list(self, request, *args, **kwargs):
        date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
        date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        user = SystemUserProfile.objects.get(user=request.user)
        transactions_list = []
        transactions = InternalTransaction.objects.filter(
            trash=False).order_by('id')
        if request.GET['type'] == 'success':

            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()

                transactions = transactions.filter(
                    Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                    date__date__gte=date1,
                    date__date__lte=date2,
                    status='completed',
                )

            elif request.GET['role'] == 'ChainCompany':
                chain_company = ChainCompany.objects.get(user=user, trash=False)

                transactions = transactions.filter(
                    chain_company=chain_company,
                    date__date__gte=date1,
                    date__date__lte=date2,
                    status='completed',
                )

        if request.GET['type'] == 'failed':
            if request.GET['role'] == 'KillHouse':
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()

                transactions = transactions.filter(
                    Q(kill_house=kill_house) | Q(parent_kill_house=kill_house),
                    date__date__gte=date1,
                    date__date__lte=date2,
                    status='failed',
                )

            elif request.GET['role'] == 'ChainCompany':
                chain_company = ChainCompany.objects.get(user=user, trash=False)

                transactions = transactions.filter(
                    chain_company=chain_company,
                    date__date__gte=date1,
                    date__date__lte=date2,
                    status='failed',
                )

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class CityLivestockViewSet(viewsets.ModelViewSet):
    queryset = CityLivestock.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityLivestockSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            city_livestock = user.city_livestock_user.all()

            # send to serializer
            serializer = self.serializer_class(city_livestock[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class FinalApprovalOutProvinceViewSet(viewsets.ModelViewSet):
    queryset = PoultryRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityLivestockSerializer

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        now = datetime.now().date()
        poultry_requests = PoultryRequest.objects.filter(trash=False, out_province_request_cancel=False, out=True,
                                                         send_date__date=now, province_state='pending',
                                                         final_state='pending', state_process='pending')
        poultry = SystemUserProfile.objects.filter(
            key__in=poultry_requests.filter(payer_type='poultry', sms=False).values_list('poultry__user__key',
                                                                                         flat=True)).values_list('id',
                                                                                                                 flat=True)
        buyer = SystemUserProfile.objects.filter(
            key__in=poultry_requests.filter(payer_type='buyer', sms=False).values_list(
                'out_province_poultry_request_buyer__user__key',
                flat=True)).values_list('id', flat=True)
        poultry_requests_for_sms = poultry_requests.filter(payer_type='poultry').values_list('id', flat=True).distinct()
        wage_type = WageType.objects.filter(en_name='poultry-sell-out-province', trash=False).first()
        if wage_type and wage_type.status == True:
            sms = threading.Thread(target=send_sms_for_final_approval_out_province_threading,
                                   args=(list(buyer), list(poultry_requests_for_sms)))
            sms.start()
        for poultry_request in poultry_requests:
            # if poultry_request.has_wage == False:
            hatching = PoultryHatching.objects.get(key=poultry_request.hatching.key, trash=False)
            if hatching.left_over >= poultry_request.quantity:
                hatching.out_province_killed_weight += int(poultry_request.quantity * poultry_request.Index_weight)
                hatching.out_province_killed_quantity += poultry_request.quantity
                hatching.save()
            else:
                different_quantity = poultry_request.quantity - hatching.left_over
                hatching.out_province_killed_weight += int(hatching.left_over * poultry_request.Index_weight)
                hatching.out_province_killed_quantity += hatching.left_over
                hatching.extra_killed_quantity += different_quantity
                hatching.save()
            url = f'https://rasadyar.net/pay/{base_url_for_sms_report}'
            if poultry_request.payer_type == 'poultry':
                poultry_request.payment_link = f'{url}/p{poultry_request.poultry.user.user_gate_way_id}{poultry_request.order_code}'
            else:
                poultry_request.payment_link = f'{url}/b{poultry_request.out_province_poultry_request_buyer.user.user_gate_way_id}'
            poultry_request.final_state = 'archive'
            poultry_request.province_state = 'accepted'
            poultry_request.state_process = 'accepted'
            poultry_request.agent = {
                "role": None,
                "fullname": user.fullname,
                "mobile": user.mobile,
                "date": str(datetime.now())
            }
            poultry_request.hatching_left_over = poultry_request.hatching.left_over

            poultry_request.save()

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


class ImprovingLivestockViewSet(viewsets.ModelViewSet):
    queryset = ImprovingLivestock.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ImprovingLivestockSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        # refresh(request.user.id)
        # get operator profile information
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            # get operator object
            improving_livestock = user.improving_livestock_user.all()

            # send to serializer
            serializer = self.serializer_class(improving_livestock[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class ReportSubmissionTimeViewset(viewsets.ModelViewSet):
    queryset = ReportSubmissionTime.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ReportSubmissionTimeSerializer

    def list(self, request, *args, **kwargs):
        report_submission = ReportSubmissionTime.objects.filter(trash=False).first()
        serializer = self.serializer_class(report_submission)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        report_submission = ReportSubmissionTime.objects.filter(trash=False).first()
        serializer = self.serializer_class(report_submission)
        serializer.update(instance=report_submission, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ReportsViewset(viewsets.ModelViewSet):
    queryset = Reports.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ReportsSerializer

    def list(self, request, *args, **kwargs):
        reports = Reports.objects.filter(trash=False, active=False).order_by('id')
        serializer = self.serializer_class(reports, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ReportsUsersViewset(viewsets.ModelViewSet):
    queryset = ReportsUsers.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ReportsUsersSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = ReportsUsersFilterSet
    filterset_fields = [
        'firstname',
        'lastname',
        'fullname',
        'mobile',
        'position',
        'city',

    ]

    def create(self, request, *args, **kwargs):
        if ReportsUsers.objects.filter(mobile=request.data['mobile']).exists():
            return Response({"result": "این کاربر قبلا ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            user = serializer.create(validated_data=request.data)
            reports = Reports.objects.filter(active=True, trash=False)
            if reports:
                for report in reports:
                    user_report = UserReports(
                        user=user,
                        report=report
                    )
                    user_report.save()
                    report.active = True
                    report.save()
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        users_list = []
        reports_users = ReportsUsers.objects.filter(trash=False).order_by('id')
        if 'search' in request.GET:
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=reports_users
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=reports_users)
                            users_list = ps.filter()
                    reports_users = [] if len(users_list) == 0 else users_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(reports_users)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(reports_users, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        reports_user = ReportsUsers.objects.get(key=request.data['user_key'], trash=False)
        request.data.pop('user_key')
        if 'mobile' in request.data.keys() and request.data['mobile'] != reports_user.mobile:
            if ReportsUsers.objects.filter(mobile=request.data['mobile']).exists():
                return Response({"result": "این کاربر قبلا ثبت شده است"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(reports_user)
        serializer.update(instance=reports_user, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class UserReportsViewset(viewsets.ModelViewSet):
    queryset = UserReports.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = UserReportsSerializer

    def create(self, request, *args, **kwargs):
        reports = Reports.objects.filter(key__in=request.data['reports_list'])
        reports_users = ReportsUsers.objects.filter(trash=False).order_by('id')

        for report in reports:
            for user in reports_users:
                user_report = UserReports(
                    user=user,
                    report=report
                )
                user_report.save()
            report.active = True
            report.save()

        return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None, *args, **kwargs):
        if 'user_report_key' in request.data.keys():
            user_report = UserReports.objects.get(key=request.data['user_report_key'], trash=False)
            request.data.pop('user_report_key')
            serializer = self.serializer_class(user_report)
            serializer.update(instance=user_report, validated_data=request.data)
            return Response(serializer.data, status=status.HTTP_200_OK)

        report = Reports.objects.get(key=request.data['report_key'], trash=False)
        user_reports = UserReports.objects.filter(report=report)
        if not user_reports:
            return Response({"result": "گزارشی ثبت نشده"}, status=status.HTTP_403_FORBIDDEN)
        for user_report in user_reports:
            user_report.active = request.data['active']
            user_report.save()
        return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)


class MovingTextDashboardStatusViewset(viewsets.ModelViewSet):
    queryset = MovingTextDashboardStatus.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = MovingTextDashboardStatusSerializer

    def list(self, request, *args, **kwargs):
        moving_text_dashboard = MovingTextDashboardStatus.objects.filter(trash=False).first()
        serializer = self.serializer_class(moving_text_dashboard)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        moving_text_dashboard = MovingTextDashboardStatus.objects.filter(trash=False).first()
        serializer = self.serializer_class(moving_text_dashboard)
        serializer.update(instance=moving_text_dashboard, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class MovingTextViewset(viewsets.ModelViewSet):
    queryset = MovingText.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = MovingTextSerializer
    pagination_class = CustomPagination

    def create(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            moving_text = serializer.create(validated_data=request.data)
            roles = MovingTextRole.objects.filter(trash=False)
            if roles:
                for role in roles:
                    moving_text_with_role = MovingTextWithRole(
                        moving_text=moving_text,
                        role=role
                    )
                    moving_text_with_role.save()
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        if 'dashboard' in request.GET:
            role = SystemUserProfile.objects.get(user=request.user, trash=False).role.all().values_list('name',
                                                                                                        flat=True)
            moving_text_id = MovingTextWithRole.objects.filter(trash=False, active=True,
                                                               role__role__in=role).values_list('moving_text',
                                                                                                flat=True)
            moving_text = MovingText.objects.filter(id__in=moving_text_id, trash=False).order_by('id')
            serializer = MovingTextForDashboardSerializer(moving_text, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)



        else:
            moving_text = MovingText.objects.filter(trash=False).order_by('id')
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(moving_text)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(moving_text, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        moving_text = MovingText.objects.get(trash=False, key=request.data['moving_text_key'])
        request.data.pop('moving_text_key')
        serializer = self.serializer_class(moving_text)
        serializer.update(instance=moving_text, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class MovingTextWithRoleViewset(viewsets.ModelViewSet):
    queryset = MovingTextWithRole.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = MovingTextWithRoleSerializer

    def update(self, request, pk=None, *args, **kwargs):
        moving_text_role = MovingTextWithRole.objects.get(trash=False, key=request.data['moving_text_role_key'])
        request.data.pop('moving_text_role_key')
        serializer = self.serializer_class(moving_text_role)
        serializer.update(instance=moving_text_role, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class NewProductViewset(viewsets.ModelViewSet):
    queryset = NewProduct.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = NewProductSerializer

    def create(self, request, *args, **kwargs):
        parent = None
        if 'parent_key' in request.data.keys():
            if request.data['parent_key'] is not None:
                parent = NewProduct.objects.get(key=request.data['parent_key'])
            request.data.pop('parent_key')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            product = serializer.create(validated_data=request.data)
            if parent is not None:
                product.parent = parent
                product.save()
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        products = NewProduct.objects.filter(trash=False)
        serializer = self.serializer_class(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class RolesProductsViewset(viewsets.ModelViewSet):
    queryset = RolesProducts.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = RolesProductsSerializer

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.GET['role'] == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()
            products = RolesProducts.objects.filter(kill_house=kill_house, trash=False)

        elif request.GET['role'] in ['Guild', 'Steward']:
            products = RolesProducts.objects.filter(guild__user=user, guild__active=True, trash=False)

        else:
            products = RolesProducts.objects.filter(trash=False)
        serializer = self.serializer_class(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosRolesProductsViewset(viewsets.ModelViewSet):
    queryset = RolesProducts.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosRolesProductsSerializer

    def list(self, request, *args, **kwargs):
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)
        if pos.kill_house:
            products = RolesProducts.objects.filter(kill_house=pos.kill_house, trash=False)
        else:
            products = RolesProducts.objects.filter(guild=pos.guild, trash=False)

        serializer = self.serializer_class(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        request.data.pop('product_key')
        serializer = self.serializer_class(product)
        serializer.update(instance=product, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosPosOtherProductsViewset(viewsets.ModelViewSet):
    queryset = OtherProducts.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosOtherProductsSerializer

    def list(self, request, *args, **kwargs):
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)
        if pos.kill_house:
            products = OtherProducts.objects.filter(kill_house=pos.kill_house, trash=False)
        else:
            products = OtherProducts.objects.filter(guild=pos.guild, trash=False)

        serializer = self.serializer_class(products, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def create(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        image = None
        kill_house = None
        guild = None
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        if 'image' in request.data.keys():
            image = request.data['image']
            request.data.pop('image')
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        if pos.kill_house:
            kill_house = KillHouse.objects.get(key=pos.kill_house.key, trash=False)
        else:
            guild = Guilds.objects.get(key=pos.guild.key, trash=False)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            product = serializer.create(validated_data=request.data)
            if image:
                product.image = send_image_to_server(image)
            if kill_house:
                product.kill_house = kill_house
            else:
                product.guild = guild

            product.save()
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)

    def update(self, request, pk=None, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        image = None
        try:
            product = OtherProducts.objects.get(trash=False, key=request.data['product_key'])
            request.data.pop('product_key')
        except:
            return Response({"result": "محصول مورد نظر یافت نشد!"}, status=status.HTTP_200_OK)

        if 'image' in request.data.keys():
            image = request.data['image']
            request.data.pop('image')
            product.image = send_image_to_server(image)
        serializer = self.serializer_class(product)
        serializer.update(instance=product, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error
        product = OtherProducts.objects.get(trash=False, key=request.GET["product_key"])
        product.trash = True
        product.save()
        return Response({"result": "با موفقیت حذف شد."}, status=status.HTTP_200_OK)


class CombinedPosProductsViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = CombinedPosProductSerializer

    def get_queryset(self, pos_id, version):
        pos = POSMachine.objects.get(pos_id=pos_id, trash=False)
        if pos.kill_house:
            roles_products = RolesProducts.objects.filter(kill_house=pos.kill_house, trash=False)
            other_products = OtherProducts.objects.filter(kill_house=pos.kill_house, trash=False)
        elif pos.guild:
            roles_products = RolesProducts.objects.filter(guild=pos.guild, trash=False)
            other_products = OtherProducts.objects.filter(guild=pos.guild, trash=False)
        else:
            if int(version) <= 217:
                live_stock_products = LiveStockRolseProduct.objects.filter(cooperative=pos.cooperative,
                                                                           parent_product__name='سبوس', trash=False)
            else:
                live_stock_products = LiveStockRolseProduct.objects.filter(cooperative=pos.cooperative, trash=False)
            return list(live_stock_products)

        return list(roles_products) + list(other_products)

    def list(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        version = request.headers.get('device-version')
        queryset = self.get_queryset(validation_device, version)
        serializer = self.get_serializer(queryset, many=True, context={'validation_device': validation_device})
        return Response(serializer.data, status=status.HTTP_200_OK)
class NewCombinedPosProductsViewSet(viewsets.ModelViewSet):
    permission_classes = [AllowAny]
    serializer_class = NewCombinedPosProductSerializer

    def get_queryset(self, pos, version,role):
        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=pos.owner).first()
            roles_products = RolesProducts.objects.filter(kill_house=kill_house, trash=False)
            other_products = OtherProducts.objects.filter(kill_house=kill_house, trash=False)

        elif role == 'Steward':
            steward = Steward.objects.filter(user=pos.owner).first()
            roles_products = RolesProducts.objects.filter(steward=steward, trash=False)
            other_products = OtherProducts.objects.filter(steward=steward, trash=False)
        elif role == 'Guilds':
            guild = Guilds.objects.filter(user=pos.owner).first()
            roles_products = RolesProducts.objects.filter(guild=guild, trash=False)
            other_products = OtherProducts.objects.filter(guild=guild, trash=False)
        else:
            if int(version) <= 217:
                live_stock_products = LiveStockRolseProduct.objects.filter(cooperative=pos.cooperative,
                                                                           parent_product__name='سبوس', trash=False)
            else:
                live_stock_products = LiveStockRolseProduct.objects.filter(cooperative=pos.cooperative, trash=False)
            return list(live_stock_products)

        return list(roles_products) + list(other_products)

    def list(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_pos()
        version = request.headers.get('device-version')
        role = request.headers.get('device-role')
        queryset = self.get_queryset(validation_device, version,role)
        serializer = self.get_serializer(queryset, many=True, context={'validation_device': validation_device})
        return Response(serializer.data, status=status.HTTP_200_OK)


class AdminXViewSet(viewsets.ModelViewSet):
    queryset = AdminX.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AdminXSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)

            super_admin = user.admin_x_user.all()

            serializer = self.serializer_class(super_admin[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


class SupporterViewSet(viewsets.ModelViewSet):
    queryset = Supporter.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SupporterSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            super_admin = SystemUserProfile.objects.get(user=request.user, trash=False).supporter_user.first()

            serializer = self.serializer_class(super_admin)
            return Response(serializer.data, status=status.HTTP_200_OK)


class ZarinPalAccountsViewset(viewsets.ModelViewSet):
    queryset = ZarinPalAccounts.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ZarinPalAccountsSerializer

    def list(self, request, *args, **kwargs):
        zarinpal_accounts = ZarinPalAccounts.objects.filter(trash=False).order_by('id')
        serializer = self.serializer_class(zarinpal_accounts, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        zarinpal_account = ZarinPalAccounts.objects.get(trash=False, key=request.data['account_key'])
        request.data.pop('account_key')
        serializer = self.serializer_class(zarinpal_account)
        serializer.update(instance=zarinpal_account, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PoultryExportViewset(viewsets.ModelViewSet):
    queryset = PoultryExport.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryExportSerializer

    def list(self, request, *args, **kwargs):
        poultry_export = PoultryExport.objects.filter(trash=False).first()
        serializer = self.serializer_class(poultry_export)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        poultry_export = PoultryExport.objects.filter(trash=False).first()
        serializer = self.serializer_class(poultry_export)
        serializer.update(instance=poultry_export, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PoultryOutProvinceRequestViewset(viewsets.ModelViewSet):
    queryset = PoultryOutProvinceRequest.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryOutProvinceRequestSerializer

    def list(self, request, *args, **kwargs):
        poultry_out_province = PoultryOutProvinceRequest.objects.filter(trash=False).first()
        serializer = self.serializer_class(poultry_out_province)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        poultry_out_province = PoultryOutProvinceRequest.objects.filter(trash=False).first()
        serializer = self.serializer_class(poultry_out_province)
        serializer.update(instance=poultry_out_province, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


def pos_machine_to_dict(pos):
    return {
        "pos_id": pos.pos_id,
        "receiver_number": pos.receiver_number,
        "terminal_number": pos.terminal_number,
        "Lat": pos.Lat,
        "Long": pos.Long,
        "pos-company": pos.pos_company.en_name,
    }


def get_pos_details(pos_machines):
    return [pos_machine_to_dict(pos) for pos in pos_machines]


def get_role_user_details(role_type, user, name, pos_details):
    return {
        "type": role_type,
        "user-key": user.user_gate_way_id,
        "fullname": user.fullname,
        "firstname": user.first_name,
        "lastname": user.last_name,
        "mobile": user.mobile,
        "name": name,
        "pos-list": pos_details,
    }


@api_view(['GET'])
@permission_classes([AllowAny])
def Rolesusers(request):
    pos_id = request.query_params.get('pos_id')
    role_type = request.query_params.get('type', 'all').lower()
    user_key = request.query_params.get('user_key')

    pos_machines = POSMachine.objects.filter(trash=False).select_related('pos_company')

    # If pos_id is provided
    if pos_id:
        try:
            pos_machine = POSMachine.objects.filter(pos_id=pos_id) \
                .select_related('pos_company', 'kill_house', 'guild', 'steward', 'dispenser') \
                .get()
        except POSMachine.DoesNotExist:
            return Response({"message": "POSMachine not found"}, status=404)

        pos_details = pos_machine_to_dict(pos_machine)
        if pos_machine.kill_house:
            owner = pos_machine.kill_house.kill_house_operator.user
            type_match = "kill-house"
            name = pos_machine.kill_house.name
        elif pos_machine.guild:
            owner = pos_machine.guild.user
            type_match = "guilds"
            name = pos_machine.guild.guilds_name
        elif pos_machine.dispenser:
            owner = pos_machine.dispenser.user
            type_match = "dispenser"
            name = pos_machine.dispenser.user.fullname
        elif pos_machine.steward:
            owner = pos_machine.steward
            type_match = "steward"
            name = pos_machine.steward.fullname
        else:
            return Response({"message": "POSMachine has no related owner"}, status=404)

        if user_key and owner.user_gate_way_id != user_key:
            return Response({"message": "User does not match POSMachine owner"}, status=404)

        if role_type != 'all' and role_type != type_match:
            return Response({"message": "Type does not match"}, status=404)

        return Response(get_role_user_details(type_match, owner, name, [pos_details]))

    # If no pos_id, handle filtering by type and user_key
    kill_house_filters = {}
    filters = {}
    if user_key:
        try:
            user_profile = SystemUserProfile.objects.get(user_gate_way_id=user_key)
            kill_house_filters['kill_house_operator__user'] = user_profile
            filters['user'] = user_profile
        except SystemUserProfile.DoesNotExist:
            return Response({"message": "User not found"}, status=404)

    roles_users_list = []

    if role_type in ['all', 'kill-house']:
        kill_houses = KillHouse.objects.filter(
            out_province=False, trash=False, **kill_house_filters
        ).select_related('kill_house_operator__user') \
            .prefetch_related(Prefetch('kill_house_pos', queryset=pos_machines)) \
            .only('kill_house_operator__user__fullname', 'kill_house_operator__user__first_name',
                  'kill_house_operator__user__last_name', 'kill_house_operator__user__mobile', 'name')

        for kh in kill_houses:
            if role_type in ['all', 'kill-house']:
                roles_users_list.append(
                    get_role_user_details("KillHouse", kh.kill_house_operator.user, kh.name,
                                          get_pos_details(kh.kill_house_pos.all()))
                )

    if role_type in ['all', 'guilds', 'steward']:
        guilds_stewards = Guilds.objects.filter(
            trash=False, **filters
        ).select_related('user') \
            .prefetch_related(Prefetch('guild_pos', queryset=pos_machines)) \
            .only('user__fullname', 'user__first_name', 'user__last_name', 'user__mobile', 'guilds_name')

        for gs in guilds_stewards:
            if role_type in ['all', 'guilds']:
                roles_users_list.append(
                    get_role_user_details("Guilds", gs.user, gs.guilds_name, get_pos_details(gs.guild_pos.all()))
                )

    if role_type in ['all', 'dispenser']:
        dispensers = Dispenser.objects.filter(
            trash=False, **filters
        ).select_related('user') \
            .prefetch_related(Prefetch('dispenser_pos', queryset=pos_machines)) \
            .only('user__fullname', 'user__first_name', 'user__last_name', 'user__mobile')

        for disp in dispensers:
            if role_type in ['all', 'dispenser']:
                roles_users_list.append(
                    get_role_user_details("Dispenser", disp.user, disp.user.fullname,
                                          get_pos_details(disp.dispenser_pos.all()))
                )

    if not roles_users_list:
        return Response({"message": "Not found"}, status=404)

    return Response(roles_users_list)


class VetFarmAggregatePermissionViewset(viewsets.ModelViewSet):
    queryset = VetFarmAggregatePermission.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = VetFarmAggregatePermissionSerializer

    def list(self, request, *args, **kwargs):
        aggregate_permission = VetFarmAggregatePermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(aggregate_permission)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        aggregate_permission = VetFarmAggregatePermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(aggregate_permission)
        serializer.update(instance=aggregate_permission, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class KillHouseBarLimitationViewset(viewsets.ModelViewSet):
    queryset = KillHouseBarLimitation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillHouseBarLimitationSerializer

    def list(self, request, *args, **kwargs):
        bar_limitation = KillHouseBarLimitation.objects.filter(trash=False).first()
        serializer = self.serializer_class(bar_limitation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        bar_limitation = KillHouseBarLimitation.objects.filter(trash=False).first()
        serializer = self.serializer_class(bar_limitation)
        serializer.update(instance=bar_limitation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class KillHouseDistributionManagementStewardGuildViewset(viewsets.ModelViewSet):
    queryset = KillHouse.objects.filter(trash=False, out_province=False).order_by('id')
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillHouseDistributionManagementStewardGuildSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = KillHouseFilterSet
    filterset_fields = [
        'name',
        'kill_house_operator__user__fullname',
        'kill_house_operator__user__first_name',
        'kill_house_operator__user__last_name',
        'kill_house_operator__user__mobile',

    ]

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        if role in ('CityOperator', 'CityJahad', 'CityCommerce', 'CitySupervisor', 'CityGuild'):
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            kill_houses = KillHouse.objects.filter(address__city=user.city, trash=False, out_province=False).order_by(
                'id')
        else:

            kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('id')
        kill_house_list = []
        if 'search' in request.GET:
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=kill_houses
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=kill_houses)
                            kill_house_list = ps.filter()
                    kill_houses = [] if len(kill_house_list) == 0 else kill_house_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(kill_houses)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(kill_houses, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class StewardDistributionManagementGuildViewset(viewsets.ModelViewSet):
    queryset = Guilds.objects.filter(trash=False, steward=True).order_by('id')
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardDistributionManagementGuildSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsFilterSet

    def list(self, request, *args, **kwargs):
        stewards = Guilds.objects.filter(trash=False, steward=True).order_by('id')

        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                stewards = stewards.filter(
                    self.build_query(value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(stewards.distinct())
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = GuildsSerializer(stewards.distinct(), many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def build_query(self, value):
        from django.db.models import Q
        query = Q()
        for field in self.filterset_class.Meta.fields:
            query |= Q(**{f"{field}__icontains": value})
        return query


class OutOfProvinceSellingCarcassesPermissionViewset(viewsets.ModelViewSet):
    queryset = OutOfProvinceSellingCarcassesPermission.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = OutOfProvinceSellingCarcassesPermissionSerializer

    def list(self, request, *args, **kwargs):
        permission = OutOfProvinceSellingCarcassesPermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(permission)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        permission = OutOfProvinceSellingCarcassesPermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(permission)
        serializer.update(instance=permission, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class BaseOutProvinceCarcassesBuyerViewSet(viewsets.ModelViewSet):
    queryset = BaseOutProvinceCarcassesBuyer.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = BaseOutProvinceCarcassesBuyerSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = BaseOutProvinceCarcassesBuyerFilterSet
    filterset_fields = [
        'mobile',
        'first_name',
        'last_name',
        'fullname',
        'unit_name',
        'city',
        'province',

    ]

    def list(self, request, *args, **kwargs):
        buyer_list = []
        if 'state' in request.GET:
            buyers = BaseOutProvinceCarcassesBuyer.objects.filter(trash=False).order_by('id')
            if 'search' in request.GET:
                if request.GET['search'] == 'filter':
                    if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                        for item in self.filterset_fields:
                            query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                            if (self.filterset_class(
                                    data=query,
                                    queryset=buyers
                            )
                            ).filter():
                                ps = self.filterset_class(data=query, queryset=buyers)
                                buyer_list = ps.filter()
                        buyers = [] if len(buyer_list) == 0 else buyer_list

            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(buyers)
            if page is not None:
                serializer = BaseOutProvinceCarcassesBuyerFordispensersSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)

        elif 'mobile' in request.GET:
            buyer = BaseOutProvinceCarcassesBuyer.objects.filter(mobile=request.GET['mobile'], trash=False)
            if buyer:
                serializer = self.get_serializer(buyer.first())
                return Response(serializer.data, status=status.HTTP_200_OK)
            else:
                return Response({"result": "خریداری یافت نشد!"}, status=status.HTTP_404_NOT_FOUND)


        else:
            buyers = BaseOutProvinceCarcassesBuyer.objects.filter(active=True, trash=False).order_by('id')
            serializer = self.get_serializer(buyers, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)


class OutProvinceCarcassesBuyerViewSet(viewsets.ModelViewSet):
    LEGAL_DOCUMENT_ENDPOINT = "https://pay.rasadyar.net/national-documents"

    queryset = OutProvinceCarcassesBuyer.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = OutProvinceCarcassesBuyerrSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = OutProvinceCarcassesBuyerFilterSet
    filterset_fields = [
        'mobile',
        'first_name',
        'last_name',
        'fullname',
        'unit_name',

    ]

    def _fetch_legal_person_payload(self, info_value: str):
        info_value = info_value or self.request.data.get('info_value')
        if not info_value:
            return None
        try:
            response = requests.get(
                self.LEGAL_DOCUMENT_ENDPOINT,
                params={'info': info_value, 'type': 'unit'},
            )
            if response.status_code == 200:
                return response.json()
        except:
            return None

    def _normalize_branch_list(self, value):
        if value in (None, ''):
            return value
        if isinstance(value, str):
            return value
        try:
            return json.dumps(value, ensure_ascii=False)
        except (TypeError, ValueError):
            return str(value)

    def _apply_legal_person_payload(self, base_buyer, payload, is_real_person):
        base_buyer.isRealPerson = is_real_person
        if not payload:
            return None
        base_buyer.status = payload.get('status', False)
        base_buyer.statusCode = payload.get('statusCode')
        base_buyer.apiLogId = payload.get('apiLogId')

        data = payload.get('data') or {}
        base_buyer.legalPersonInfoDtoId = data.get('legalPersonInfoDtoId')
        base_buyer.parentLegalPersonId = data.get('parentLegalPersonId')
        base_buyer.successful = data.get('successful', False)
        base_buyer.message = data.get('message')
        base_buyer.name = data.get('name')
        base_buyer.nationalCode = data.get('nationalCode')
        base_buyer.postCode = data.get('postCode')
        base_buyer.address = data.get('address')
        base_buyer.legalPersonType = data.get('legalPersonType')
        base_buyer.registerNumber = data.get('registerNumber')
        base_buyer.registerUnit = data.get('registerUnit')
        base_buyer.registerDate = data.get('registerDate')
        base_buyer.registerDateUnix = data.get('registerDateUnix')
        base_buyer.residency = data.get('residency')
        base_buyer.state = data.get('state')
        base_buyer.isSettle = data.get('isSettle', False)
        base_buyer.settleDate = data.get('settleDate')
        base_buyer.isBreakUp = data.get('isBreakUp', False)
        base_buyer.breakUpdate = data.get('breakUpdate')
        base_buyer.isBranch = data.get('isBranch', False)
        base_buyer.branchList = self._normalize_branch_list(data.get('branchList'))
        base_buyer.establishmentDate = data.get('establishmentDate')
        base_buyer.isDbResult = data.get('isDbResult', False)
        base_buyer.serviceType = data.get('serviceType')

        parent = data.get('parentLegalPerson') or {}
        base_buyer.parentLegalPersonInfoDtoId = parent.get('legalPersonInfoDtoId')
        base_buyer.parentLegalPersonParentId = parent.get('parentLegalPersonId')
        base_buyer.parentLegalPersonSuccessful = parent.get('successful', False)
        base_buyer.parentLegalPersonMessage = parent.get('message')
        base_buyer.parentLegalPersonName = parent.get('name')
        base_buyer.parentLegalPersonNationalCode = parent.get('nationalCode')
        base_buyer.parentLegalPersonPostCode = parent.get('postCode')
        base_buyer.parentLegalPersonAddress = parent.get('address')
        base_buyer.parentLegalPersonType = parent.get('legalPersonType')
        base_buyer.parentLegalPersonRegisterNumber = parent.get('registerNumber')
        base_buyer.parentLegalPersonRegisterUnit = parent.get('registerUnit')
        base_buyer.parentLegalPersonRegisterDate = parent.get('registerDate')
        base_buyer.parentLegalPersonRegisterDateUnix = parent.get('registerDateUnix')
        base_buyer.parentLegalPersonResidency = parent.get('residency')
        base_buyer.parentLegalPersonState = parent.get('state')
        base_buyer.parentLegalPersonIsSettle = parent.get('isSettle', False)
        base_buyer.parentLegalPersonSettleDate = parent.get('settleDate')
        base_buyer.parentLegalPersonIsBreakUp = parent.get('isBreakUp', False)
        base_buyer.parentLegalPersonBreakUpdate = parent.get('breakUpdate')
        base_buyer.parentLegalPersonIsBranch = parent.get('isBranch', False)
        base_buyer.parentLegalPersonBranchList = self._normalize_branch_list(parent.get('branchList'))
        base_buyer.parentLegalPersonEstablishmentDate = parent.get('establishmentDate')
        base_buyer.parentLegalPersonIsDbResult = parent.get('isDbResult', False)
        base_buyer.parentLegalPersonServiceType = parent.get('serviceType')

    def create(self, request, *args, **kwargs):
        role = request.data.pop('role', None)
        operator_user = SystemUserProfile.objects.get(user=request.user, trash=False)
        if request.data.get('info_value'):
            if BaseOutProvinceCarcassesBuyer.objects.filter(trash=False,
                                                            nationalCode=request.data.get('info_value')).exists():
                return Response({"result": "کاربر وجود دارد! "}, status=status.HTTP_403_FORBIDDEN)
        if role:
            steward = Guilds.objects.get(user=operator_user, active=True, trash=False)


        else:
            kill_house = KillHouse.objects.filter(kill_house_operator__user=operator_user, trash=False).first()

        if SystemUserProfile.objects.filter(mobile=request.data['mobile'], trash=False).exists():
            system_profile = SystemUserProfile.objects.get(mobile=request.data['mobile'], trash=False)
        else:
            password = "123456"
            data = {
                "username": request.data['mobile'],
                "password": password,
                "api_key": PROJECT_API_KEY
            }
            req = requests.post(
                url=ARTA_URL_REGISTER,
                data=data,
                verify=False
            )

            if req.status_code in (200, 400):
                user = User(username=request.data['mobile'], first_name=request.data['first_name'],
                            last_name=request.data['last_name'])
                user.save()
                base_id = SystemUserProfile.objects.all()
                if base_id.count() > 0:
                    base_id = int(base_id.last().base_order) + 1
                else:
                    base_id = 1000
                system_profile = SystemUserProfile(
                    mobile=request.data['mobile'],
                    first_name=request.data['first_name'],
                    last_name=request.data['last_name'],
                    user=user,
                    base_order=base_id,
                    password=password,
                    national_id=request.data['national_id'],
                    city=operator_user.city,
                    province=operator_user.province
                )
                system_profile.save()
            else:
                return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است! "}, status=status.HTTP_403_FORBIDDEN)

        base_buyer = BaseOutProvinceCarcassesBuyer.objects.filter(trash=False, user=system_profile)
        if base_buyer:
            base_buyer = base_buyer.first()
        else:
            base_buyer = BaseOutProvinceCarcassesBuyer(
                user=system_profile,
            )
        base_buyer.first_name = request.data['first_name']
        base_buyer.last_name = request.data['last_name']
        base_buyer.mobile = request.data['mobile']
        base_buyer.unit_name = request.data['unit_name']
        base_buyer.city = request.data['city']
        base_buyer.province = request.data['province']
        base_buyer.national_id = request.data['national_id']

        if 'isRealPerson' in request.data:
            is_real_person_value = request.data.get('isRealPerson')
            if isinstance(is_real_person_value, bool):
                is_real_person = is_real_person_value
            else:
                is_real_person = str(is_real_person_value).strip().lower() in (
                    'true', '1', 'yes', 'y', 'on', 'real', 'حقیقی'
                )
            legal_info_value = (
                    request.data.get('info_value')
                    or request.data.get('legalNationalCode')
                    or request.data.get('legal_national_code')
                    or request.data.get('national_id')
            )
            legal_payload = self._fetch_legal_person_payload(legal_info_value)
            self._apply_legal_person_payload(base_buyer, legal_payload, is_real_person)
        base_buyer.save()
        if role:
            if OutProvinceCarcassesBuyer.objects.filter(buyer=base_buyer, steward=steward).exists():
                return Response({"result": "خریدار قبلا برای مباشر ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)
        else:
            if OutProvinceCarcassesBuyer.objects.filter(buyer=base_buyer, Kill_house=kill_house).exists():
                return Response({"result": "خریدار قبلا برای کشتارگاه ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)
        if 'info_value' in request.data:
            request.data.pop('info_value')
        if 'isRealPerson' in request.data:
            request.data.pop('isRealPerson')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            buyer = serializer.create(validated_data=request.data)
            if role:
                buyer.steward = steward

            else:
                buyer.Kill_house = kill_house

            buyer.buyer = base_buyer
            buyer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        buyer_list = []
        if 'state' in request.GET:
            if request.GET['role'] == "KillHouse":
                kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()

                buyers = OutProvinceCarcassesBuyer.objects.filter(Kill_house=kill_house, trash=False).order_by('id')

            elif request.GET['role'] == "Steward":
                steward = Guilds.objects.get(user=user, active=True, trash=False)

                buyers = OutProvinceCarcassesBuyer.objects.filter(steward=steward, trash=False).order_by('id')
            else:
                buyers = OutProvinceCarcassesBuyer.objects.filter(trash=False).order_by('id')

            buyer_type = request.GET.get('type')
            if buyer_type:
                buyer_type = str(buyer_type).strip().lower()
                if buyer_type == 'real':
                    buyers = buyers.filter(buyer__isRealPerson=True)
                elif buyer_type == 'legal':
                    buyers = buyers.filter(buyer__isRealPerson=False)

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

            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(buyers)
            if page is not None:
                serializer = OutProvinceCarcassesBuyerForBuyerRequestSerializer(page, many=True,
                                                                                context={'request': request})
                return self.get_paginated_response(serializer.data)
        else:
            if request.GET['role'] == "KillHouse":

                buyers = OutProvinceCarcassesBuyer.objects.filter(Kill_house__kill_house_operator__user=user,
                                                                  active=True, trash=False).order_by('id')
            elif request.GET['role'] == "Steward":

                buyers = OutProvinceCarcassesBuyer.objects.filter(steward__user=user,
                                                                  active=True, trash=False).order_by('id')
            else:
                buyers = OutProvinceCarcassesBuyer.objects.filter(active=True, trash=False).order_by('id')

            buyer_type = request.GET.get('type')
            if buyer_type:
                buyer_type = str(buyer_type).strip().lower()
                if buyer_type == 'real':
                    buyers = buyers.filter(buyer__isRealPerson=True)
                elif buyer_type == 'legal':
                    buyers = buyers.filter(buyer__isRealPerson=False)

            serializer = OutProvinceCarcassesBuyerForChoosingBuyerSerializer(buyers, many=True)
            return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        buyer = OutProvinceCarcassesBuyer.objects.get(key=request.data['buyer_key'], trash=False)

        if 'mobile' in request.data.keys():
            base_buyer = buyer.buyer
            system_user_profile = base_buyer.user if base_buyer else None

            if system_user_profile:
                first_mobile_number = system_user_profile.mobile
                second_mobile_number = request.data['mobile']

                if first_mobile_number != second_mobile_number:
                    if SystemUserProfile.objects.filter(mobile=second_mobile_number, trash=False).exclude(
                            id=system_user_profile.id).exists():
                        return Response(
                            {"result": "این شماره در سامانه به نام شخص دیگری است"},
                            status=status.HTTP_403_FORBIDDEN
                        )

                    data = {
                        "first_mobile_number": first_mobile_number,
                        "second_mobile_number": second_mobile_number,
                    }

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

                    if req.status_code == 200:
                        user = User.objects.get(id=system_user_profile.user.id)
                        user.username = second_mobile_number
                        user.save()

                        system_user_profile.mobile = second_mobile_number
                        system_user_profile.save()

                        buyer.mobile = second_mobile_number
                        buyer.save()
                        if base_buyer:
                            base_buyer.mobile = second_mobile_number
                            base_buyer.save()

            request.data.pop('mobile')

        request.data.pop('buyer_key')
        serializer = self.serializer_class(buyer)
        serializer.update(instance=buyer, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        buyer = OutProvinceCarcassesBuyer.objects.get(key=request.GET["buyer_key"], trash=False)
        buyer.trash = True
        buyer.save()
        return Response({"result": "با موفقیت حذف شد."}, status=status.HTTP_200_OK)


class PosOutProvinceCarcassesBuyerViewSet(viewsets.ModelViewSet):
    queryset = OutProvinceCarcassesBuyer.objects.all()
    permission_classes = [AllowAny]
    serializer_class = OutProvinceCarcassesBuyerrSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = OutProvinceCarcassesBuyerFilterSet
    filterset_fields = [
        'mobile',
        'first_name',
        'last_name',
        'fullname',
        'unit_name',

    ]

    def list(self, request, *args, **kwargs):
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)
        buyers = OutProvinceCarcassesBuyer.objects.filter(Kill_house=pos.kill_house,
                                                          active=True, trash=False).order_by('id')
        serializer = OutProvinceCarcassesBuyerForChoosingBuyerSerializer(buyers, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ProductPricingTypeViewset(viewsets.ModelViewSet):
    queryset = ProductPricingType.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProductPricingTypeSerializer

    def list(self, request, *args, **kwargs):
        pricing_type = ProductPricingType.objects.filter(trash=False).first()
        serializer = self.serializer_class(pricing_type)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        pricing_type = ProductPricingType.objects.filter(trash=False).first()
        serializer = self.serializer_class(pricing_type)
        serializer.update(instance=pricing_type, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class KillHousePricePermissionViewset(viewsets.ModelViewSet):
    queryset = KillHousePricePermission.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = KillHousePricePermissionSerializer

    def list(self, request, *args, **kwargs):
        kill_house_permission = KillHousePricePermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(kill_house_permission)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        kill_house_permission = KillHousePricePermission.objects.filter(trash=False).first()
        serializer = self.serializer_class(kill_house_permission)
        serializer.update(instance=kill_house_permission, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class AutomaticDirectBuyingPermissionViewSet(viewsets.ModelViewSet):
    queryset = AutomaticDirectBuyingPermission.objects.all()
    permission_classes = [AllowAny]
    serializer_class = AutomaticDirectBuyingPermissionSerializer

    def list(self, request, *args, **kwargs):
        query = self.queryset.first()
        ser_data = self.serializer_class(query)
        return Response(ser_data.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        query = self.queryset.first()
        ser_data = self.serializer_class(query)
        ser_data.update(instance=query, validated_data=request.data)
        return Response(ser_data.data, status=status.HTTP_200_OK)


class PosMachineTransactionViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosMachineTransactionsSerializer

    def create(self, request, *args, **kwargs):
        # timestamp_date = request.data['timestamp_date']
        # transaction_date = datetime.fromtimestamp(timestamp_date)
        try:
            product = RolesProducts.objects.get(key=request.data['product_key'])
        except:
            return Response({"result": "محصول موجود نمی باشد!"}, status=status.HTTP_403_FORBIDDEN)
        pos = POSMachine.objects.get(pos_id=request.data['pos-id'])
        # request.data.pop('timestamp_date')
        request.data.pop('product_key')
        request.data.pop('pos-id')

        try:
            pos_transaction = PosMachineTransactions.objects.get(check_id=request.data['check_id'])
            serializer = self.serializer_class(pos_transaction)
            serializer.update(instance=pos_transaction, validated_data=request.data)
            if pos_transaction.paid:
                pos_allocation_weight_for_product(product)
            return Response(serializer.data, status=status.HTTP_200_OK)


        except:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_transaction = serializer.create(validated_data=request.data)
                # pos_transaction.date = transaction_date
                pos_transaction.product = product
                pos_transaction.pos = pos
                pos_transaction.save()
                if pos_transaction.paid:
                    pos_allocation_weight_for_product(product)

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

    def update(self, request, *args, **kwargs):
        # timestamp_date = request.data['timestamp_date']
        # transaction_date = datetime.fromtimestamp(timestamp_date)

        try:
            product = RolesProducts.objects.get(key=request.data['product_key'])
        except:
            return Response({"result": "محصول موجود نمی باشد!"}, status=status.HTTP_403_FORBIDDEN)

        pos = POSMachine.objects.get(pos_id=request.data['pos-id'])
        # request.data.pop('timestamp_date')
        request.data.pop('product_key')
        request.data.pop('pos-id')

        try:
            pos_transaction = PosMachineTransactions.objects.get(check_id=request.data['check_id'])
            serializer = self.serializer_class(pos_transaction)
            serializer.update(instance=pos_transaction, validated_data=request.data)
            if pos_transaction.paid:
                pos_allocation_weight_for_product(product)
            return Response(serializer.data, status=status.HTTP_200_OK)


        except:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_transaction = serializer.create(validated_data=request.data)
                # pos_transaction.date = transaction_date
                pos_transaction.product = product
                pos_transaction.pos = pos
                pos_transaction.save()
                if pos_transaction.paid:
                    pos_allocation_weight_for_product(product)

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


class NewPosMachineTransactionViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosMachineTransactionsSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosMachineTransactionsFilterSet
    filterset_fields = [
        'mobile',
        'natcode',
        'fullname',
    ]

    def create(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device)
        try:
            pos_transaction = PosMachineTransactions.objects.filter(check_id=request.data['check_id']).first()
            if pos_transaction:
                paid = pos_transaction.paid
                request.data.pop('products')

                serializer = self.serializer_class(pos_transaction)
                serializer.update(instance=pos_transaction, validated_data=request.data)
                if not paid and pos_transaction.paid:

                    if not pos_transaction.live_stock:

                        product_transaction = ProductsTransactions.objects.filter(transaction=pos_transaction,
                                                                                  trash=False,
                                                                                  product__isnull=False).first()
                        if product_transaction:
                            pos_allocation_weight_for_product(product_transaction.product)
                    else:
                        product_transaction = ProductsTransactions.objects.filter(transaction=pos_transaction,
                                                                                  trash=False,
                                                                                  live_stack_products__isnull=False).first()
                        if product_transaction:
                            cooperative_warehousing(product_transaction.live_stack_products)
                            rancher_warehousing(pos_transaction)

            else:
                products = request.data['products']
                request.data.pop('products')
                serializer = self.serializer_class(data=request.data)
                if serializer.is_valid():
                    pos_transaction = serializer.create(validated_data=request.data)
                    pos_transaction.pos = pos
                    if pos.kill_house:
                        pos_transaction.kill_house = pos.kill_house
                    elif pos.guild:
                        pos_transaction.guild = pos.guild
                    pos_transaction.date = datetime.now()
                    pos_transaction.save()
                    for product in products:
                        product_transaction = ProductsTransactions(
                            transaction=pos_transaction,
                            cur_price=product['cur_price'],
                            cur_weight=product['cur_qty'],
                            price=product['price'],
                            name=product['name'],
                            image=product['image'],
                            unit=product['unit'],
                            targetunit=product['targetunit'],
                            price_approved=product['price_approved'],
                        )
                        if product['product_type'] == 'roles_product':
                            roles_product = RolesProducts.objects.get(key=product['key'])
                            product_transaction.product = roles_product
                        elif product['product_type'] == 'other_product':
                            other_product = OtherProducts.objects.get(key=product['key'])
                            product_transaction.other_product = other_product
                        elif product['product_type'] == 'stock_product':
                            pos_transaction.live_stock = True
                            pos_transaction.save()
                            live_stock_product = LiveStockRolseProduct.objects.get(key=product['key'])
                            product_transaction.live_stack_products = live_stock_product
                        product_transaction.save()
                    if pos_transaction.paid:
                        if pos_transaction.live_stock == False:
                            product_transaction = ProductsTransactions.objects.filter(transaction=pos_transaction,
                                                                                      trash=False,
                                                                                      product__isnull=False).first()
                            if product_transaction:
                                pos_allocation_weight_for_product(product_transaction.product)
                        else:
                            product_transaction = ProductsTransactions.objects.filter(transaction=pos_transaction,
                                                                                      trash=False,
                                                                                      live_stack_products__isnull=False).first()
                            if product_transaction:
                                cooperative_warehousing(product_transaction.live_stack_products)
                                rancher_warehousing(pos_transaction)

            chat_ids = list(
                User_Bale.objects.filter(trash=False, super_admin=True).values_list('chat_id',
                                                                                    flat=True).distinct())
            if pos_transaction.pos:
                chat_id_list = chat_ids + list(
                    User_Bale.objects.filter(rasadyar_user=pos_transaction.pos.user, trash=False).values_list(
                        'chat_id',
                        flat=True).distinct())
            else:
                chat_id_list = []
            send_transaction(pos_transaction, chat_id_list)
            return Response(serializer.data, status=status.HTTP_200_OK)
        except Exception as e:
            error_message = str(e)
            error_title = e.__class__.__name__
            error_traceback = traceback.format_exc()
            print(error_message)
            print(error_title)
            print(error_traceback)

            return Response(
                {
                    "result": "خطای سرور داخلی رخ داده است. لطفا بعدا تلاش کنید.",
                    "error_message": error_message,
                    "error_title": error_title,
                    "error_traceback": error_traceback,
                },
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

    def update(self, request, *args, **kwargs):
        # timestamp_date = request.data['timestamp_date']
        # transaction_date = datetime.fromtimestamp(timestamp_date)

        try:
            product = RolesProducts.objects.get(key=request.data['product_key'])
        except:
            return Response({"result": "محصول موجود نمی باشد!"}, status=status.HTTP_403_FORBIDDEN)

        pos = POSMachine.objects.get(pos_id=request.data['pos-id'])
        # request.data.pop('timestamp_date')
        request.data.pop('product_key')
        request.data.pop('pos-id')

        try:
            pos_transaction = PosMachineTransactions.objects.get(check_id=request.data['check_id'])
            serializer = self.serializer_class(pos_transaction)
            serializer.update(instance=pos_transaction, validated_data=request.data)
            if pos_transaction.paid:
                pos_allocation_weight_for_product(product)
            return Response(serializer.data, status=status.HTTP_200_OK)


        except:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                pos_transaction = serializer.create(validated_data=request.data)
                # pos_transaction.date = transaction_date
                pos_transaction.product = product
                pos_transaction.pos = pos
                pos_transaction.save()
                if pos_transaction.paid:
                    pos_allocation_weight_for_product(product)

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

    def list(self, request, *args, **kwargs):
        filters = {}
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        price_type = request.GET.get('price_type')
        paid = request.GET.get('paid')
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        filters['trash'] = False
        filters['pos'] = pos

        if date1 and date2:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2

        if price_type:
            filters['price_type__in'] = price_type.split(',')

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

        transactions = PosMachineTransactions.objects.filter(**filters).order_by('-date')
        if 'search' in request.GET and 'value' in request.GET:
            transactions_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=transactions
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=transactions)
                            transactions_list = ps.filter()
                    transactions = [] if len(transactions_list) == 0 else transactions_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(transactions)
            if page is not None:
                serializer = NewPosMachineTransactionsSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = NewPosMachineTransactionsSerializer(transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class LiveStockTransactionViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PosMachineTransactionsSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosMachineTransactionsFilterSet
    filterset_fields = [
        'mobile',
        'natcode',
        'fullname',
    ]

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        state = request.GET.get('state')
        filters = {}
        products = {
            "bran": "سبوس",
            "barley": "جو",
            "soy": "سویا",
            "corn": "ذرت",
            "sheep_concentrate": "کنسانتره گوسفندی",
            "high_cow_concentrate": "کنسانتره گاو شیری پرتولید",
            "medium_cow_concentrate": "کنسانتره گاو شیری متوسط",
            "fattening_calf_concentrate": "کنسانتره گوساله پرواری",
        }
        product = products[request.GET.get('name')]
        if state:
            if state == 'paid':
                filters['paid'] = True
            elif state == 'unpaid':
                filters['paid'] = False
            else:
                pass

        cooperative_key = request.GET.get('cooperative_key')
        if role in ('LiveStockProvinceJahad', 'Union'):
            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, trash=False).values_list('transaction__id',
                                                                                                flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).order_by('-date')

            else:
                transactions = PosMachineTransactions.objects.filter(trash=False, live_stock=True).order_by('-date')


        elif cooperative_key:
            cooperative = Cooperative.objects.get(key=cooperative_key)
            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, live_stack_products__cooperative=cooperative,
                    trash=False).values_list('transaction__id',
                                             flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).order_by('-date')
            else:

                transactions = PosMachineTransactions.objects.filter(pos__cooperative=cooperative, trash=False,
                                                                     live_stock=True).order_by('-date')



        else:
            cooperative = Cooperative.objects.get(user=user)
            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, live_stack_products__cooperative=cooperative,
                    trash=False).values_list('transaction__id',
                                             flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).order_by('-date')

            else:

                transactions = PosMachineTransactions.objects.filter(pos__cooperative=cooperative, trash=False,
                                                                     live_stock=True).order_by('-date')

        if date1 and date2:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2

        transactions = transactions.filter(**filters).order_by('-date')
        if 'search' in request.GET and 'value' in request.GET:
            transactions_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=transactions
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=transactions)
                            transactions_list = ps.filter()
                    transactions = [] if len(transactions_list) == 0 else transactions_list

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(transactions)
            if page is not None:
                serializer = PosMachineTransactionsForLiveStockSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = PosMachineTransactionsForLiveStockSerializer(transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class LiveStockTransactionDashboeardViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    serializer_class = PosMachineTransactionsSerializer
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    filterset_class = PosMachineTransactionsFilterSet
    filterset_fields = [
        'mobile',
        'natcode',
        'fullname',
    ]

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

        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        state = request.GET.get('state')
        filters = {}
        if state:
            if state == 'paid':
                filters['paid'] = True
            elif state == 'unpaid':
                filters['paid'] = False
            else:
                pass

        products = {
            "bran": "سبوس",
            "barley": "جو",
            "soy": "سویا",
            "corn": "ذرت",
            "sheep_concentrate": "کنسانتره گوسفندی",
            "high_cow_concentrate": "کنسانتره گاو شیری پرتولید",
            "medium_cow_concentrate": "کنسانتره گاو شیری متوسط",
            "fattening_calf_concentrate": "کنسانتره گوساله پرواری",
        }
        product = products[request.GET.get('name')]

        cooperative_key = request.GET.get('cooperative_key')
        if role in ('LiveStockProvinceJahad', 'Union'):
            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, trash=False).values_list('transaction__id',
                                                                                                flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')


            else:

                transactions = PosMachineTransactions.objects.filter(trash=False, paid=True,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')


        elif cooperative_key:
            cooperative = Cooperative.objects.get(key=cooperative_key)
            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, live_stack_products__cooperative=cooperative,
                    trash=False).values_list('transaction__id',
                                             flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')

            else:
                transactions = PosMachineTransactions.objects.filter(pos__cooperative=cooperative, trash=False,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')



        else:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            cooperative = Cooperative.objects.get(user=user)

            if product:
                product_transactions = ProductsTransactions.objects.filter(
                    live_stack_products__parent_product__name=product, live_stack_products__cooperative=cooperative,
                    trash=False).values_list('transaction__id',
                                             flat=True)
                transactions = PosMachineTransactions.objects.filter(id__in=product_transactions, trash=False,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')
            else:
                transactions = PosMachineTransactions.objects.filter(pos__cooperative=cooperative, trash=False,
                                                                     live_stock=True).prefetch_related(
                    'transaction_products_transactions').only('id', 'additional', 'date').order_by('-date')

        if date1 and date2:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()

            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2

        transactions = transactions.filter(**filters).order_by('-date')
        if 'search' in request.GET and 'value' in request.GET:
            transactions_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=transactions
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=transactions)
                            transactions_list = ps.filter()
                    transactions = [] if len(transactions_list) == 0 else transactions_list

        weights_by_transaction = defaultdict(int)
        product_weights = ProductsTransactions.objects.filter(
            trash=False,
            live_stack_products__isnull=False,
            transaction__in=transactions
        ).values(
            'transaction_id'
        ).annotate(
            total_weight=Sum('cur_weight')
        )

        for item in product_weights:
            weights_by_transaction[item['transaction_id']] = item['total_weight'] or 0

        price = transactions.aggregate(total=Sum('price'))[
                    'total'] or 0
        total_cooperative_price = 0
        total_union_price = 0
        total_company_price = 0
        cur_heavy = 0
        cur_light = 0
        weight = 0
        for transaction in transactions:
            total_weight = weights_by_transaction.get(transaction.id, 0)
            additional_data = json.loads(transaction.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 * total_weight
                else:
                    total_company_price += share_price * total_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 += total_weight

        dict_result = {
            'lenTransaction': len(transactions),
            'price': price,
            'totalCooperativePrice': total_cooperative_price,
            'totalUnionPrice': total_union_price,
            'totalCompanyPrice': total_company_price,
            'curHeavy': cur_heavy,
            'curLight': cur_light,
            'curWeight': weight,
        }

        return Response(dict_result, status=status.HTTP_200_OK)


class PosAllocationTransactionsViewSet(viewsets.ModelViewSet):
    queryset = PosAllocationTransactions.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosAllocationTransactionsSerializer
    pagination_class = CustomPagination

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

        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        paid = request.GET.get('paid')
        if date1:
            filters = {
                'date__date__gte': date1,
                'date__date__lte': date2,
                'trash': False,
            }
        else:
            filters = {
                'trash': False,
            }
        if paid:
            filters['paid'] = paid

        transactions = PosAllocationTransactions.objects.filter(**filters).order_by('-date')
        if 'page_size' in request.GET:

            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(transactions)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        timestamp_date = request.data['timestamp_date']
        transaction_date = datetime.fromtimestamp(timestamp_date)
        pos = POSMachine.objects.get(pos_id=request.data['pos-id'])
        allocation = StewardAllocation.objects.get(key=request.data['allocation_key'])
        request.data.pop('timestamp_date')
        request.data.pop('allocation_key')
        request.data.pop('pos-id')

        try:
            allocation_transaction = PosAllocationTransactions.objects.get(check_id=request.data['check_id'])
            serializer = self.serializer_class(allocation_transaction)
            serializer.update(instance=allocation_transaction, validated_data=request.data)
            if allocation_transaction.paid:
                allocation_calculate_price(allocation)
            return Response(serializer.data, status=status.HTTP_200_OK)


        except:
            serializer = self.serializer_class(data=request.data)
            if serializer.is_valid():
                allocation_transaction = serializer.create(validated_data=request.data)
                allocation_transaction.date = transaction_date
                allocation_transaction.pos = pos
                allocation_transaction.allocation = allocation
                allocation_transaction.save()
                if allocation_transaction.paid:
                    allocation_calculate_price(allocation)
                return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class BroadcastPriceViewset(viewsets.ModelViewSet):
    queryset = BroadcastPrice.objects.all()
    permission_classes = [AllowAny]
    serializer_class = BroadcastPriceSerializer

    def list(self, request, *args, **kwargs):
        price = BroadcastPrice.objects.filter(trash=False).first()

        serializer = self.serializer_class(price)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        kill_house_price = 0
        steward_price = 0
        guild_price = 0
        price = BroadcastPrice.objects.filter(trash=False).first()
        # approved_price = ApprovedPrice.objects.filter(trash=False).first()
        # if request.data['active'] == True:
        #     if approved_price.approved == False:
        #         return Response({"result":"ابتدا در استان قیمت مصوب مرغ زنده رو در استان فعال کنید !"},status=status.HTTP_403_FORBIDDEN)
        parent_product = NewProduct.objects.get(trash=False)
        parent_product.approved_price_status = request.data['active']
        if 'kill_house_price' in request.data.keys():
            parent_product.approved_price = int(request.data['kill_house_price'])
            kill_house_price = int(request.data['kill_house_price'])
            steward_price = int(request.data['steward_price'])
            guild_price = int(request.data['guild_price'])
        parent_product.save()
        roles_products_thread = threading.Thread(target=change_roles_products_state,
                                                 args=(
                                                     request.data['active'], kill_house_price, steward_price,
                                                     guild_price))

        roles_products_thread.start()

        serializer = self.serializer_class(price)
        serializer.update(instance=price, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class NewPosBroadcastPriceViewset(viewsets.ModelViewSet):
    queryset = BroadcastPrice.objects.all()
    permission_classes = [AllowAny]
    serializer_class = BroadcastPriceSerializer

    def list(self, request, *args, **kwargs):
        price = BroadcastPrice.objects.filter(trash=False).first()
        allow = AllowRegisterCodeForStewardAllocation.objects.filter(trash=False).first()
        steward_free_sale = AllowRegisterCodeForStewardFreeSaleBarInformation.objects.filter(trash=False).first()
        kill_free_sale = AllowRegisterCodeForKillHouseFreeSaleBarInformation.objects.filter(trash=False).first()

        result = {
            "active": price.active,
            "kill_house_price": int(price.kill_house_price),
            "steward_price": int(price.steward_price),
            "guild_price": int(price.guild_price),
            "kill_house_in_province_allocation_register_code": allow.active,
            "steward_in_province_allocation_register_code": allow.active,
            "kill_house_free_sale_register_code": kill_free_sale.active,
            "steward_free_sale_register_code": steward_free_sale.active,
        }

        return Response(result, status=status.HTTP_200_OK)


class OutProvinceSaleLimitationViewset(viewsets.ModelViewSet):
    queryset = OutProvinceSaleLimitation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = OutProvinceSaleLimitationSerializer

    def list(self, request, *args, **kwargs):
        limitation = OutProvinceSaleLimitation.objects.filter(trash=False).first()

        serializer = self.serializer_class(limitation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        limitation = BroadcastPrice.objects.filter(trash=False).first()
        serializer = self.serializer_class(limitation)
        serializer.update(instance=limitation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PosBroadcastPriceViewset(viewsets.ModelViewSet):
    queryset = BroadcastPrice.objects.all()
    permission_classes = [AllowAny]
    serializer_class = BroadcastPriceSerializer

    def list(self, request, *args, **kwargs):
        price = BroadcastPrice.objects.filter(trash=False).first()
        type = request.GET.get('type')
        if type:
            if type in ('KillHouse_Steward', 'KillHouse_Guild'):
                price_amount = price.kill_house_price
                approved_price_status = False if price.active == False else True

            elif type in (
                    'KillHouse_KillHouse', 'Steward_Steward', 'Steward_KillHouse', 'Guild_KillHouse', 'Guild_Guild',
                    'Guild_Steward'):
                price_amount = price.guild_price
                approved_price_status = False

            else:
                price_amount = price.steward_price
                approved_price_status = False if price.active == False else True
        else:
            price_amount = price.guild_price
            approved_price_status = False

        result = {
            "price": int(price_amount),
            # "approved_price_status": approved_price_status,
            "approved_price_status": False,
        }

        return Response(result, status=status.HTTP_200_OK)


class ParentCompanyViewSet(viewsets.ModelViewSet):
    queryset = ParentCompany.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ParentCompanySerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            parent_company = SystemUserProfile.objects.get(user=request.user, trash=False).parent_company_user.first()

            serializer = self.serializer_class(parent_company)
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityGuildViewSet(viewsets.ModelViewSet):
    queryset = CityGuild.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityGuildSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            city_guild = SystemUserProfile.objects.get(user=request.user, trash=False).city_guild_user.first()

            serializer = self.serializer_class(city_guild)
            return Response(serializer.data, status=status.HTTP_200_OK)


class CityGuildForSubSectorViewSet(viewsets.ModelViewSet):
    queryset = CityGuild.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityGuildForSubSectorSerializer

    def list(self, request, *args, **kwargs):
        city_guilds = CityGuild.objects.filter(trash=False)
        serializer = self.serializer_class(city_guilds, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class CityGuildForSubSectorTransactionsViewSet(viewsets.ModelViewSet):
    queryset = CityGuild.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityGuildForSubsectorTransactionSerializer

    def list(self, request, *args, **kwargs):
        city_guilds = CityGuild.objects.filter(trash=False)
        serializer = self.serializer_class(city_guilds, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class CityGuildWageDashboardViewSet(viewsets.ModelViewSet):
    queryset = CityGuild.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CityGuildSerializer

    def list(self, request, *args, **kwargs):
        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 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__isnull=False, calculate_status=True,
                                                           temporary_trash=False, temporary_deleted=False,
                                                           receiver_state='accepted', date__date__gte=date1,
                                                           date__date__lte=date2)
            transactions = PosMachineTransactions.objects.filter(paid=True, trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2)
            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild__isnull=False,
                                                                    date__date__gte=date1, date__date__lte=date2)
        else:
            allocations = StewardAllocation.objects.filter(trash=False, to_guilds__isnull=False, calculate_status=True,
                                                           temporary_trash=False, temporary_deleted=False,
                                                           receiver_state='accepted')
            transactions = PosMachineTransactions.objects.filter(paid=True, trash=False)
            sub_transactions = SubSectorTransactions.objects.filter(trash=False, city_guild__isnull=False)
        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 Response(result, status=status.HTTP_200_OK)


class TotalCitySubSectorWageDashboardViewSet(viewsets.ModelViewSet):
    queryset = ProvinceOperator.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceOperatorSerializer

    def list(self, request, *args, **kwargs):
        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_sell_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-sell', trash=False).first().amount

        kill_houses = KillHouse.objects.filter(out_province=False, trash=False).order_by('id')

        poultries = Poultry.objects.filter(trash=False, city_operator__isnull=False).order_by('id')
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            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,
                                                             has_wage=True, wage_pay=True, poultry__in=poultries,
                                                             temporary_deleted=False, send_date__date__gte=date1,
                                                             send_date__date__lte=date2)
            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,
                                                                        kill_request__recive_date__date__gte=date1,
                                                                        kill_request__recive_date__date__lte=date2).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_request__recive_date__date__gte=date1,
                kill_request__recive_date__date__lte=date2
            )
            difference_requests = BarDifferenceRequest.objects.filter(kill_house__in=kill_houses, trash=False,
                                                                      state='accepted', acceptor_date__date__gte=date1,
                                                                      acceptor_date__date__lte=date2)
            city_operator_deposit = SubSectorTransactions.objects.filter(trash=False, date__date__gte=date1,
                                                                         date__date__lte=date2)
        else:
            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,
                                                             has_wage=True, wage_pay=True, poultry__in=poultries,
                                                             temporary_deleted=False)

            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
            )
            difference_requests = BarDifferenceRequest.objects.filter(kill_house__in=kill_houses, trash=False,
                                                                      state='accepted')

            city_operator_deposit = SubSectorTransactions.objects.filter(trash=False)
        hatchings = PoultryHatching.objects.filter(poultry__in=poultries, killed_quantity__gt=0, trash=False).order_by(
            'poultry')

        hatching_list1 = hatchings.filter(
            pk__in=province_kill_requests.values_list('province_request__poultry_request__hatching', flat=True),
            poultry__in=poultries, killed_quantity__gt=0, trash=False).values_list('id', flat=True)
        hatching_list2 = hatchings.filter(
            pk__in=kill_house_requests.values_list('province_request__poultry_request__hatching', flat=True),
            poultry__in=poultries, killed_quantity__gt=0, trash=False).values_list('id', flat=True)
        hatching_list3 = hatchings.filter(pk__in=poultry_requests.values_list('hatching', flat=True),
                                          poultry__in=poultries, killed_quantity__gt=0, trash=False).values_list('id',
                                                                                                                 flat=True)
        total_hatching_list = chain(hatching_list1, hatching_list2, hatching_list3)
        hatchings = hatchings.filter(pk__in=total_hatching_list)

        total_province_live_weight = province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
                                         'total'] or 0
        total_province_live_quantity = province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                                           'total'] or 0
        total_province_live_weight += kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0
        total_province_live_quantity += kill_house_requests.aggregate(total=Sum('accepted_real_quantity'))['total'] or 0

        total_province_live_weight += \
            difference_requests.aggregate(total=Sum('weight'))['total'] or 0

        total_province_carcasses_weight = total_province_live_weight * 0.75
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
        else:
            date1 = None
            date2 = None

        total_pure_province_carcasses_weight = total_province_carcasses_weight - get_difference_carcasses_weight(
            kill_houses, date1, date2)
        # return Response(total_pure_province_carcasses_weight)
        internal_total_pure_province_carcasses_weight = (
                                                            (
                                                                    total_pure_province_carcasses_weight / total_province_carcasses_weight) if total_province_carcasses_weight > 0 else 0) * total_province_carcasses_weight
        external_total_pure_province_carcasses_weight = total_province_carcasses_weight - internal_total_pure_province_carcasses_weight

        total_pure_province_carcasses_price = internal_total_pure_province_carcasses_weight * province_live_wage_amount
        total_out_selling_province_carcasses_price = external_total_pure_province_carcasses_weight * free_sell_carcesses_weight_amount

        hatching_quantity = hatchings.aggregate(total=Sum('quantity'))[
                                'total'] or 0
        poultry_requests = poultry_requests.filter(hatching__id__in=hatching_list3)
        out_province_poultry_request_quantity = poultry_requests.aggregate(total=Sum('quantity'))[
                                                    'total'] or 0
        out_province_poultry_request_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                                                  'total'] or 0

        union_out_province_poultry_request_amount = poultry_requests.aggregate(total=Sum('union_share'))[
                                                        'total'] or 0

        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

        union_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                         share_type__en_name='union').first().percent / 100
        union_province_kill_request_wage = total_pure_province_carcasses_price * union_province_kill_request_percent
        union_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * union_free_sell_carcasses_percent

        city_percent_province_kill_request = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='province-kill-request').first().percent / 100
        city_percent_out_poultry_request = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='poultry-sell-out-province').first().percent / 100
        city_percent_out_sell_carcasses = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='carcasse-sell').first().percent / 100

        union_total_wage = union_province_kill_request_wage + union_out_province_poultry_request_amount + union_free_sell_carcasses_wage
        hatching_killing_percent = ((
                                            out_province_poultry_request_quantity + total_province_live_quantity) / hatching_quantity if hatching_quantity > 0 else 0) * 100

        city_province_kill_request_wage = union_province_kill_request_wage * city_percent_province_kill_request
        city_out_province_poultry_request = union_out_province_poultry_request_amount * city_percent_out_poultry_request
        city_out_province_sell_carcasses = union_free_sell_carcasses_wage * city_percent_out_sell_carcasses
        city_total_wage = city_province_kill_request_wage + city_out_province_poultry_request + city_out_province_sell_carcasses

        city_deposit = city_operator_deposit.aggregate(total=Sum('amount'))['total'] or 0
        city_total_remain_wage_amount = city_total_wage - city_deposit

        result = {
            "wage_counting_type": wage_counting_type,
            "poultries": len(poultries),
            "hatchings": len(hatchings),
            "hatchings_quantity": hatching_quantity,
            "total_province_kill_requests_quantity": total_province_live_quantity,
            "total_province_kill_requests_weight": total_province_live_weight,
            "total_province_kill_requests_total_carcasses_weight": total_province_carcasses_weight,
            "total_province_kill_requests_carcasses_weight": internal_total_pure_province_carcasses_weight,
            "total_out_selling_province_carcasses_weight": external_total_pure_province_carcasses_weight,
            "out_province_poultry_request_quantity": out_province_poultry_request_quantity,
            "out_province_poultry_request_weight": out_province_poultry_request_weight,
            "total_killed_quantity": out_province_poultry_request_quantity + total_province_live_quantity,
            "hatching_killing_percent": hatching_killing_percent,
            "out_province_poultry_request_amount": union_out_province_poultry_request_amount,
            "total_pure_province_carcasses_price": union_province_kill_request_wage,
            "union_total_out_selling_province_carcasses_price": union_free_sell_carcasses_wage,
            "union_total_wage": union_total_wage,
            "city_total_wage": city_total_wage,
            "city_deposit": city_deposit,
            "city_total_remain_wage_amount": city_total_remain_wage_amount,
        }

        return Response(result, status=status.HTTP_200_OK)


# class TotalCitySubSectortransactionDashboardViewSet(viewsets.ModelViewSet):
#     queryset = ProvinceOperator.objects.all()
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = ProvinceOperatorSerializer
#
#     def list(self, request, *args, **kwargs):
#         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
#         city_percent_province_kill_request = SubSectorPercentageOfWageType.objects.filter(
#             percentage_of_wage_type__wage_type__en_name='province-kill-request').first().percent / 100
#         city_percent_out_poultry_request = SubSectorPercentageOfWageType.objects.filter(
#             percentage_of_wage_type__wage_type__en_name='poultry-sell-out-province').first().percent / 100
#         city_percent_out_sell_carcasses = SubSectorPercentageOfWageType.objects.filter(
#             percentage_of_wage_type__wage_type__en_name='carcasse-sell').first().percent / 100
#
#         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
#         kill_houses = KillHouse.objects.filter(out_province=False, trash=False).order_by('id')
#         poultries = Poultry.objects.filter(trash=False).order_by('id')
#         hatchings = PoultryHatching.objects.filter(poultry__in=poultries, trash=False).order_by('poultry')
#
#         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,
#                                                          temporary_deleted=False, hatching__in=hatchings)
#
#         union_out_province_poultry_request_amount = poultry_requests.aggregate(total=Sum('union_share'))[
#                                                         'total'] or 0
#
#         province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, return_to_province=False,
#                                                                     archive_wage=False,
#                                                                     state__in=('pending', 'accepted'),
#                                                                     temporary_trash=False, temporary_deleted=False,
#                                                                     province_request__poultry_request__hatching__in=hatchings)
#
#         total_province_kill_requests_weight = province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
#                                                   'total'] or 0
#         total_province_live_weight = total_province_kill_requests_weight
#
#         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)
#         total_out_selling_province_carcasses_weight = \
#             kill_house_free_sale_bar_info.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0
#         union_total_out_selling_province_carcasses_price = \
#             kill_house_free_sale_bar_info.aggregate(total=Sum('union_share'))['total'] or 0
#
#         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
#         out_selling_out_carcasses_buying_difference = total_out_selling_province_carcasses_weight - total_out_carcasses_buying_for_pure_province_carcasses_weight if (
#                                                                                                                                                                              total_out_selling_province_carcasses_weight - total_out_carcasses_buying_for_pure_province_carcasses_weight) > 0 else 0
#         total_pure_province_carcasses_weight = total_province_carcasses_weight - out_selling_out_carcasses_buying_difference
#
#         total_pure_province_carcasses_price = total_pure_province_carcasses_weight * province_live_wage_amount
#         union_province_kill_request_wage = int(
#             total_pure_province_carcasses_price * union_province_kill_request_percent)
#         union_total_wage = union_province_kill_request_wage + union_out_province_poultry_request_amount + union_total_out_selling_province_carcasses_price
#
#         city_province_kill_request_wage = union_province_kill_request_wage * city_percent_province_kill_request
#         city_out_province_poultry_request = union_out_province_poultry_request_amount * city_percent_out_poultry_request
#         city_out_province_out_sell_carcasses_price = union_total_out_selling_province_carcasses_price * city_percent_out_sell_carcasses
#         city_total_wage = city_province_kill_request_wage + city_out_province_poultry_request + city_out_province_out_sell_carcasses_price
#         city_operator_deposit = SubSectorTransactions.objects.filter(trash=False)
#         city_deposit = city_operator_deposit.aggregate(total=Sum('amount'))['total'] or 0
#         city_total_remain_wage_amount = city_total_wage - city_deposit
#
#         result = {
#             "wage_counting_type": wage_counting_type,
#             "city_out_province_poultry_request": city_out_province_poultry_request,
#             "city_province_kill_request_wage": city_province_kill_request_wage,
#             "city_out_province_out_sell_carcasses_wage": city_out_province_out_sell_carcasses_price,
#             "union_total_wage": union_total_wage,
#             "city_total_wage": city_total_wage,
#             "city_deposit": city_deposit,
#             "city_total_remain_wage_amount": city_total_remain_wage_amount,
#         }
#
#         return Response(result, status=status.HTTP_200_OK)
class TotalCitySubSectortransactionDashboardViewSet(viewsets.ModelViewSet):
    queryset = ProvinceOperator.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProvinceOperatorSerializer

    def list(self, request, *args, **kwargs):
        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_sell_carcesses_weight_amount = total_wage_type.filter(en_name='carcasse-sell', 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
        )

        total_province_live_weight = province_kill_requests.aggregate(total=Sum('total_killed_weight'))[
                                         'total'] or 0
        total_province_live_quantity = province_kill_requests.aggregate(total=Sum('total_killed_quantity'))[
                                           'total'] or 0
        total_province_live_weight += kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0
        total_province_live_quantity += kill_house_requests.aggregate(total=Sum('accepted_real_quantity'))['total'] or 0

        difference_requests = BarDifferenceRequest.objects.filter(kill_house__in=kill_houses, trash=False,
                                                                  state='accepted')
        total_province_live_weight += \
            difference_requests.aggregate(total=Sum('weight'))['total'] or 0

        total_province_carcasses_weight = total_province_live_weight * 0.75

        total_pure_province_carcasses_weight = total_province_carcasses_weight - get_difference_carcasses_weight(
            kill_houses)

        # return Response(total_pure_province_carcasses_weight)
        internal_total_pure_province_carcasses_weight = (
                                                                total_pure_province_carcasses_weight / total_province_carcasses_weight) * total_province_carcasses_weight
        external_total_pure_province_carcasses_weight = total_province_carcasses_weight - internal_total_pure_province_carcasses_weight

        total_pure_province_carcasses_price = internal_total_pure_province_carcasses_weight * province_live_wage_amount
        total_out_selling_province_carcasses_price = external_total_pure_province_carcasses_weight * free_sell_carcesses_weight_amount

        poultries = Poultry.objects.filter(trash=False, city_operator__isnull=False).order_by('id')
        hatchings = PoultryHatching.objects.filter(poultry__in=poultries, killed_quantity__gt=0, trash=False).order_by(
            'poultry')

        hatching_quantity = hatchings.aggregate(total=Sum('quantity'))[
                                'total'] or 0
        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,
                                                         has_wage=True, wage_pay=True,
                                                         temporary_deleted=False, hatching__in=hatchings)
        out_province_poultry_request_quantity = poultry_requests.aggregate(total=Sum('quantity'))[
                                                    'total'] or 0
        out_province_poultry_request_weight = poultry_requests.aggregate(total=Sum(F('quantity') * F('Index_weight')))[
                                                  'total'] or 0

        union_out_province_poultry_request_amount = poultry_requests.aggregate(total=Sum('union_share'))[
                                                        'total'] or 0

        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

        union_free_sell_carcasses_percent = percentages_wage_type.filter(wage_type__en_name='carcasse-sell',
                                                                         share_type__en_name='union').first().percent / 100
        union_province_kill_request_wage = total_pure_province_carcasses_price * union_province_kill_request_percent
        union_free_sell_carcasses_wage = total_out_selling_province_carcasses_price * union_free_sell_carcasses_percent

        city_percent_province_kill_request = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='province-kill-request').first().percent / 100
        city_percent_out_poultry_request = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='poultry-sell-out-province').first().percent / 100
        city_percent_out_sell_carcasses = SubSectorPercentageOfWageType.objects.filter(
            percentage_of_wage_type__wage_type__en_name='carcasse-sell').first().percent / 100

        union_total_wage = union_province_kill_request_wage + union_out_province_poultry_request_amount + union_free_sell_carcasses_wage
        hatching_killing_percent = ((
                                            out_province_poultry_request_quantity + total_province_live_quantity) / hatching_quantity) * 100

        city_province_kill_request_wage = union_province_kill_request_wage * city_percent_province_kill_request
        city_out_province_poultry_request = union_out_province_poultry_request_amount * city_percent_out_poultry_request
        city_out_province_sell_carcasses = union_free_sell_carcasses_wage * city_percent_out_sell_carcasses
        city_total_wage = city_province_kill_request_wage + city_out_province_poultry_request + city_out_province_sell_carcasses
        city_operator_deposit = SubSectorTransactions.objects.filter(trash=False)
        city_deposit = city_operator_deposit.aggregate(total=Sum('amount'))['total'] or 0
        city_total_remain_wage_amount = city_total_wage - city_deposit

        result = {
            "wage_counting_type": wage_counting_type,
            "city_out_province_poultry_request": city_out_province_poultry_request,
            "city_province_kill_request_wage": city_province_kill_request_wage,
            "city_out_province_out_sell_carcasses_wage": city_out_province_sell_carcasses,
            "union_total_wage": union_total_wage,
            "city_total_wage": city_total_wage,
            "city_deposit": city_deposit,
            "city_total_remain_wage_amount": city_total_remain_wage_amount,
        }

        return Response(result, status=status.HTTP_200_OK)


class SubSectorTransactionsViewSet(viewsets.ModelViewSet):
    queryset = SubSectorTransactions.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = SubSectorTransactionsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = SubSectorTransactionsFilterSet
    filterset_fields = [
        'city_operator__user__first_name',
        'city_operator__user__last_name',
        'city_operator__user__fullname',
        'city_operator__user__mobile',
        'city_operator__user__city__name',
        'from_account',
        'to_account',

    ]

    def create(self, request, *args, **kwargs):
        operator = None
        vet = None
        guild = None
        role_type = request.data['role_type']
        if role_type == 'vet':
            vet = Vet.objects.get(key=request.data['role_key'], trash=False)

        elif role_type == 'guild':
            guild = CityGuild.objects.get(key=request.data['role_key'], trash=False)
        else:
            operator = CityOperator.objects.get(key=request.data['role_key'], trash=False)
        request.data.pop('role_type')
        request.data.pop('role_key')
        image = request.data['image']
        request.data.pop('image')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            transaction = serializer.create(validated_data=request.data)
            transaction.image = send_image_to_server(image)
            if operator:
                transaction.city_operator = operator

            elif guild:
                transaction.city_guild = guild

            else:
                transaction.vet = vet

            transaction.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors)

    def list(self, request, *args, **kwargs):
        role_type = request.GET['type']
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            if role_type == 'city':
                operator_transactions = SubSectorTransactions.objects.filter(date__date__gte=date1,
                                                                             date__date__lte=date2,
                                                                             city_operator__isnull=False,
                                                                             trash=False).order_by('-date')
            elif role_type == 'vet':
                operator_transactions = SubSectorTransactions.objects.filter(date__date__gte=date1,
                                                                             date__date__lte=date2,
                                                                             vet__isnull=False,
                                                                             trash=False).order_by('-date')
            else:
                operator_transactions = SubSectorTransactions.objects.filter(date__date__gte=date1,
                                                                             date__date__lte=date2,
                                                                             city_guild__isnull=False,
                                                                             trash=False).order_by('-date')


        else:
            if role_type == 'city':
                operator_transactions = SubSectorTransactions.objects.filter(city_operator__isnull=False,
                                                                             trash=False).order_by('-date')

            elif role_type == 'vet':
                operator_transactions = SubSectorTransactions.objects.filter(vet__isnull=False, trash=False).order_by(
                    '-date')
            else:
                operator_transactions = SubSectorTransactions.objects.filter(city_guild__isnull=False,
                                                                             trash=False).order_by('-date')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(operator_transactions)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(operator_transactions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        transaction = SubSectorTransactions.objects.get(key=request.data['transaction_key'], trash=False)
        if 'image' in request.data.keys():
            if request.data['image'] != None or request.data['image'] != "":
                transaction.image = send_image_to_server(request.data['image'])
                transaction.save()

                request.data.pop('image')
        request.data.pop('transaction_key')
        serializer = self.serializer_class(transaction)
        serializer.update(instance=transaction, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        transaction = SubSectorTransactions.objects.get(key=request.GET["transaction_key"], trash=False)
        transaction.trash = True
        transaction.save()
        return Response({"result": "با موفقیت حذف شد."}, status=status.HTTP_200_OK)


class PosSegmentationViewSet(viewsets.ModelViewSet):
    queryset = PosSegmentation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosSegmentationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosSegmentationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name'
    ]

    def create(self, request, *args, **kwargs):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        guild = Guilds.objects.get(id=pos.guild.id, trash=False)
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        request.data.pop('product_key')
        if product.total_remain_weight < request.data['weight']:
            return Response({"result": "موجودی انبار کمتر از وزن وارد شده است!"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            segmentation = serializer.create(validated_data=request.data)
            segmentation.guild = guild
            segmentation.product = product
            segmentation.date = datetime.now()
            segmentation.save()
            guild_steward_product_segmentation(product)
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device, trash=False)
        segmentations = PosSegmentation.objects.filter(guild=pos.guild,
                                                       date__date__gte=date1,
                                                       date__date__lte=date2,
                                                       trash=False).order_by('-date')

        if 'search' in request.GET and 'value' in request.GET:
            segmentation_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=segmentations
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=segmentations)
                            segmentation_list = ps.filter()
                    segmentations = [] if len(segmentation_list) == 0 else segmentation_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(segmentations)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(segmentations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.data['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت ویرایش به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(segmentation)
        serializer.update(instance=segmentation, validated_data=request.data)
        guild_steward_product_segmentation(segmentation.product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.GET['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت حذف به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        product = segmentation.product
        segmentation.trash = True
        segmentation.save()
        guild_steward_product_segmentation(product)

        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class NewPosSegmentationViewSet(viewsets.ModelViewSet):
    queryset = PosSegmentation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PosSegmentationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosSegmentationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name'
    ]

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

        pos = POSMachine.objects.get(pos_id=request.data['pos-id'], trash=False)
        guild = None
        kill_house = None
        quota = None
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        if pos.guild:
            guild = product.guild
        else:
            kill_house = product.kill_house
            quota = request.data['quota']
        to_guild = None
        if 'guild_key' in request.data.keys():
            to_guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')

        request.data.pop('product_key')
        if kill_house:
            kill_house_total_input_warehouse_governmental_weight = kill_house.total_input_warehouse_governmental_weight
            kill_house_total_input_warehouse_free_weight = kill_house.total_input_warehouse_free_weight
            if request.data['sale_type'] == 'free':
                quota = request.data['quota']
                if quota == 'governmental':
                    if not kill_house.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            if quota == 'governmental':
                if kill_house.total_input_warehouse_governmental_weight < (
                        kill_house.total_selling_warehouse_governmental_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if kill_house.total_input_warehouse_free_weight < (
                        kill_house.total_selling_warehouse_free_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                segmentation_sale_type = request.data['sale_type']
                if kill_house.governmental_selling_permission:
                    if segmentation_sale_type == 'free':
                        if not kill_house.free_sale_form_governmental_quota:
                            if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                    else:
                        if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if kill_house.total_commitment_segmentation_governmental_weight > 0:
                    if kill_house.total_segmentation_governmental_weight + request.data[
                        'weight'] > kill_house.total_commitment_segmentation_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if kill_house.free_selling_permission:
                    if kill_house.total_commitment_selling_in_province_free_weight > kill_house.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_commitment_segmentation_free_weight > 0:
                    if kill_house.total_segmentation_free_weight + request.data[
                        'weight'] > kill_house.total_commitment_segmentation_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

        else:
            if request.data['sale_type'] == 'free':
                quota = request.data['quota']
                if quota == 'governmental':
                    if not guild.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            if quota == 'governmental':
                if guild.total_input_warehouse_governmental_weight < (
                        guild.total_selling_warehouse_governmental_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if guild.total_input_warehouse_free_weight < (
                        guild.total_selling_warehouse_free_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                segmentation_sale_type = request.data['sale_type']
                if guild.governmental_selling_permission:
                    if segmentation_sale_type == 'free':
                        if not guild.free_sale_form_governmental_quota:
                            if guild.total_commitment_selling_in_province_governmental_weight > guild.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                    else:
                        if guild.total_commitment_selling_in_province_governmental_weight > guild.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if guild.total_commitment_segmentation_governmental_weight > 0:
                    if guild.total_segmentation_governmental_weight + request.data[
                        'weight'] > guild.total_commitment_segmentation_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if guild.free_selling_permission:
                    if guild.total_commitment_selling_in_province_free_weight > guild.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if guild.total_commitment_segmentation_free_weight > 0:
                    if guild.total_segmentation_free_weight + request.data[
                        'weight'] > guild.total_commitment_segmentation_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

        if product.total_remain_weight < request.data['weight']:
            return Response({"result": "موجودی انبار کمتر از وزن وارد شده است!"}, status=status.HTTP_403_FORBIDDEN)

        now_time = datetime.now().time()

        production_date = datetime.strptime(str(request.data['production_date']), '%Y-%m-%d').date()
        production_date = datetime(year=production_date.year, month=production_date.month, day=production_date.day,
                                   hour=now_time.hour,
                                   minute=now_time.minute,
                                   second=now_time.second)
        request.data.pop('production_date')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            segmentation = serializer.create(validated_data=request.data)
            if guild:
                segmentation.guild = guild
            else:

                segmentation.kill_house = kill_house
            if to_guild:
                segmentation.to_guild = to_guild

            segmentation.product = product
            segmentation.date = datetime.now()
            segmentation.production_date = production_date
            segmentation.save()
            guild_steward_product_segmentation(product)

            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        pos = POSMachine.objects.get(pos_id=request.GET['pos-id'], trash=False)
        if role:

            if date1:

                if role == 'KillHouse':
                    segmentations = PosSegmentation.objects.filter(kill_house=pos.kill_house,
                                                                   date__date__gte=date1,
                                                                   date__date__lte=date2,
                                                                   trash=False)
                else:
                    segmentations = PosSegmentation.objects.filter(guild=pos.guild,
                                                                   date__date__gte=date1,
                                                                   date__date__lte=date2,
                                                                   trash=False)
            else:
                if role == 'KillHouse':
                    segmentations = PosSegmentation.objects.filter(kill_house=pos.kill_house,
                                                                   trash=False)
                else:
                    segmentations = PosSegmentation.objects.filter(guild=pos.guild,
                                                                   trash=False)
        else:
            segmentations = PosSegmentation.objects.filter(trash=False)

        if 'search' in request.GET and 'value' in request.GET:
            segmentation_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=segmentations
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=segmentations)
                            segmentation_list = ps.filter()
                    segmentations = [] if len(segmentation_list) == 0 else segmentation_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(segmentations)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(segmentations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.data['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت ویرایش به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        if segmentation.kill_house:
            if segmentation.quota == 'governmental':
                if segmentation.kill_house.total_input_warehouse_governmental_weight < (
                        (segmentation.kill_house.total_selling_warehouse_governmental_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if segmentation.kill_house.total_input_warehouse_free_weight < (
                        (segmentation.kill_house.total_selling_warehouse_free_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)

        else:
            if segmentation.quota == 'governmental':
                if segmentation.guild.total_input_warehouse_governmental_weight < (
                        (segmentation.guild.total_selling_warehouse_governmental_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if segmentation.guild.total_input_warehouse_free_weight < (
                        (segmentation.guild.total_selling_warehouse_free_weight - segmentation.weight) + request.data[
                    'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(segmentation)
        serializer.update(instance=segmentation, validated_data=request.data)
        guild_steward_product_segmentation(segmentation.product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.GET['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت حذف به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        product = segmentation.product
        segmentation.trash = True
        segmentation.save()
        # if segmentation.guild:
        guild_steward_product_segmentation(product)

        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class AppSegmentationViewSet(viewsets.ModelViewSet):
    queryset = PosSegmentation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = AppSegmentationSerializer
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosSegmentationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name',
        'to_guild__user__first_name',
        'to_guild__user__last_name',
        'to_guild__user__fullname',
        'to_guild__user__mobile',
        'to_guild__guilds_name'
    ]

    def create(self, request, *args, **kwargs):
        guild = None
        kill_house = None
        quota = None
        dispenser = request.data.pop('dispenser',None)
        representative = request.data.pop('representative',None)
        product = RolesProducts.objects.get(key=request.data['product_key'], trash=False)
        if product.guild:
            guild = product.guild
        else:
            kill_house = product.kill_house
            quota = request.data['quota']
        to_guild = None
        if 'guild_key' in request.data.keys():
            to_guild = Guilds.objects.get(key=request.data['guild_key'], trash=False)
            request.data.pop('guild_key')

        request.data.pop('product_key')
        if kill_house:
            kill_house_total_input_warehouse_governmental_weight = kill_house.total_input_warehouse_governmental_weight
            kill_house_total_input_warehouse_free_weight = kill_house.total_input_warehouse_free_weight
            if request.data['sale_type'] == 'free':
                quota = request.data['quota']
                if quota == 'governmental':
                    if not kill_house.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            if quota == 'governmental':
                if kill_house.total_input_warehouse_governmental_weight < (
                        kill_house.total_selling_warehouse_governmental_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if kill_house.total_input_warehouse_free_weight < (
                        kill_house.total_selling_warehouse_free_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                segmentation_sale_type = request.data['sale_type']
                if kill_house.governmental_selling_permission:
                    if segmentation_sale_type == 'free':
                        if not kill_house.free_sale_form_governmental_quota:
                            if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                    else:
                        if kill_house.total_commitment_selling_in_province_governmental_weight > kill_house.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if kill_house.total_commitment_segmentation_governmental_weight > 0:
                    if kill_house.total_segmentation_governmental_weight + request.data[
                        'weight'] > kill_house.total_commitment_segmentation_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if kill_house.free_selling_permission:
                    if kill_house.total_commitment_selling_in_province_free_weight > kill_house.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if kill_house.total_commitment_segmentation_free_weight > 0:
                    if kill_house.total_segmentation_free_weight + request.data[
                        'weight'] > kill_house.total_commitment_segmentation_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

        else:
            if request.data['sale_type'] == 'free':
                quota = request.data['quota']
                if quota == 'governmental':
                    if not guild.free_sale_form_governmental_quota:
                        return Response({"result": "مجاز به فروش آزاد از انبار دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            if quota == 'governmental':
                if guild.total_input_warehouse_governmental_weight < (
                        guild.total_selling_warehouse_governmental_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش دولتی بیشتر از ورودی دولتی انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if guild.total_input_warehouse_free_weight < (
                        guild.total_selling_warehouse_free_weight + request.data['weight']):
                    return Response({"result": "مجاز به فروش آزاد بیشتر از ورودی آزاد انبار نمیباشید!"},
                                    status=status.HTTP_403_FORBIDDEN)
            if quota == 'governmental':
                segmentation_sale_type = request.data['sale_type']
                if guild.governmental_selling_permission:
                    if segmentation_sale_type == 'free':
                        if not guild.free_sale_form_governmental_quota:
                            if guild.total_commitment_selling_in_province_governmental_weight > guild.total_selling_in_province_governmental_weight:
                                return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                                status=status.HTTP_403_FORBIDDEN)
                    else:
                        if guild.total_commitment_selling_in_province_governmental_weight > guild.total_selling_in_province_governmental_weight:
                            return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                            status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش دولتی نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)
                if guild.total_commitment_segmentation_governmental_weight > 0:
                    if guild.total_segmentation_governmental_weight + request.data[
                        'weight'] > guild.total_commitment_segmentation_governmental_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

            else:
                if guild.free_selling_permission:
                    if guild.total_commitment_selling_in_province_free_weight > guild.total_selling_in_province_free_weight:
                        return Response({"result": "ابتدا تعهد داخل استان رو تکمیل کنید!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "مجاز به فروش آزاد نمیباشید!"}, status=status.HTTP_403_FORBIDDEN)

                if guild.total_commitment_segmentation_free_weight > 0:
                    if guild.total_segmentation_free_weight + request.data[
                        'weight'] > guild.total_commitment_segmentation_free_weight:
                        return Response({"result": "به دلیل بیشتر از وزن تعهد مجاز به فروش دولتی نمیباشید!"},
                                        status=status.HTTP_403_FORBIDDEN)

        if product.total_remain_weight < request.data['weight']:
            return Response({"result": "موجودی انبار کمتر از وزن وارد شده است!"}, status=status.HTTP_403_FORBIDDEN)

        now_time = datetime.now().time()

        production_date = datetime.strptime(str(request.data['production_date']), '%Y-%m-%d').date()
        production_date = datetime(year=production_date.year, month=production_date.month, day=production_date.day,
                                   hour=now_time.hour,
                                   minute=now_time.minute,
                                   second=now_time.second)
        request.data.pop('production_date')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            segmentation = serializer.create(validated_data=request.data)
            if guild:
                segmentation.guild = guild
            else:

                segmentation.kill_house = kill_house
            if to_guild:
                segmentation.to_guild = to_guild

            segmentation.product = product
            segmentation.date = datetime.now()
            segmentation.production_date = production_date
            segmentation.dispenser = dispenser if dispenser else None
            segmentation.representative = representative if representative else None
            segmentation.save()
            guild_steward_product_segmentation(product)

            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        steward_key = request.GET.get('steward_key')
        user = SystemUserProfile.objects.get(user=request.user)
        if role:
            if steward_key:
                if steward_key == 'all':
                    if role in ['CityJahad']:
                        segmentations = PosSegmentation.objects.filter(guild__isnull=False, guild__user__city=user.city,
                                                                       date__date__gte=date1,
                                                                       date__date__lte=date2,
                                                                       trash=False)
                    else:
                        segmentations = PosSegmentation.objects.filter(guild__isnull=False,
                                                                       date__date__gte=date1,
                                                                       date__date__lte=date2,
                                                                       trash=False)
                else:
                    guild = Guilds.objects.get(key=steward_key, trash=False)
                    if role in ['CityJahad']:
                        segmentations = PosSegmentation.objects.filter(guild=guild, guild__user__city=user.city,
                                                                       date__date__gte=date1,
                                                                       date__date__lte=date2,
                                                                       trash=False)
                    else:

                        segmentations = PosSegmentation.objects.filter(guild=guild,
                                                                       date__date__gte=date1,
                                                                       date__date__lte=date2,
                                                                       trash=False)
            else:
                if role == 'KillHouse':
                    kill_house = KillHouse.objects.filter(kill_house_operator__user=user).first()
                    segmentations = PosSegmentation.objects.filter(kill_house=kill_house,
                                                                   date__date__gte=date1,
                                                                   date__date__lte=date2,
                                                                   trash=False)
                else:
                    guild = Guilds.objects.get(user=user, active=True, trash=False)
                    segmentations = PosSegmentation.objects.filter(guild=guild,
                                                                   date__date__gte=date1,
                                                                   date__date__lte=date2,
                                                                   trash=False)
        else:
            guild = Guilds.objects.get(user=user, active=True, trash=False)
            segmentations = PosSegmentation.objects.filter(guild=guild,
                                                           date__date__gte=date1,
                                                           date__date__lte=date2,
                                                           trash=False)

        if 'search' in request.GET and 'value' in request.GET:
            segmentation_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=segmentations
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=segmentations)
                            segmentation_list = ps.filter()
                    segmentations = [] if len(segmentation_list) == 0 else segmentation_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(segmentations)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(segmentations, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.data['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت ویرایش به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        if segmentation.kill_house:
            if segmentation.quota == 'governmental':
                if segmentation.kill_house.total_input_warehouse_governmental_weight < (
                        (segmentation.kill_house.total_selling_warehouse_governmental_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if segmentation.kill_house.total_input_warehouse_free_weight < (
                        (segmentation.kill_house.total_selling_warehouse_free_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)

        else:
            if segmentation.quota == 'governmental':
                if segmentation.guild.total_input_warehouse_governmental_weight < (
                        (segmentation.guild.total_selling_warehouse_governmental_weight - segmentation.weight) +
                        request.data[
                            'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده دولتی می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if segmentation.guild.total_input_warehouse_free_weight < (
                        (segmentation.guild.total_selling_warehouse_free_weight - segmentation.weight) + request.data[
                    'weight']):
                    return Response({"result": "وزن وارد شده بیشتر از باقی مانده آزاد می باشد!"},
                                    status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(segmentation)
        serializer.update(instance=segmentation, validated_data=request.data)
        guild_steward_product_segmentation(segmentation.product)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        now = datetime.now().date()
        segmentation = PosSegmentation.objects.get(key=request.GET['key'])
        if now != segmentation.date.date():
            return Response({"result": "مهلت حذف به اتمام رسیده است !"}, status=status.HTTP_403_FORBIDDEN)
        product = segmentation.product
        segmentation.trash = True
        segmentation.save()
        # if segmentation.guild:
        guild_steward_product_segmentation(product)

        return Response({"result": "بار با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class SegmentationDashboardViewSet(APIView):
    permission_classes = [TokenHasReadWriteScope]
    filterset_class = PosSegmentationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name',
        'to_guild__user__first_name',
        'to_guild__user__last_name',
        'to_guild__user__fullname',
        'to_guild__user__mobile',
        'to_guild__guilds_name'
    ]

    def get(self, request):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        role = request.GET.get('role')
        steward_key = request.GET.get('steward_key')
        user = SystemUserProfile.objects.get(user=request.user)
        if role:
            if role == 'KillHouse':
                filters = {'trash': False, 'kill_house__kill_house_operator__user': user}
            else:
                if steward_key:
                    if steward_key == 'all':
                        filters = {'trash': False, 'guild__isnull': False}
                    else:
                        filters = {'trash': False, 'guild__key': steward_key}

                else:
                    filters = {'trash': False, 'guild__user': user}


        else:
            filters = {'trash': False, 'guild__user': user}
        if date1:
            filters['date__date__gte'] = date1
            filters['date__date__lte'] = date2
        segmentations = PosSegmentation.objects.filter(**filters)
        if 'search' in request.GET and 'value' in request.GET:
            segmentation_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=segmentations
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=segmentations)
                            segmentation_list = ps.filter()
                    segmentations = [] if len(segmentation_list) == 0 else segmentation_list

        segmentations_aggregates = segmentations.aggregate(
            total_count=Count('id'),
            total_self_count=Count('id', filter=Q(to_guild__isnull=True)),
            total_other_count=Count('id', filter=Q(to_guild__isnull=False)),
            total_weight=Sum('weight'),
            total_self_weight=Sum('weight', filter=Q(to_guild__isnull=True)),
            total_other_weight=Sum('weight', filter=Q(to_guild__isnull=False)),

        )

        result = {
            "total_count": segmentations_aggregates['total_count'] or 0,
            "total_weight": segmentations_aggregates['total_weight'] or 0,
            "total_self_count": segmentations_aggregates['total_self_count'] or 0,
            "total_self_weight": segmentations_aggregates['total_self_weight'] or 0,
            "total_other_count": segmentations_aggregates['total_other_count'] or 0,
            "total_other_weight": segmentations_aggregates['total_other_weight'] or 0

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


class GuildsForPosMachineTransactionsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    serializer_class = GuildsPosMachineForTransactionsNewSerializer
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = GuildsForPostationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name'
    ]

    # def get_filtered_guilds(self, request):
    #     if 'date1' in request.GET and 'date2' in request.GET:
    #         date1 = datetime.strptime(request.GET['date1'], '%Y-%m-%d').date()
    #         date2 = datetime.strptime(request.GET['date2'], '%Y-%m-%d').date()
    #
    #         guilds = Guilds.objects.filter(
    #             id__in=PosMachineTransactions.objects.filter(
    #                 trash=False,
    #                 date__date__gte=date1,
    #                 date__date__lte=date2,
    #                 pos__guild__isnull=False,
    #                 paid=True
    #             ).values_list('pos__guild__id', flat=True).distinct()
    #         ).annotate(
    #             transaction_count=Count(
    #                 'guild_pos__roles_products_pos_transactions',
    #                 filter=Q(guild_pos__roles_products_pos_transactions__trash=False) &
    #                        Q(guild_pos__roles_products_pos_transactions__paid=True)
    #             )
    #         ).order_by('-transaction_count')
    #
    #     else:
    #         guilds = Guilds.objects.annotate(
    #             transaction_count=Count(
    #                 'guild_pos__roles_products_pos_transactions',
    #                 filter=Q(guild_pos__roles_products_pos_transactions__trash=False) &
    #                        Q(guild_pos__roles_products_pos_transactions__paid=True)
    #             )
    #         ).order_by('-transaction_count')
    #
    #     return guilds

    def get_filtered_guilds(self, request):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')

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

            guilds = Guilds.objects.filter(
                Q(
                    id__in=PosMachineTransactions.objects.filter(
                        trash=False,
                        date__date__gte=date1,
                        date__date__lte=date2,
                        pos__guild__isnull=False,
                        paid=True
                    ).values_list('pos__guild__id', flat=True)
                ) |
                Q(
                    id__in=StewardAllocation.objects.filter(
                        date__date__gte=date1,
                        date__date__lte=date2,
                        to_guilds__isnull=False,
                        to_cold_house__isnull=True,
                        temporary_trash=False,
                        trash=False,
                        calculate_status=True
                    ).values_list('to_guilds__id', flat=True)
                )
            ).annotate(
                transaction_count=Count(
                    'guild_pos__roles_products_pos_transactions',
                    filter=Q(
                        guild_pos__roles_products_pos_transactions__trash=False,
                        guild_pos__roles_products_pos_transactions__paid=True,
                        guild_pos__roles_products_pos_transactions__date__date__gte=date1,
                        guild_pos__roles_products_pos_transactions__date__date__lte=date2
                    ),
                    distinct=True
                )
            ).order_by('-transaction_count')

        else:
            guilds = Guilds.objects.filter(
                Q(
                    id__in=PosMachineTransactions.objects.filter(
                        trash=False,
                        paid=True,
                        pos__guild__isnull=False
                    ).values_list('pos__guild__id', flat=True)
                ) |
                Q(
                    id__in=StewardAllocation.objects.filter(
                        to_guilds__isnull=False,
                        to_cold_house__isnull=True,
                        temporary_trash=False,
                        trash=False,
                        calculate_status=True
                    ).values_list('to_guilds__id', flat=True)
                )
            ).annotate(
                transaction_count=Count(
                    'guild_pos__roles_products_pos_transactions',
                    filter=Q(
                        guild_pos__roles_products_pos_transactions__trash=False,
                        guild_pos__roles_products_pos_transactions__paid=True
                    ),
                    distinct=True
                )
            ).order_by('-transaction_count')

        return guilds

    def apply_search_filter(self, request, guilds):
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                guilds = guilds.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )
        return guilds

    def list(self, request, *args, **kwargs):
        guilds = self.get_filtered_guilds(request)
        guilds = self.apply_search_filter(request, guilds)

        serializer = self.serializer_class(guilds, many=True, context={'request': request})
        data = serializer.data

        data = sorted(data, key=lambda x: x['transaction']['total_carcasses_weight'], reverse=True)

        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(data)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(data)

        return Response(data, status=status.HTTP_200_OK)


# class GuildsForPosMachineTransactionsViewSet(viewsets.ModelViewSet):
#     queryset = Guilds.objects.all()
#     serializer_class = GuildsPosMachineForTransactionsNewSerializer
#     permission_classes = [TokenHasReadWriteScope]
#     filter_backends = [DjangoFilterBackend]
#     pagination_class = CustomPagination
#     filterset_class = GuildsForPostationFilterSet
#     filterset_fields = [
#         'guild__user__first_name',
#         'guild__user__last_name',
#         'guild__user__fullname',
#         'guild__user__mobile',
#         'guild__guilds_name'
#     ]
#
#     def _get_date_range(self, request):
#         d1 = request.GET.get('date1')
#         d2 = request.GET.get('date2')
#         if d1 and d2:
#             try:
#                 date1 = datetime.strptime(d1, '%Y-%m-%d').date()
#                 date2 = datetime.strptime(d2, '%Y-%m-%d').date()
#                 return date1, date2
#             except ValueError:
#                 return None, None
#         return None, None
#
#     def get_filtered_guild_ids(self, request):
#         date1, date2 = self._get_date_range(request)
#
#         if date1 and date2:
#             pos_qs = PosMachineTransactions.objects.filter(
#                 trash=False,
#                 date__date__gte=date1,
#                 date__date__lte=date2,
#                 pos__guild__isnull=False,
#                 paid=True
#             ).values_list('pos__guild__id', flat=True)
#             alloc_qs = StewardAllocation.objects.filter(
#                 date__date__gte=date1,
#                 date__date__lte=date2,
#                 to_guilds__isnull=False,
#                 to_cold_house__isnull=True,
#                 temporary_trash=False,
#                 trash=False,
#                 receiver_state='accepted',
#                 calculate_status=True
#             ).values_list('to_guilds__id', flat=True)
#         else:
#             pos_qs = PosMachineTransactions.objects.filter(
#                 trash=False, paid=True, pos__guild__isnull=False
#             ).values_list('pos__guild__id', flat=True)
#             alloc_qs = StewardAllocation.objects.filter(
#                 to_guilds__isnull=False,
#                 to_cold_house__isnull=True,
#                 temporary_trash=False,
#                 trash=False,
#                 receiver_state='accepted',
#                 calculate_status=True
#             ).values_list('to_guilds__id', flat=True)
#
#         guild_ids_from_related = set(pos_qs) | set(alloc_qs)
#         guilds_base = Guilds.objects.filter(id__in=guild_ids_from_related).order_by('id')
#
#         if request.GET.get('search') == 'filter' and request.GET.get('value') not in ["", "undefined", None]:
#             value = request.GET.get('value')
#             for f in self.filterset_fields:
#                 query = QueryDict(f'{f}__contains={value}')
#                 qs = self.filterset_class(data=query, queryset=guilds_base).qs
#                 if qs.exists():
#                     guilds_base = qs
#                     break
#
#         return list(guilds_base.values_list('id', flat=True)), guilds_base
#
#     def list(self, request, *args, **kwargs):
#         guild_ids, guilds_qs_for_pagination = self.get_filtered_guild_ids(request)
#         guild_id_set = set(guild_ids)
#
#         date1, date2 = self._get_date_range(request)
#
#         pos_filter = Q(trash=False, paid=True, pos__guild__id__in=guild_ids, pos__guild__isnull=False)
#         if date1 and date2:
#             pos_filter &= Q(date__date__gte=date1, date__date__lte=date2)
#         pos_values = PosMachineTransactions.objects.filter(pos_filter).values(
#             'pos__guild__id', 'price', 'weight'
#         )
#
#         seg_filter = Q(trash=False, guild__id__in=guild_ids)
#         if date1 and date2:
#             seg_filter &= Q(date__date__gte=date1, date__date__lte=date2)
#         seg_values = PosSegmentation.objects.filter(seg_filter).values('guild__id', 'weight')
#
#         alloc_filter = Q(trash=False, calculate_status=True, to_guilds__isnull=False,
#                          receiver_state='accepted', to_cold_house__isnull=True, temporary_trash=False)
#         if date1 and date2:
#             alloc_filter &= Q(date__date__gte=date1, date__date__lte=date2)
#         alloc_values = StewardAllocation.objects.filter(alloc_filter).values('to_guilds__id', 'real_weight_of_carcasses')
#
#         product_values = RolesProducts.objects.filter(trash=False, guild__id__in=guild_ids).values(
#             'guild__id', 'name', 'total_remain_weight'
#         ).order_by('guild__id')
#
#         agg = {gid: {
#             "len_transaction": 0,
#             "total_price": 0,
#             "pos_weight": 0,
#             "pos_segmentation_weight": 0,
#             "allocation_carcass_weight": 0,
#             "product": None,
#             "total_remain_weight": 0,
#         } for gid in guild_ids}
#
#         for p in pos_values:
#             gid = p.get('pos__guild__id')
#             if gid in guild_id_set:
#                 agg_g = agg[gid]
#                 agg_g['len_transaction'] += 1
#                 agg_g['total_price'] += p.get('price') or 0
#                 agg_g['pos_weight'] += p.get('weight') or 0
#
#         for s in seg_values:
#             gid = s.get('guild__id')
#             if gid in guild_id_set:
#                 agg[gid]['pos_segmentation_weight'] += s.get('weight') or 0
#
#         for a in alloc_values:
#             gid = a.get('to_guilds__id')
#             if gid in guild_id_set:
#                 agg[gid]['allocation_carcass_weight'] += a.get('real_weight_of_carcasses') or 0
#
#         seen_products = set()
#         for pr in product_values:
#             gid = pr.get('guild__id')
#             if gid in guild_id_set and gid not in seen_products:
#                 agg[gid]['product'] = pr.get('name') or '-'
#                 agg[gid]['total_remain_weight'] = pr.get('total_remain_weight') or 0
#                 seen_products.add(gid)
#
#         precomputed = {}
#         for gid, v in agg.items():
#             pos_weight_kg = round((v['pos_weight'] or 0) / 1000, 1)
#             seg_weight_kg = round((v['pos_segmentation_weight'] or 0) / 1000, 1)
#             total_carcasses = v['allocation_carcass_weight'] or 0
#
#             precomputed[gid] = {
#                 "len_transaction": v['len_transaction'],
#                 "total_price": v['total_price'],
#                 "real_allocated_weight": round(pos_weight_kg + seg_weight_kg, 1),
#                 "product": v['product'] or '-',
#                 "total_carcasses_weight": total_carcasses,
#                 "total_remain_weight": v['total_remain_weight'] or 0,
#             }
#
#         page = self.paginate_queryset(guilds_qs_for_pagination)
#         to_serialize = page if page is not None else guilds_qs_for_pagination
#         context = {'request': request, 'precomputed_transactions': precomputed}
#         serializer = self.get_serializer(to_serialize, many=True, context=context)
#
#         if page is not None:
#             return self.get_paginated_response(serializer.data)
#         return Response(serializer.data, status=status.HTTP_200_OK)


class PosMachineTransactionsForInsPectionViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    serializer_class = PosMachineTransactionsForInspectionSerializer
    permission_classes = [AllowAny]
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosMachineTransactionsFilterSet
    filterset_fields = [
        'pos__guild__user__first_name',
        'pos__guild__user__last_name',
        'pos__guild__user__fullname',
        'pos__guild__user__mobile',
        'pos__guild__guilds_name'
    ]

    def list(self, request, *args, **kwargs):
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()

            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            transactions = PosMachineTransactions.objects.filter(trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2, pos__key=request.GET['pos_key'],
                                                                 paid=True)
        else:
            transactions = PosMachineTransactions.objects.filter(trash=False, pos__key=request.GET['pos_key'],
                                                                 paid=True)

        if 'search' in request.GET and 'value' in request.GET:
            transactions_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=transactions
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=transactions)
                            transactions_list = ps.filter()
                    transactions = [] if len(transactions_list) == 0 else transactions_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(transactions)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        ser_data = self.serializer_class(transactions, many=True).data
        return Response(ser_data, status=status.HTTP_200_OK)


class DetailsOfGuildsForPosMachineTransactionsViewSet(viewsets.ModelViewSet):
    queryset = PosMachineTransactions.objects.all()
    serializer_class = PosMachineTransactionsForInspectionSerializer
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = PosMachineTransactionsFilterSet
    filterset_fields = [
        'pos__guild__user__first_name',
        'pos__guild__user__last_name',
        'pos__guild__user__fullname',
        'pos__guild__user__mobile',
        'pos__guild__guilds_name'
    ]

    def list(self, request, *args, **kwargs):
        guild = Guilds.objects.get(key=request.GET['key'])
        if 'date1' in request.GET:
            date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
            date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
            transactions = PosMachineTransactions.objects.filter(trash=False, date__date__gte=date1,
                                                                 date__date__lte=date2, pos__guild=guild,
                                                                 paid=True).order_by('-date')
        else:
            transactions = PosMachineTransactions.objects.filter(trash=False, pos__guild=guild,
                                                                 paid=True).order_by('-date')

        if 'search' in request.GET and 'value' in request.GET:
            transactions_list = []
            if request.GET['search'] == 'filter':
                if request.GET['value'] != "" and request.GET['value'] != 'undefined':
                    for item in self.filterset_fields:
                        query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
                        if (self.filterset_class(
                                data=query,
                                queryset=transactions
                        )
                        ).filter():
                            ps = self.filterset_class(data=query, queryset=transactions)
                            transactions_list = ps.filter()
                    transactions = [] if len(transactions_list) == 0 else transactions_list
        if 'page' in request.GET:
            page_size = request.query_params.get('page_size', None)
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(transactions)
            if page is not None:
                serializer = self.serializer_class(page, many=True)
                return self.get_paginated_response(serializer.data)
        ser_data = self.serializer_class(transactions, many=True).data
        return Response(ser_data, status=status.HTTP_200_OK)


class DashboardOfGuildsForPosMachineTransactionsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    serializer_class = GuildsPosMachineForTransactionsSerializer
    permission_classes = [TokenHasReadWriteScope]
    filter_backends = [DjangoFilterBackend]
    pagination_class = CustomPagination
    filterset_class = GuildsForPostationFilterSet
    filterset_fields = [
        'guild__user__first_name',
        'guild__user__last_name',
        'guild__user__fullname',
        'guild__user__mobile',
        'guild__guilds_name'
    ]

    def get_filtered_guilds(self, request):
        if 'date1' in request.GET and 'date2' in request.GET:
            date1 = datetime.strptime(request.GET['date1'], '%Y-%m-%d').date()
            date2 = datetime.strptime(request.GET['date2'], '%Y-%m-%d').date()
            guilds = Guilds.objects.filter(
                id__in=PosMachineTransactions.objects.filter(
                    trash=False,
                    date__date__gte=date1,
                    date__date__lte=date2,
                    pos__guild__isnull=False,
                    paid=True
                ).values_list('pos__guild__id', flat=True).distinct()
            )
        else:
            guilds = Guilds.objects.filter(
                trash=False
            )

        return guilds

    def apply_search_filter(self, request, guilds):
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                guilds = guilds.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )
        return guilds

    def list(self, request, *args, **kwargs):
        guilds = self.get_filtered_guilds(request)
        guilds = self.apply_search_filter(request, guilds)
        pos = PosMachineTransactions.objects.filter(trash=False, pos__guild__in=guilds, paid=True)
        total_price = pos.aggregate(total=Sum('price'))[
                          'total'] or 0

        result = {
            'lenGuild': len(guilds),
            "totalPrice": total_price,
            "lenPosTransaction": len(pos),
        }

        return Response(result, status=status.HTTP_200_OK)


class CooperativeWarehouseDashboardViewSet(viewsets.ModelViewSet):
    queryset = Cooperative.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CooperativeForAllocationsReportSerializer
    filterset_class = CooperativeFilterSet
    pagination_class = CustomPagination

    def list(self, request, *args, **kwargs):
        cooperatives = Cooperative.objects.filter(trash=False).order_by('id')
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if search != 'undefined' and search.strip():
                cooperatives = cooperatives.filter(
                    build_query(self.filterset_class.Meta.fields, search)
                )
        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)
        page = self.paginate_queryset(cooperatives)
        if page is not None:
            serializer = self.serializer_class(page, many=True, context={'request': request})
            return self.get_paginated_response(serializer.data)
        serializer = self.serializer_class(cooperatives, many=True, context={'request': request})
        return Response(serializer.data, status=status.HTTP_200_OK)


class DashboardForCooperativeWarehouseViewSet(viewsets.ModelViewSet):
    queryset = Cooperative.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CooperativeForAllocationsReportSerializer
    filterset_class = CooperativeFilterSet
    pagination_class = CustomPagination

    def list(self, request, *args, **kwargs):
        cooperatives = Cooperative.objects.filter(trash=False).order_by('id')
        value = request.GET.get('value')
        search = request.GET.get('search')
        products = {
            "bran": "سبوس",
            "barley": "جو",
            "soy": "سویا",
            "corn": "ذرت",
            "sheep_concentrate": "کنسانتره گوسفندی",
            "high_cow_concentrate": "کنسانتره گاو شیری پرتولید",
            "medium_cow_concentrate": "کنسانتره گاو شیری متوسط",
            "fattening_calf_concentrate": "کنسانتره گوساله پرواری",
        }
        name = products[request.GET.get('name')]
        if value and search == 'filter':
            if search != 'undefined' and search.strip():
                cooperatives = cooperatives.filter(
                    build_query(self.filterset_class.Meta.fields, search)
                )
        cooperative_roles = LiveStockRolseProduct.objects.filter(cooperative__in=cooperatives,
                                                                 parent_product__name=name)
        product_transactions = ProductsTransactions.objects.filter(live_stack_products__in=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.aggregate(
            total=Sum('total_weight')
        )['total'] or 0
        total_receipt_weight = cooperative_roles.aggregate(
            total=Sum('total_receipt_weight')
        )['total'] or 0
        total_weight = cooperative_roles.aggregate(
            total=Sum('total_weight')
        )['total'] or 0
        total_remain_weight = cooperative_roles.aggregate(
            total=Sum('total_remain_weight')
        )['total'] or 0
        total_allocated_weight = cooperative_roles.aggregate(
            total=Sum('total_allocated_weight')
        )['total'] or 0
        result_dict = {
            "totalTransactionsPrice": transactions_amount,
            "totalTransactionsWeight": total_transactions_weight,
            "transactions": len(transactions),
            "totalWeight": total_weight,
            "totalReceiptWeight": total_receipt_weight,
            "totalAllocatedWeight": total_allocated_weight,
            "totalRemainWeight": total_remain_weight,
        }
        return Response(result_dict, status=status.HTTP_200_OK)


class PriceConfirmationViewset(viewsets.ModelViewSet):
    queryset = PriceConfirmation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PriceConfirmationSerializer

    def list(self, request, *args, **kwargs):
        price_confirmation = PriceConfirmation.objects.filter(trash=False).first()

        serializer = self.serializer_class(price_confirmation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        price_confirmation = PriceConfirmation.objects.filter(trash=False).first()
        serializer = self.serializer_class(price_confirmation)
        serializer.update(instance=price_confirmation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class CompanyBeneficiaryAccountViewset(viewsets.ModelViewSet):
    queryset = CompanyBeneficiaryAccount.objects.all()
    permission_classes = [AllowAny]
    serializer_class = CompanyBeneficiaryAccountSerializer

    def create(self, request, *args, **kwargs):
        # accounts = CompanyBeneficiaryAccount.objects.filter(trash=False)
        # percents = accounts.aggregate(total=Sum('percent'))['total'] or 0
        # if request.data['percent'] + percents > 100:
        #     return Response({"result": " مجموع درصد ها نباید از 100 بیشتر شود !"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            account = serializer.create(validated_data=request.data)
            return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        accounts = CompanyBeneficiaryAccount.objects.filter(trash=False).order_by('id')
        serializer = self.serializer_class(accounts, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        account = CompanyBeneficiaryAccount.objects.get(key=request.data['account_key'])
        request.data.pop('account_key')
        if 'percent' in request.data:
            percent = request.data['percent']
            accounts = CompanyBeneficiaryAccount.objects.filter(trash=False).exclude(id=account.id)
            percents = accounts.aggregate(total=Sum('percent'))['total'] or 0
            # if percent + percents > 100:
            #     return Response({"result": " مجموع درصد ها نباید از 100 بیشتر شود !"}, status=status.HTTP_403_FORBIDDEN)
        serializer = self.serializer_class(account)
        serializer.update(instance=account, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        account = CompanyBeneficiaryAccount.objects.get(key=request.GET['account_key'])
        account.trash = True
        account.save()
        return Response({"result": " با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


from django.db.models.expressions import RawSQL, Subquery

from django.db.models.fields import IntegerField, BooleanField, TextField


def filter_json_text_field(*args, **kwargs):
    queryset = PosMachineTransactions.objects.filter(
        ~Q(additional=''),
        additional__isnull=False,
        additional__regex=r'^\s*{'
    )

    for i in range(0, len(args), 2):
        if i + 1 >= len(args):
            break

        key = args[i]
        value = args[i + 1]

        if isinstance(value, bool):
            field_type = BooleanField()
        elif isinstance(value, int):
            field_type = IntegerField()
        else:
            field_type = TextField()

        annotation_name = f'json_{key}'
        queryset = queryset.annotate(**{
            annotation_name: RawSQL(
                """
                jsonb_extract_path_text(additional::jsonb, %s)
                """,
                [key]
            )
        }).annotate(
            **{f'cast_{key}': Cast(F(annotation_name), field_type)}
        ).filter(**{f'cast_{key}': value})

    return queryset.filter(**kwargs)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def get_T(request):
    results = filter_json_text_field(
        'cur_heavy', 2,
        'isTaavoni', True,
        'ownerNatcode', '4060603546'
    )

    return Response(results.count())


class ReportPosDeviceSessionViewSet(viewsets.ModelViewSet):
    queryset = POSDeviceSession.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = POSDeviceSessionForCompanySerializer
    pagination_class = CustomPagination
    filterset_class = POSDeviceSessionForCompanyFilterSet

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.filter(trash=False, user=request.user).first()
        company = request.GET.get('company')
        role_check = request.GET['role']
        filters = {"trash": False}
        if role_check in ('AdminX', 'SuperAdmin', 'Jahad', 'GuildRoom'):
            if company and company is not None:
                filters['key'] = request.GET['company']

        else:
            filters['user'] = user
        pos_company = PosCompany.objects.filter(**filters)

        pos = POSMachine.objects.filter(pos_company__in=pos_company, trash=False).annotate(
            session_count=Count('pos_device_session', filter=Q(pos_device_session__trash=False))
        ).filter(session_count__gt=0)
        pos_sessions = POSDeviceSession.objects.filter(pos__in=pos, trash=False)
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                pos_sessions = pos_sessions.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)
        page = self.paginate_queryset(pos_sessions)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = POSDeviceSessionForCompanySerializer(pos_sessions, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ProteinGuildViewSet(viewsets.ModelViewSet):
    queryset = ProteinGuild.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = ProteinGuildSerializer

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            guild = user.protein_guild_user.all()
            serializer = self.serializer_class(guild[0])
            return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_all_pos_company(request):
    pos_company = PosCompany.objects.filter(trash=False).order_by('id')
    ser_data = PosCompanySerializer(pos_company, many=True)
    return Response(ser_data.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@csrf_exempt
@permission_classes([AllowAny])
def get_all_pos_version(request):
    pos_version = PosDeviceVersion.objects.filter(trash=False).order_by('-code').values_list('code',
                                                                                             flat=True).distinct()
    pos_company = PosCompany.objects.all().order_by('en_name')
    ser_data = PosCompanyForPosVersionSerializer(pos_company, many=True)
    result_dict = {
        'pos_version': pos_version,
        'company': ser_data.data
    }
    return Response(result_dict, 200)


class GetOnePosVersionViewSet(viewsets.ModelViewSet):
    queryset = PosDeviceVersion.objects.all()
    serializer_class = PosDeviceVersionForOneCompanySerializer
    permission_classes = [AllowAny]

    def list(self, request, *args, **kwargs):
        pos_version = PosDeviceVersion.objects.filter(trash=False, code=int(request.GET['code'])).order_by(
            'company__en_name')
        ser_data = self.serializer_class(pos_version, many=True)

        return Response(ser_data.data, 200)

    def update(self, request, *args, **kwargs):
        key = request.data.pop('key')
        query = self.queryset.get(key=key)
        serializer = self.serializer_class(query)
        serializer.update(instance=query, validated_data=request.data)
        return Response(serializer.data, 200)

    def create(self, request, *args, **kwargs):
        company_id = request.data.pop('id', None)
        if company_id:
            company = PosCompany.objects.get(id=int(company_id))

        else:
            company = PosCompany.objects.filter(trash=False, en_name='Unknown').first()

        if self.queryset.filter(trash=False, company=company, code=int(request.data['code'])).exists():
            return Response({"result": f'برای {company.name} نسخه {request.data["code"]} قبلا ثبت شده است.'})  # noqa
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            pos_device_version = serializer.create(validated_data=request.data)
            pos_device_version.company = company
            pos_device_version.save()
            return Response({"result": f"با موفقیت ثبت شد."}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)


class CommonlyUsedViewSet(viewsets.ModelViewSet):
    queryset = CommonlyUsed.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = CommonlyUsedSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = CommonlyUsedFilterSet
    filterset_fields = [
        'kill_house__name',
        'kill_house__kill_house_operator__user__last_name',
        'kill_house__kill_house_operator__user__first_name',
        'kill_house__kill_house_operator__user__fullname',
        'kill_house__kill_house_operator__user__mobile',
        'guild__guilds_name',
        'guild__user__last_name',
        'guild__user__first_name',
        'guild__user__fullname',
        'guild__user__mobile',

    ]

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        role = request.data.pop('role')
        guilds = Guilds.objects.filter(key__in=request.data.pop('guild_key_list'), trash=False)

        serializer = self.serializer_class(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors)

        validated_data = serializer.validated_data
        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).first()

            commonly_used_instances = [
                CommonlyUsed(
                    **validated_data,
                    kill_house=kill_house,
                    guild=guild
                )
                for guild in guilds
            ]

        else:
            steward = Guilds.objects.get(user=user, steward=True, trash=False)

            commonly_used_instances = [
                CommonlyUsed(
                    **validated_data,
                    steward=steward,
                    guild=guild
                )
                for guild in guilds
            ]

        CommonlyUsed.objects.bulk_create(commonly_used_instances)

        return Response({"result": "با موفقیت ثبت شد."}, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(trash=False, user=request.user)
        role = request.GET.get('role')
        today = datetime.now().date()
        allocations = None
        commonly_used = None

        if role == 'KillHouse':
            kill_house = KillHouse.objects.filter(
                kill_house_operator__user=user, trash=False
            ).first()

            allocations = StewardAllocation.objects.filter(
                Q(to_steward__isnull=False) | Q(to_guilds__isnull=False),
                kill_house=kill_house,
                date__date=today
            )

            filter_args = {'kill_house': kill_house, 'trash': False}

        else:
            steward = Guilds.objects.get(
                user=user, steward=True, trash=False
            )

            allocations = StewardAllocation.objects.filter(
                Q(to_steward__isnull=False) | Q(to_guilds__isnull=False),
                steward=steward,
                date__date=today
            )

            filter_args = {'steward': steward, 'trash': False}

        excluded_guild_ids = allocations.filter(to_guilds__isnull=False).values_list('to_guilds', flat=True)
        excluded_steward_ids = allocations.filter(to_steward__isnull=False).values_list('to_steward', flat=True)

        commonly_used = CommonlyUsed.objects.filter(**filter_args).exclude(
            Q(guild__in=excluded_guild_ids) | Q(guild__in=excluded_steward_ids)
        )

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(commonly_used)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(commonly_used, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        commonly_used = CommonlyUsed.objects.get(key=request.GET["commonly_used_key"], trash=False)
        commonly_used.trash = True
        commonly_used.save()
        return Response({"result": "با موفقیت حذف شد."}, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def get_all_guilds(request):
    steward = Guilds.objects.filter(trash=False, steward=True).select_related('user').only('key',
                                                                                           'guilds_name',
                                                                                           'user__mobile',
                                                                                           'user__fullname') \
        .order_by('id')
    ser_data = GetAllGuildsSerializer(steward, many=True).data
    return Response(ser_data, status=status.HTTP_200_OK)


class PercentageDropLimitationViewset(viewsets.ModelViewSet):
    queryset = PercentageDropLimitation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = PercentageDropLimitationSerializer

    def list(self, request, *args, **kwargs):
        drop_limitation = PercentageDropLimitation.objects.filter(trash=False).first()

        serializer = self.serializer_class(drop_limitation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        drop_limitation = PercentageDropLimitation.objects.filter(trash=False).first()
        serializer = self.serializer_class(drop_limitation)
        serializer.update(instance=drop_limitation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class UploadImageLimitationViewset(viewsets.ModelViewSet):
    queryset = UploadImageLimitation.objects.all()
    permission_classes = [AllowAny]
    serializer_class = UploadImageLimitationSerializer

    def list(self, request, *args, **kwargs):
        image_limitation = UploadImageLimitation.objects.filter(trash=False).first()

        serializer = self.serializer_class(image_limitation)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        image_limitation = UploadImageLimitation.objects.filter(trash=False).first()
        serializer = self.serializer_class(image_limitation)
        serializer.update(instance=image_limitation, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ApkInfoViewset(viewsets.ModelViewSet):
    queryset = ApkInfo.objects.all()
    permission_classes = [AllowAny]
    serializer_class = ApkInfoSerializer

    def list(self, request, *args, **kwargs):
        apk = ApkInfo.objects.filter(trash=False).first()

        serializer = self.serializer_class(apk)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        apk = ApkInfo.objects.filter(trash=False).first()
        serializer = self.serializer_class(apk)
        serializer.update(instance=apk, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class DirectBuyingVerificationViewset(viewsets.ModelViewSet):
    queryset = DirectBuyingVerification.objects.filter(trash=False)
    permission_classes = [AllowAny]
    serializer_class = DirectBuyingVerificationSerializer

    def get_object(self):
        instance, created = DirectBuyingVerification.objects.get_or_create(
            trash=False)
        return instance

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

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)


class FinePermissionViewset(viewsets.ModelViewSet):
    queryset = FinePermission.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = FinePermissionSerializer

    def list(self, request, *args, **kwargs):
        fines = FinePermission.objects.filter(trash=False).order_by('id')
        serializer = self.serializer_class(fines, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        fine = FinePermission.objects.get(trash=False, key=request.data['key'])
        serializer = self.serializer_class(fine)
        serializer.update(instance=fine, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class ShowMarketRequestViewset(viewsets.ModelViewSet):
    queryset = ShowMarketRequest.objects.filter(trash=False)
    permission_classes = [AllowAny]
    serializer_class = ShowMarketRequestSerializer

    def get_object(self):
        instance, created = ShowMarketRequest.objects.get_or_create(
            trash=False)
        return instance

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

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)


class IndexWeightCategoryViewSet(viewsets.ModelViewSet):
    queryset = IndexWeightCategory.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = IndexWeightCategorySerializer

    def list(self, request, *args, **kwargs):
        index_weight = IndexWeightCategory.objects.filter(trash=False).order_by('id')
        serializer = self.serializer_class(index_weight, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        index_weight = IndexWeightCategory.objects.get(trash=False, key=request.data['key'])
        serializer = self.serializer_class(index_weight)
        serializer.update(instance=index_weight, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class GetAllPoultryForPoultryScienceViewSet(APIView):
    permission_classes = [TokenHasReadWriteScope]

    def get(self, request):
        poultry_science = PoultryScience.objects.filter(trash=False, poultry__isnull=False).values_list('poultry__id',
                                                                                                        flat=True).distinct()

        poultry = Poultry.objects.filter(trash=False).exclude(id__in=poultry_science).select_related('user',
                                                                                                     'address').order_by(
            'id')
        serializer = GetAllPoultryForPoultryScienceSerializer(poultry, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


class PoultryScienceViewSet(viewsets.ModelViewSet):
    queryset = PoultryScience.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryScienceSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = PoultryScienceFilterSet

    def retrieve(self, request, pk=None, *args, **kwargs):
        if 'profile' in request.GET:
            user = SystemUserProfile.objects.get(user=request.user, trash=False)
            poultry_science = user.poultry_science_user.all()
            serializer = self.serializer_class(poultry_science[0])
            return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        query = self.queryset.get(id=request.data['poultry_science_id'])
        query.poultry.set(request.data['poultry'])
        return Response({'result': 'باموفقیت انجام شد.'}, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        query = self.queryset
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if search != 'undefined' and search.strip():
                query = query.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(query)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

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


class PoultryScienceReportViewSet(viewsets.ModelViewSet):
    queryset = PoultryScienceReport.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = PoultryScienceReportSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = PoultryScienceReportFilterSet

    def list(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        query = self.queryset.order_by('-id')
        role = request.GET['role']

        if role == 'PoultryScience':
            query = query.filter(poultry_science__user=user)

        elif role == 'VetFarm':
            vet_farms = VetFarm.objects.filter(vet__user=user, trash=False)
            poultries = Poultry.objects.filter(
                pk__in=vet_farms.values('poultry')
            )
            hatching_ids = PoultryHatching.objects.filter(
                poultry__in=poultries
            ).values_list('id', flat=True)
            query = query.filter(hatching__id__in=hatching_ids)

        elif role == 'CityOperator':
            city_operator = CityOperator.objects.get(user=user, trash=False)
            hatching_ids = PoultryHatching.objects.filter(
                poultry__city_operator=city_operator.unit_name
            ).values_list('id', flat=True)
            query = query.filter(hatching__id__in=hatching_ids)

        elif role == 'CityJahad':
            hatching_ids = PoultryHatching.objects.filter(
                poultry__address__city=user.city
            ).values_list('id', flat=True)
            query = query.filter(hatching__id__in=hatching_ids)

        elif role == 'CityPoultry':
            hatching_ids = PoultryHatching.objects.filter(
                poultry__address__city=user.city
            ).values_list('id', flat=True)
            query = query.filter(hatching__id__in=hatching_ids)

        else:
            query = query.filter(user=user)

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(query)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

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

    def create(self, request, *args, **kwargs):
        user = get_object_or_404(SystemUserProfile, user=request.user, trash=False)
        poultry_science = PoultryScience.objects.filter(trash=False, user=user).first()

        # if poultry_science:
        # if not poultry_science.poultry.exists():
        #     return Response(
        #         {"result": "برای این کارشناس مرغداری ثبت نشده است!"},
        #         status=status.HTTP_403_FORBIDDEN
        #     )

        hatching_id = request.data.get("hatching_id")
        hatching = PoultryHatching.objects.filter(trash=False, id=hatching_id).first()
        # if self.queryset.filter(hatching=hatching).exists():
        #     return Response(
        #         {"result": "برای این واحد قبلا گزارش ثبت شده است!"},
        #         status=status.HTTP_403_FORBIDDEN
        #     )
        if not hatching:
            return Response(
                {"result": "جوجه‌ریزی وجود ندارد!"},
                status=status.HTTP_403_FORBIDDEN
            )

        # دریافت JSON از request
        report_json = request.data.get('json') or request.data.get('report_information')
        if isinstance(report_json, str):
            try:
                report_json = json.loads(report_json)
            except json.JSONDecodeError:
                report_json = None

        poultry_science_report = PoultryScienceReport(
            hatching=hatching,
            poultry_science=poultry_science or None,
            user=user,
            reporter_fullname=user.fullname,
            reporter_mobile=user.mobile,
            reporter_role=request.data.get('role'),
            date=datetime.now(),
            lat=request.data.get('lat', None),
            log=request.data.get('log', None),
            report_information=report_json,
            chicken_age=hatching.chicken_age,
        )

        # files = request.FILES.getlist("file")
        # if not files:
        #     single_file = request.FILES.get("file")
        #     if single_file:
        #         files = [single_file]
        # if files:
        #     poultry_science_report.image = [
        #         send_image_to_server_for_poultry_science(f, f.name) for f in files
        #     ]

        poultry_science_report.save()

        ser_data = self.serializer_class(poultry_science_report)
        return Response(ser_data.data, status=status.HTTP_201_CREATED)


class PoultryAndHatchingForPoultryScience(GenericAPIView):
    permission_classes = [TokenHasReadWriteScope]
    pagination_class = CustomPagination

    def get(self, request):
        type_page = request.GET.get('type')
        hatching_has_report = request.GET.get('report')
        role = request.GET.get('role')
        user = get_object_or_404(SystemUserProfile, user=request.user, trash=False)
        poultry_science = PoultryScience.objects.filter(trash=False, user=user).first()
        if poultry_science:
            poultry = poultry_science.poultry.filter(trash=False)
            hatching = PoultryHatching.objects.filter(
                state='pending',
                allow_hatching='pending',
                archive=False,
                trash=False,
                poultry__in=poultry
            ).order_by('-date', 'poultry')
        else:
            hatching = PoultryHatching.objects.filter(
                state='pending',
                allow_hatching='pending',
                archive=False,
                trash=False,
            ).order_by('-date', 'poultry')

        if type_page == 'farm':

            poultry = poultry_science.poultry.filter(trash=False)
            page_size = request.query_params.get('page_size')
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(poultry)
            if page is not None:
                serializer = PoultryDetailForPoultryScienceSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)
            ser_data = PoultryDetailForPoultryScienceSerializer(poultry, many=True).data
            return Response(ser_data, status=status.HTTP_200_OK)

        elif type_page == 'hatching':
            if hatching_has_report:
                hatching = hatching.exclude(
                    id__in=PoultryScienceReport.objects.filter(trash=False).values_list('hatching__id',
                                                                                        flat=True).distinct())
            if role == 'PoultryScience':
                poultry_science = PoultryScience.objects.filter(user=user, trash=False)
                allowed_poultry_ids = poultry_science.values_list('poultry', flat=True).distinct()
                hatching = hatching.filter(poultry__in=allowed_poultry_ids)

            elif role == 'VetFarm':
                vet_farms = VetFarm.objects.filter(vet__user=user, trash=False)
                poultries = Poultry.objects.filter(
                    pk__in=vet_farms.values('poultry')
                )
                hatching = hatching.filter(
                    poultry__in=poultries
                )
            elif role == 'CityOperator':
                city_operator = CityOperator.objects.get(user=user, trash=False)
                hatching = hatching.filter(
                    poultry__city_operator=city_operator.unit_name
                )
            elif role == 'CityJahad':
                city_jahad = CityJahad.objects.get(user=user, trash=False)
                hatching = hatching.filter(
                    poultry__address__city=city_jahad.address.city
                )
            elif role == 'CityPoultry':
                city_poultry = CityPoultry.objects.get(user=user, trash=False)
                hatching = hatching.filter(
                    poultry__address__city=city_poultry.address.city
                )
            else:
                hatching = hatching

            page_size = request.query_params.get('page_size')
            if page_size:
                self.pagination_class.page_size = int(page_size)

            page = self.paginate_queryset(hatching)
            if page is not None:
                serializer = PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer(page, many=True)
                return self.get_paginated_response(serializer.data)

            ser_data = PoultryHatchingForPoultryAndHatchingForPoultryScienceSerializer(hatching, many=True).data
            return Response(ser_data, status=status.HTTP_200_OK)

        else:
            hatching_aggregate = hatching.aggregate(
                total_quantity=Sum('quantity'),
                total_left_over=Sum('left_over'),
                total_losses=Sum('losses'),
                total_killed_quantity=Sum('killed_quantity'),
            )
            poultry_count = hatching.values_list('poultry', flat=True).distinct()
            result = {
                "farm_count": poultry_count.count(),
                "hatching_count": hatching.count(),
                "hatching_quantity": hatching_aggregate['total_quantity'] or 0,
                "hatching_left_over": hatching_aggregate['total_left_over'] or 0,
                "hatching_losses": hatching_aggregate['total_losses'] or 0,
                "hatching_killed_quantity": hatching_aggregate['total_killed_quantity'] or 0,
                "hatching_max_age": hatching.order_by(
                    '-chicken_age').first().chicken_age if hatching.exists() else None,
                "hatching_min_age": hatching.order_by('chicken_age').first().chicken_age if hatching.exists() else None,
            }
            return Response(result, status=status.HTTP_200_OK)

class AllowRegisterCodeForGuildsViewSet(viewsets.ModelViewSet):
    queryset = AllowRegisterCodeForGuilds.objects.filter(trash=False)
    serializer_class = AllowRegisterCodeForGuildsSerializer
    permission_classes = [TokenHasReadWriteScope]


class StewardAppLoginViewSet(viewsets.ModelViewSet):
    queryset = StewardAppLogin.objects.filter(trash=False)
    serializer_class = StewardAppLoginSerializer
    permission_classes = [AllowAny]

    def create(self, request, *args, **kwargs):
        steward = Guilds.objects.get(user__mobile=request.data['mobile'], trash=False)
        request.data.pop('mobile')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            login = serializer.create(validated_data=request.data)
            login.steward = steward
            login.save()
            return Response({"result": f"با موفقیت ثبت شد."}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)


class GuildsGeneralConfigsViewSet(viewsets.ModelViewSet):
    queryset = GuildsGeneralConfigs.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsGeneralConfigsSerializer

    def list(self, request, *args, **kwargs):
        configs = GuildsGeneralConfigs.objects.filter(trash=False).first()
        serializer = self.serializer_class(configs)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        stewards = Guilds.objects.filter(trash=False, steward=True).order_by('id')
        configs = GuildsGeneralConfigs.objects.filter(trash=False).first()
        serializer = self.serializer_class(configs, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        update_data = serializer.validated_data
        fields_to_update = []
        for field in update_data.keys():
            if hasattr(Guilds, field):
                fields_to_update.append(field)
                for steward in stewards:
                    setattr(steward, field, update_data[field])

        if fields_to_update:
            Guilds.objects.bulk_update(stewards, fields_to_update)

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


class GuildsForGeneralConfigsViewSet(viewsets.ModelViewSet):
    queryset = Guilds.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = GuildsForGeneralConfigsSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsForGeneralConfigsFilterSet

    def list(self, request, *args, **kwargs):
        stewards = Guilds.objects.filter(trash=False, steward=True).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(stewards)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(stewards, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def update(self, request, pk=None, *args, **kwargs):
        steward = Guilds.objects.get(key=request.data['key'])
        serializer = self.serializer_class(steward)
        serializer.update(instance=steward, validated_data=request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)


class StewardSalesInformationViewSet(APIView):
    permission_classes = [TokenHasReadWriteScope]

    def get(self, request):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(user=user, steward=True, active=True, trash=False)
        product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
        archives = WarehouseArchive.objects.filter(Q(steward=steward) | Q(guild=steward), trash=False, warehouse=True)

        guild_steward_allocations = StewardAllocation.objects.filter(
            Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(
                to_steward=steward),
            trash=False, calculate_status=True, warehouse=True, steward_warehouse=True)

        output_steward_allocations = guild_steward_allocations.filter(Q(guilds=steward) | Q(steward=steward))
        input_steward_allocations = guild_steward_allocations.filter(
            Q(to_guilds=steward) | Q(to_steward=steward))

        steward_free_bar_informations = StewardFreeBarInformation.objects.filter(steward=steward,
                                                                                 trash=False,
                                                                                 temporary_trash=False,
                                                                                 temporary_deleted=False,
                                                                                 warehouse=True)
        steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
            steward=steward,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True)

        segmentations = PosSegmentation.objects.filter(guild=steward, trash=False, warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True, trash=False,
                                                           warehouse=True)

        total_input_allocations_governmental_weight = \
            input_steward_allocations.filter(receiver_state='accepted', quota='governmental').aggregate(
                total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_input_allocations_free_weight = \
            input_steward_allocations.filter(receiver_state='accepted', quota='free').aggregate(
                total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_input_free_bar_carcasses_weight = \
            steward_free_bar_informations.aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0
        total_steward_free_sale_bar_carcasses_weight = \
            steward_free_Sale_bar_informations.aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0
        total_steward_free_sale_bar_carcasses_governmental_weight = \
            steward_free_Sale_bar_informations.filter(quota='governmental').aggregate(
                total=Sum('weight_of_carcasses'))[
                'total'] or 0

        total_steward_house_free_sale_bar_carcasses_free_weight = \
            steward_free_Sale_bar_informations.filter(quota='free').aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0

        total_steward_in_province_allocations_weight = \
            output_steward_allocations.aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_steward_in_province_allocations_governmental_weight = \
            output_steward_allocations.filter(quota='governmental').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0
        total_steward_in_province_allocations_free_weight = \
            output_steward_allocations.filter(quota='free').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        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_governmental_weight=Sum('weight',
                                             filter=Q(quota='governmental')),
            archives_free_weight=Sum('weight',
                                     filter=Q(quota='free')),

        )
        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0
        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

        total_governmental_input_weight = total_input_allocations_governmental_weight
        total_free_input_weight = total_input_allocations_free_weight + total_input_free_bar_carcasses_weight
        total_governmental_output_weight = total_steward_free_sale_bar_carcasses_governmental_weight + segmentations_governmental_weight + total_steward_in_province_allocations_governmental_weight + int(
            pos_governmental_allocated_weight / 1000)
        total_free_output_weight = total_steward_house_free_sale_bar_carcasses_free_weight + total_steward_in_province_allocations_free_weight + segmentations_free_weight + int(
            pos_free_allocated_weight / 1000)
        total_governmental_remain_weight = (
                                                   total_governmental_input_weight - total_governmental_output_weight) - archives_governmental_weight
        total_free_remain_weight = (total_free_input_weight - total_free_output_weight) - archives_free_weight

        result = {

            "total_governmental_input_weight": int(total_governmental_input_weight),
            "total_free_input_weight": int(total_free_input_weight),
            "total_governmental_output_weight": int(total_governmental_output_weight),
            "total_free_output_weight": int(total_free_output_weight),
            "total_governmental_remain_weight": int(total_governmental_remain_weight),
            "total_free_remain_weight": int(total_free_remain_weight),
            "total_steward_free_sale_bar_carcasses_weight": int(total_steward_free_sale_bar_carcasses_weight),
            "total_steward_in_province_allocations_weight": int(total_steward_in_province_allocations_weight),
            "segmentations_weight": int(segmentations_weight),
            "total_selling_in_province_governmental_weight": steward.total_selling_in_province_governmental_weight,
            "total_selling_in_province_free_weight": steward.total_selling_in_province_free_weight,
            "total_commitment_selling_in_province_governmental_weight": steward.total_commitment_selling_in_province_governmental_weight,
            "total_commitment_selling_in_province_governmental_remain_weight": steward.total_commitment_selling_in_province_governmental_remain_weight,
            "total_commitment_selling_in_province_free_weight": steward.total_commitment_selling_in_province_free_weight,
            "total_commitment_selling_in_province_free_remain_weight": steward.total_commitment_selling_in_province_free_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_governmental_weight": archives_governmental_weight,
            "archives_free_weight": archives_free_weight,

        }

        return Response(result, status=200)


class ReturnStewardAllocationViewSet(viewsets.ModelViewSet):
    queryset = StewardAllocation.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = StewardAllocationSerializer

    def update(self, request, pk=None, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        allocation = StewardAllocation.objects.get(key=request.data['key'])
        quota = allocation.quota
        if allocation.kill_house:
            if quota == 'governmental':
                if allocation.kill_house.total_remain_warehouse_governmental_weight < allocation.real_weight_of_carcasses:
                    return Response({"result": "باقیمانده وزن دولتی کمتر از تخصیص برگشت داده شده است!"},
                                    status=status.HTTP_403_FORBIDDEN)
            else:
                if allocation.kill_house.total_remain_warehouse_free_weight < allocation.real_weight_of_carcasses:
                    return Response({"result": "باقیمانده وزن آزاد کمتر از تخصیص برگشت داده شده است!"},
                                    status=status.HTTP_403_FORBIDDEN)
        allocation.trash = False
        allocation.return_trash = True
        allocation.returner_trash = user.fullname
        allocation.return_trash_date = datetime.now()
        allocation.save()
        if allocation.seller_type == 'KillHouse':
            kill_house_allocations_product_warehousing(allocation.product)
        else:
            guild_steward_allocations_product_warehousing(allocation.product)
        return Response({"result": "با موفقیت انجام شد!"}, status=status.HTTP_200_OK)


class StewardRequestViewSet(viewsets.ModelViewSet):
    queryset = StewardRequest.objects.filter(trash=False)
    serializer_class = StewardRequestSerializer
    permission_classes = [TokenHasReadWriteScope]

    def create(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(key=request.data['key'])

        request.data.pop('key')
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            steward_request = serializer.create(validated_data=request.data)
            steward_request.steward = steward
            steward_request.registerer = user.fullname
            steward_request.registerer_mobile = user.mobile
            steward_request.save()
            return Response({"result": f"با موفقیت ثبت شد."}, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_403_FORBIDDEN)


class RestrictionCarcassDistributionViewSet(viewsets.ModelViewSet):
    queryset = RestrictionCarcassDistribution.objects.filter(trash=False).order_by('id')
    serializer_class = RestrictionCarcassDistributionSerializer
    permission_classes = [TokenHasReadWriteScope]


class AllowRegisterCodeForKillHouseFreeSaleBarInformationViewSet(viewsets.ModelViewSet):
    queryset = AllowRegisterCodeForKillHouseFreeSaleBarInformation.objects.filter(trash=False)
    serializer_class = AllowRegisterCodeForKillHouseFreeSaleBarInformationSerializer
    permission_classes = [TokenHasReadWriteScope]

    def get_queryset(self):
        return AllowRegisterCodeForKillHouseFreeSaleBarInformation.objects.filter(trash=False)

    def list(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class AllowRegisterCodeForStewardFreeSaleBarInformationViewSet(viewsets.ModelViewSet):
    queryset = AllowRegisterCodeForStewardFreeSaleBarInformation.objects.filter(trash=False)
    serializer_class = AllowRegisterCodeForStewardFreeSaleBarInformationSerializer
    permission_classes = [TokenHasReadWriteScope]

    def get_queryset(self):
        return AllowRegisterCodeForStewardFreeSaleBarInformation.objects.filter(trash=False)

    def list(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class LimitationForDirectPurchaseAndBarInformationViewSet(viewsets.ModelViewSet):
    queryset = LimitationForDirectPurchaseAndBarInformation.objects.filter(trash=False)
    serializer_class = LimitationForDirectPurchaseAndBarInformationSerializer
    permission_classes = [TokenHasReadWriteScope]

    def get_queryset(self):
        return LimitationForDirectPurchaseAndBarInformation.objects.filter(trash=False)

    def list(self, request, *args, **kwargs):
        instance = self.get_queryset().first()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class PosSalesInformationViewSet(APIView):
    permission_classes = [AllowAny]

    def kill_house_info(self, kill_house):
        product = RolesProducts.objects.filter(kill_house=kill_house, trash=False, name='مرغ گرم').first()
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True, trash=False)
        pos_allocated_weight = transactions.aggregate(total=Sum('cur_weight'))['total'] or 0
        pos_governmental_allocated_weight = transactions.filter(price_approved=True).aggregate(total=Sum('cur_weight'))[
                                                'total'] or 0
        pos_free_allocated_weight = transactions.filter(price_approved=False).aggregate(total=Sum('cur_weight'))[
                                        'total'] or 0
        archives = WarehouseArchive.objects.filter(kill_house=kill_house, trash=False, warehouse=True)

        kill_house_requests = KillHouseRequest.objects.filter(
            input_warehouse=kill_house,
            temporary_trash=False,
            temporary_deleted=False,
            trash=False, calculate_status=True, warehouse=True)

        kill_house_free_bar_informations = KillHouseFreeBarInformation.objects.filter(input_warehouse=kill_house,
                                                                                      trash=False,
                                                                                      temporary_trash=False,
                                                                                      temporary_deleted=False,
                                                                                      calculate_status=True,
                                                                                      warehouse=True).exclude(
            entered_message='ورود به انبار مجازی')
        kill_house_free_Sale_bar_informations = KillHouseFreeSaleBarInformation.objects.filter(
            kill_house=kill_house,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            calculate_status=True, warehouse=True)
        kill_house_allocations = StewardAllocation.objects.filter(kill_house=kill_house, trash=False,
                                                                  receiver_state__in=('pending', 'accepted'),
                                                                  temporary_trash=False,
                                                                  temporary_deleted=False,
                                                                  to_cold_house__isnull=True,
                                                                  calculate_status=True, warehouse=True)

        segmentations = PosSegmentation.objects.filter(kill_house=kill_house, trash=False, warehouse=True)
        cold_house_allocations = StewardAllocation.objects.filter(
            kill_house=kill_house,
            to_cold_house__isnull=False,
            receiver_state__in=('accepted', 'pending'),
            trash=False, warehouse=True)
        total_entered_kill_house_requests_carcasses_governmental_weight = \
            kill_house_requests.filter(ware_house_confirmation=True,
                                       province_request__poultry_request__free_sale_in_province=False).aggregate(
                total=Sum('ware_house_accepted_real_weight'))[
                'total'] or 0
        total_entered_kill_house_requests_carcasses_free_weight = \
            kill_house_requests.filter(ware_house_confirmation=True,
                                       province_request__poultry_request__free_sale_in_province=True).aggregate(
                total=Sum('ware_house_accepted_real_weight'))[
                'total'] or 0

        total_entered_kill_house_free_bar_carcasses_weight = \
            kill_house_free_bar_informations.aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0

        total_kill_house_free_sale__bar_carcasses_governmental_weight = \
            kill_house_free_Sale_bar_informations.filter(quota='governmental').aggregate(
                total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_kill_house_free_sale__bar_carcasses_free_weight = \
            kill_house_free_Sale_bar_informations.filter(quota='free').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_kill_house_allocations_governmental_weight = \
            kill_house_allocations.filter(quota='governmental').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0
        total_kill_house_allocations_free_weight = \
            kill_house_allocations.filter(quota='free').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        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

        cold_house_allocations_governmental_weight = \
            cold_house_allocations.filter(quota='governmental').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        cold_house_allocations_free_weight = \
            cold_house_allocations.filter(quota='free').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

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

        )

        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0

        total_governmental_input_weight = total_entered_kill_house_requests_carcasses_governmental_weight
        total_free_input_weight = total_entered_kill_house_requests_carcasses_free_weight + total_entered_kill_house_free_bar_carcasses_weight
        total_governmental_output_weight = total_kill_house_free_sale__bar_carcasses_governmental_weight + segmentations_governmental_weight + total_kill_house_allocations_governmental_weight + cold_house_allocations_governmental_weight + int(
            (pos_governmental_allocated_weight / 1000))
        total_free_output_weight = total_kill_house_free_sale__bar_carcasses_free_weight + total_kill_house_allocations_free_weight + segmentations_free_weight + cold_house_allocations_free_weight + int(
            pos_free_allocated_weight / 1000)
        total_governmental_remain_weight = (
                                                   total_governmental_input_weight - total_governmental_output_weight) - archives_governmental_weight
        total_free_remain_weight = (total_free_input_weight - total_free_output_weight) - archives_free_weight
        result = {

            "total_governmental_input_weight": int(total_governmental_input_weight),
            "total_free_input_weight": int(total_free_input_weight),
            "total_governmental_output_weight": int(total_governmental_output_weight),
            "total_free_output_weight": int(total_free_output_weight),
            "total_governmental_remain_weight": int(total_governmental_remain_weight),
            "total_free_remain_weight": int(total_free_remain_weight),
            "segmentations_weight": int(segmentations_weight),
            "total_output": int(total_governmental_output_weight + total_free_output_weight),
            "total_input": int(total_governmental_input_weight + total_free_input_weight),
            "pos_allocated_weight": int(pos_allocated_weight / 1000),
            "archives_governmental_weight": archives_governmental_weight,
            "archives_free_weight": archives_free_weight,

        }

        return result

    def guild_steward_info(self, steward):
        product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True, trash=False)
        pos_allocated_weight = transactions.aggregate(total=Sum('cur_weight'))['total'] or 0
        pos_governmental_allocated_weight = transactions.filter(price_approved=True).aggregate(total=Sum('cur_weight'))[
                                                'total'] or 0
        pos_free_allocated_weight = transactions.filter(price_approved=False).aggregate(total=Sum('cur_weight'))[
                                        'total'] or 0

        archives = WarehouseArchive.objects.filter(Q(steward=steward) | Q(guild=steward), trash=False, warehouse=True)

        guild_steward_allocations = StewardAllocation.objects.filter(
            Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(
                to_steward=steward),
            trash=False, calculate_status=True, warehouse=True, steward_warehouse=True)

        output_steward_allocations = guild_steward_allocations.filter(Q(guilds=steward) | Q(steward=steward))
        input_steward_allocations = guild_steward_allocations.filter(
            Q(to_guilds=steward) | Q(to_steward=steward))

        steward_free_bar_informations = StewardFreeBarInformation.objects.filter(steward=steward,
                                                                                 trash=False,
                                                                                 temporary_trash=False,
                                                                                 temporary_deleted=False,
                                                                                 warehouse=True)
        steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
            steward=steward,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True)

        segmentations = PosSegmentation.objects.filter(guild=steward, trash=False, warehouse=True)

        total_input_allocations_governmental_weight = \
            input_steward_allocations.filter(receiver_state='accepted', quota='governmental').aggregate(
                total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_input_allocations_free_weight = \
            input_steward_allocations.filter(receiver_state='accepted', quota='free').aggregate(
                total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_input_free_bar_carcasses_weight = \
            steward_free_bar_informations.aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0
        total_steward_free_sale_bar_carcasses_weight = \
            steward_free_Sale_bar_informations.aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0
        total_steward_free_sale_bar_carcasses_governmental_weight = \
            steward_free_Sale_bar_informations.filter(quota='governmental').aggregate(
                total=Sum('weight_of_carcasses'))[
                'total'] or 0

        total_steward_house_free_sale_bar_carcasses_free_weight = \
            steward_free_Sale_bar_informations.filter(quota='free').aggregate(total=Sum('weight_of_carcasses'))[
                'total'] or 0

        total_steward_in_province_allocations_weight = \
            output_steward_allocations.aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        total_steward_in_province_allocations_governmental_weight = \
            output_steward_allocations.filter(quota='governmental').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0
        total_steward_in_province_allocations_free_weight = \
            output_steward_allocations.filter(quota='free').aggregate(total=Sum('real_weight_of_carcasses'))[
                'total'] or 0

        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

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

        )

        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0

        total_governmental_input_weight = total_input_allocations_governmental_weight
        total_free_input_weight = total_input_allocations_free_weight + total_input_free_bar_carcasses_weight
        total_governmental_output_weight = total_steward_free_sale_bar_carcasses_governmental_weight + segmentations_governmental_weight + total_steward_in_province_allocations_governmental_weight + int(
            (pos_governmental_allocated_weight / 1000))
        total_free_output_weight = total_steward_house_free_sale_bar_carcasses_free_weight + total_steward_in_province_allocations_free_weight + segmentations_free_weight + int(
            (pos_free_allocated_weight / 1000))
        total_governmental_remain_weight = (
                                                   total_governmental_input_weight - total_governmental_output_weight) - archives_governmental_weight
        total_free_remain_weight = (total_free_input_weight - total_free_output_weight) - archives_free_weight

        result = {

            "total_governmental_input_weight": int(total_governmental_input_weight),
            "total_free_input_weight": int(total_free_input_weight),
            "total_governmental_output_weight": int(total_governmental_output_weight),
            "total_free_output_weight": int(total_free_output_weight),
            "total_governmental_remain_weight": int(total_governmental_remain_weight),
            "total_free_remain_weight": int(total_free_remain_weight),
            "segmentations_weight": int(segmentations_weight),
            "total_output": int(total_governmental_output_weight + total_free_output_weight),
            "total_input": int(total_governmental_input_weight + total_free_input_weight),
            "pos_allocated_weight": int(pos_allocated_weight / 1000),
            "archives_governmental_weight": archives_governmental_weight,
            "archives_free_weight": archives_free_weight,

        }

        return result

    def get(self, request):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device)
        if pos.kill_house:
            result = self.kill_house_info(pos.kill_house)
        else:

            result = self.guild_steward_info(pos.guild)

        return Response(result, status=status.HTTP_200_OK)


class PosColdHouseViewSet(APIView):
    permission_classes = [AllowAny]
    serializer_class = ColdHouseSerializer

    def get(self, request):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

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

        cold_house = ColdHouse.objects.filter(trash=False).order_by('kill_house')

        serializer = ColdHouseSerializer(cold_house, many=True)

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


class PosRemainWeightViewSet(APIView):
    permission_classes = [AllowAny]

    def kill_house_info(self, kill_house):

        today = datetime.now().date()
        yesterday = today - timedelta(days=1)
        two_days_ago = yesterday - timedelta(days=1)
        days = (two_days_ago, yesterday, today)
        product = RolesProducts.objects.filter(kill_house=kill_house, trash=False, name='مرغ گرم').first()
        archives = WarehouseArchive.objects.filter(kill_house=kill_house, trash=False, date__date__gte=two_days_ago,
                                                   date__date__lte=today)

        kill_house_requests = KillHouseRequest.objects.filter(input_warehouse=kill_house,
                                                              kill_request__recive_date__date__gte=two_days_ago,
                                                              kill_request__recive_date__date__lte=today,
                                                              ware_house_confirmation=True, trash=False,
                                                              calculate_status=True, warehouse=True)
        kill_house_free_buying_bars = KillHouseFreeBarInformation.objects.filter(trash=False,
                                                                                 calculate_status=True, warehouse=True,
                                                                                 date__date__gte=two_days_ago,
                                                                                 date__date__lte=today,
                                                                                 input_warehouse=kill_house) \
            .exclude(entered_message='ورود به انبار مجازی')
        kill_house_allocations = StewardAllocation.objects.filter(
            kill_house=kill_house, trash=False, calculate_status=True, warehouse=True,
            receiver_state__in=('pending', 'accepted'), production_date__date__gte=two_days_ago,
            production_date__date__lte=today)

        kill_house_free_sale_bars = KillHouseFreeSaleBarInformation.objects.filter(kill_house=kill_house,
                                                                                   production_date__date__gte=two_days_ago,
                                                                                   production_date__date__lte=today,
                                                                                   trash=False,
                                                                                   calculate_status=True,
                                                                                   warehouse=True)
        segmentations = PosSegmentation.objects.filter(kill_house=kill_house, production_date__date__gte=two_days_ago,
                                                       production_date__date__lte=today, trash=False,
                                                       warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
                                                           transaction__date__date__gte=two_days_ago,
                                                           transaction__date__date__lte=today, trash=False,
                                                           warehouse=True)

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

        for day in days:
            kill_house_requests_info = kill_house_requests.aggregate(
                total_kill_house_request_governmental_weight=Sum('ware_house_accepted_real_weight', filter=Q(
                    province_request__poultry_request__free_sale_in_province=False,
                    kill_request__recive_date__date=day)),
                total_kill_house_request_free_weight=Sum('ware_house_accepted_real_weight', filter=Q(
                    province_request__poultry_request__free_sale_in_province=True,
                    kill_request__recive_date__date=day)),

            )

            kill_house_free_buying_bars_info = kill_house_free_buying_bars.aggregate(
                total_kill_house_free_buying_bars_weight=Sum('weight_of_carcasses', filter=Q(date__date=day)))

            kill_house_allocations_info = kill_house_allocations.aggregate(
                total_kill_house_allocations_governmental_weight=Sum('real_weight_of_carcasses',
                                                                     filter=Q(quota='governmental',
                                                                              production_date__date=day)),
                total_kill_house_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                             filter=Q(quota='free', production_date__date=day)),

            )

            kill_house_free_sale_bars_info = kill_house_free_sale_bars.aggregate(
                total_kill_house_free_sale_bars_governmental_weight=Sum('real_weight_of_carcasses',
                                                                        filter=Q(quota='governmental',
                                                                                 production_date__date=day)),
                total_kill_house_free_sale_bars_free_weight=Sum('real_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_kill_house_request_governmental_weight = kill_house_requests_info[
                                                               'total_kill_house_request_governmental_weight'] or 0
            total_kill_house_request_free_weight = kill_house_requests_info['total_kill_house_request_free_weight'] or 0
            total_kill_house_free_buying_bars_weight = kill_house_free_buying_bars_info[
                                                           'total_kill_house_free_buying_bars_weight'] or 0
            total_kill_house_allocations_governmental_weight = kill_house_allocations_info[
                                                                   'total_kill_house_allocations_governmental_weight'] or 0
            total_kill_house_allocations_free_weight = kill_house_allocations_info[
                                                           'total_kill_house_allocations_free_weight'] or 0
            total_kill_house_free_sale_bars_governmental_weight = kill_house_free_sale_bars_info[
                                                                      'total_kill_house_free_sale_bars_governmental_weight'] or 0
            total_kill_house_free_sale_bars_free_weight = kill_house_free_sale_bars_info[
                                                              'total_kill_house_free_sale_bars_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_kill_house_request_governmental_weight
            total_free_input = total_kill_house_request_free_weight + total_kill_house_free_buying_bars_weight
            total_governmental_output = total_kill_house_allocations_governmental_weight + total_kill_house_free_sale_bars_governmental_weight + segmentations_governmental_weight + int(
                pos_governmental_allocated_weight / 1000)
            total_free_output = total_kill_house_allocations_free_weight + total_kill_house_free_sale_bars_free_weight + segmentations_free_weight + int(
                pos_free_allocated_weight / 1000)
            governmental_data = {
                'day': jdatetime.date.fromgregorian(date=day).strftime('%Y-%m-%d'),
                'amount': (total_governmental_input - total_governmental_output) - archives_governmental_weight,
            }
            free_data = {
                'day': jdatetime.date.fromgregorian(date=day).strftime('%Y-%m-%d'),
                'amount': (total_free_input - total_free_output) - archives_free_weight,
            }

            governmental_list.append(governmental_data)
            free_list.append(free_data)
        final_dict['governmental'] = governmental_list
        final_dict['free'] = free_list
        return final_dict

    def guild_steward_info(self, steward):
        today = datetime.now().date()
        yesterday = today - timedelta(days=1)
        two_days_ago = yesterday - timedelta(days=1)
        days = (two_days_ago, yesterday, today)
        product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
        archives = WarehouseArchive.objects.filter(Q(steward=steward) | Q(guild=steward), trash=False, warehouse=True,
                                                   date__date__gte=two_days_ago, date__date__lte=today)

        guild_steward_allocations = StewardAllocation.objects.filter(
            Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(
                to_steward=steward),
            trash=False, calculate_status=True, warehouse=True, steward_warehouse=True)

        output_steward_allocations = guild_steward_allocations.filter(Q(guilds=steward) | Q(steward=steward),
                                                                      production_date__date__gte=two_days_ago,
                                                                      production_date__date__lte=today, )
        input_steward_allocations = guild_steward_allocations.filter(
            Q(to_guilds=steward) | Q(to_steward=steward), date__date__gte=two_days_ago, date__date__lte=today, )

        steward_free_bar_informations = StewardFreeBarInformation.objects.filter(steward=steward,
                                                                                 date__date__gte=two_days_ago,
                                                                                 date__date__lte=today,
                                                                                 trash=False,
                                                                                 temporary_trash=False,
                                                                                 temporary_deleted=False,
                                                                                 warehouse=True)
        steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
            steward=steward,
            production_date__date__gte=two_days_ago,
            production_date__date__lte=today,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True)

        segmentations = PosSegmentation.objects.filter(guild=steward, production_date__date__gte=two_days_ago,
                                                       production_date__date__lte=today, trash=False, warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
                                                           transaction__date__date__gte=two_days_ago,
                                                           transaction__date__date__lte=today, trash=False,
                                                           warehouse=True)

        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_data = {
                'day': jdatetime.date.fromgregorian(date=day).strftime('%Y-%m-%d'),
                'amount': (total_governmental_input - total_governmental_output) - archives_governmental_weight,
            }
            free_data = {
                'day': jdatetime.date.fromgregorian(date=day).strftime('%Y-%m-%d'),
                'amount': (total_free_input - total_free_output) - archives_free_weight,
            }

            governmental_list.append(governmental_data)
            free_list.append(free_data)
        final_dict['governmental'] = governmental_list
        final_dict['free'] = free_list
        return final_dict

    def get(self, request):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

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

        if pos.kill_house:
            final_dict = self.kill_house_info(pos.kill_house)
        else:
            final_dict = self.guild_steward_info(pos.guild)

        return Response(final_dict, status=status.HTTP_200_OK)


class PosRemainWeightWithDateViewSet(APIView):
    permission_classes = [AllowAny]

    def kill_house_info(self, kill_house, date):

        product = RolesProducts.objects.filter(kill_house=kill_house, trash=False, name='مرغ گرم').first()

        kill_house_requests = KillHouseRequest.objects.filter(input_warehouse=kill_house,
                                                              kill_request__recive_date__date=date,
                                                              ware_house_confirmation=True, trash=False,
                                                              calculate_status=True, warehouse=True)
        kill_house_free_buying_bars = KillHouseFreeBarInformation.objects.filter(trash=False,
                                                                                 calculate_status=True, warehouse=True,
                                                                                 date__date=date,
                                                                                 input_warehouse=kill_house) \
            .exclude(entered_message='ورود به انبار مجازی')
        kill_house_allocations = StewardAllocation.objects.filter(
            kill_house=kill_house, trash=False, calculate_status=True, warehouse=True,
            receiver_state__in=('pending', 'accepted'), production_date__date=date)

        kill_house_free_sale_bars = KillHouseFreeSaleBarInformation.objects.filter(kill_house=kill_house,
                                                                                   production_date__date=date,
                                                                                   trash=False,
                                                                                   calculate_status=True,
                                                                                   warehouse=True)
        segmentations = PosSegmentation.objects.filter(kill_house=kill_house, production_date__date=date, trash=False,
                                                       warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
                                                           transaction__date__date=date, trash=False, warehouse=True)
        archives = WarehouseArchive.objects.filter(kill_house=kill_house, trash=False, warehouse=True, date__date=date)

        final_dict = {}

        kill_house_requests_info = kill_house_requests.aggregate(
            total_kill_house_request_governmental_weight=Sum('ware_house_accepted_real_weight', filter=Q(
                province_request__poultry_request__free_sale_in_province=False)),
            total_kill_house_request_free_weight=Sum('ware_house_accepted_real_weight', filter=Q(
                province_request__poultry_request__free_sale_in_province=True)),

        )

        kill_house_free_buying_bars_info = kill_house_free_buying_bars.aggregate(
            total_kill_house_free_buying_bars_weight=Sum('weight_of_carcasses'))

        kill_house_allocations_info = kill_house_allocations.aggregate(
            total_kill_house_allocations_governmental_weight=Sum('real_weight_of_carcasses',
                                                                 filter=Q(quota='governmental')),
            total_kill_house_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                         filter=Q(quota='free')),

        )

        kill_house_free_sale_bars_info = kill_house_free_sale_bars.aggregate(
            total_kill_house_free_sale_bars_governmental_weight=Sum('real_weight_of_carcasses',
                                                                    filter=Q(quota='governmental')),
            total_kill_house_free_sale_bars_free_weight=Sum('real_weight_of_carcasses',
                                                            filter=Q(quota='free')),

        )

        segmentations_info = segmentations.aggregate(
            segmentations_governmental_weight=Sum('weight',
                                                  filter=Q(quota='governmental')),
            segmentations_free_weight=Sum('weight', filter=Q(quota='free')),

        )
        pos_allocated_weight_info = transactions.aggregate(
            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_governmental_weight=Sum('weight',
                                             filter=Q(quota='governmental')),
            archives_free_weight=Sum('weight',
                                     filter=Q(quota='free')),

        )
        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0

        total_kill_house_request_governmental_weight = kill_house_requests_info[
                                                           'total_kill_house_request_governmental_weight'] or 0
        total_kill_house_request_free_weight = kill_house_requests_info['total_kill_house_request_free_weight'] or 0
        total_kill_house_free_buying_bars_weight = kill_house_free_buying_bars_info[
                                                       'total_kill_house_free_buying_bars_weight'] or 0
        total_kill_house_allocations_governmental_weight = kill_house_allocations_info[
                                                               'total_kill_house_allocations_governmental_weight'] or 0
        total_kill_house_allocations_free_weight = kill_house_allocations_info[
                                                       'total_kill_house_allocations_free_weight'] or 0
        total_kill_house_free_sale_bars_governmental_weight = kill_house_free_sale_bars_info[
                                                                  'total_kill_house_free_sale_bars_governmental_weight'] or 0
        total_kill_house_free_sale_bars_free_weight = kill_house_free_sale_bars_info[
                                                          'total_kill_house_free_sale_bars_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
        total_governmental_input = total_kill_house_request_governmental_weight
        total_free_input = total_kill_house_request_free_weight + total_kill_house_free_buying_bars_weight
        total_governmental_output = total_kill_house_allocations_governmental_weight + total_kill_house_free_sale_bars_governmental_weight + segmentations_governmental_weight + int(
            pos_governmental_allocated_weight / 1000)
        total_free_output = total_kill_house_allocations_free_weight + total_kill_house_free_sale_bars_free_weight + segmentations_free_weight + int(
            pos_free_allocated_weight / 1000)
        date = datetime.strptime(date, '%Y-%m-%d').date()

        governmental_data = {
            'day': jdatetime.date.fromgregorian(date=date).strftime('%Y-%m-%d'),
            'amount': (total_governmental_input - total_governmental_output) - archives_governmental_weight,
        }
        free_data = {
            'day': jdatetime.date.fromgregorian(date=date).strftime('%Y-%m-%d'),
            'amount': (total_free_input - total_free_output) - archives_free_weight,
        }

        final_dict['governmental'] = governmental_data
        final_dict['free'] = free_data
        return final_dict

    def guild_steward_info(self, steward, date):

        product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
        guild_steward_allocations = StewardAllocation.objects.filter(
            Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(
                to_steward=steward),
            trash=False, calculate_status=True, warehouse=True, steward_warehouse=True)

        output_steward_allocations = guild_steward_allocations.filter(Q(guilds=steward) | Q(steward=steward),
                                                                      production_date__date=date)
        input_steward_allocations = guild_steward_allocations.filter(
            Q(to_guilds=steward) | Q(to_steward=steward), date__date=date)

        steward_free_bar_informations = StewardFreeBarInformation.objects.filter(steward=steward,
                                                                                 date__date=date,
                                                                                 trash=False,
                                                                                 temporary_trash=False,
                                                                                 temporary_deleted=False,
                                                                                 warehouse=True)
        steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
            steward=steward,
            production_date__date=date,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True)

        segmentations = PosSegmentation.objects.filter(guild=steward, production_date__date=date, trash=False,
                                                       warehouse=True)
        transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
                                                           transaction__date__date=date, trash=False, warehouse=True)
        archives = WarehouseArchive.objects.filter(Q(steward=steward) | Q(guild=steward), trash=False,
                                                   date__date=date,
                                                   warehouse=True)

        final_dict = {}

        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')),
            total_input_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                    filter=Q(receiver_state='accepted', quota='free'))
        )
        output_steward_allocations_info = output_steward_allocations.aggregate(
            total_output_allocations_governmental_weight=Sum('real_weight_of_carcasses',
                                                             filter=Q(quota='governmental')),
            total_output_allocations_free_weight=Sum('real_weight_of_carcasses',
                                                     filter=Q(quota='free'))

        )
        steward_free_bar_info = steward_free_bar_informations.aggregate(
            total_free_bar_weight=Sum('weight_of_carcasses'),

        )

        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')),
            total_free_Sale_bar_free_weight=Sum('weight_of_carcasses', filter=Q(quota='free'))

        )

        segmentations_info = segmentations.aggregate(
            segmentations_governmental_weight=Sum('weight',
                                                  filter=Q(quota='governmental')),
            segmentations_free_weight=Sum('weight', filter=Q(quota='free')),

        )
        pos_allocated_weight_info = transactions.aggregate(
            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_governmental_weight=Sum('weight',
                                             filter=Q(quota='governmental')),
            archives_free_weight=Sum('weight',
                                     filter=Q(quota='free')),

        )
        archives_governmental_weight = archives_info['archives_governmental_weight'] or 0
        archives_free_weight = archives_info['archives_free_weight'] or 0

        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
        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)
        date = datetime.strptime(date, '%Y-%m-%d').date()
        governmental_data = {
            'day': jdatetime.date.fromgregorian(date=date).strftime('%Y-%m-%d'),
            'amount': (total_governmental_input - total_governmental_output) - archives_governmental_weight,
        }
        free_data = {
            'day': jdatetime.date.fromgregorian(date=date).strftime('%Y-%m-%d'),
            'amount': (total_free_input - total_free_output) - archives_free_weight,
        }

        final_dict['governmental'] = governmental_data
        final_dict['free'] = free_data
        return final_dict

    def get(self, request):
        validator = PosDeviceValidator(request)
        validation_error = validator.validation_version()
        if validation_error:
            return validation_error

        validation_device = validator.validation_device()
        if not validation_device:
            return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
        pos = POSMachine.objects.get(pos_id=validation_device)
        date = request.GET.get('date')

        if pos.kill_house:
            final_dict = self.kill_house_info(pos.kill_house, date)
        else:
            final_dict = self.guild_steward_info(pos.guild, date)

        return Response(final_dict, status=status.HTTP_200_OK)


# class StewardRemainWeightViewSet(APIView):
#     permission_classes = [TokenHasReadWriteScope]
#
#     def get(self, request):
#         user = SystemUserProfile.objects.get(user=request.user, trash=False)
#         steward = Guilds.objects.get(user=user, trash=False)
#         product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
#         today = datetime.now().date()
#         yesterday = today - timedelta(days=1)
#         two_days_ago = yesterday - timedelta(days=1)
#         days = (two_days_ago, yesterday, today)
#         archives = WarehouseArchive.objects.filter(Q(steward=steward) | Q(guild=steward), trash=False,
#                                                    date__date__gte=two_days_ago, date__date__lte=today)
#
#         guild_steward_allocations = StewardAllocation.objects.filter(
#             Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(
#                 to_steward=steward),
#             trash=False, calculate_status=True, warehouse=True, steward_warehouse=True)
#
#         output_steward_allocations = guild_steward_allocations.filter(Q(guilds=steward) | Q(steward=steward),
#                                                                       production_date__date__gte=two_days_ago,
#                                                                       production_date__date__lte=today, )
#         input_steward_allocations = guild_steward_allocations.filter(
#             Q(to_guilds=steward) | Q(to_steward=steward), date__date__gte=two_days_ago, date__date__lte=today, )
#
#         steward_free_bar_informations = StewardFreeBarInformation.objects.filter(steward=steward,
#                                                                                  date__date__gte=two_days_ago,
#                                                                                  date__date__lte=today,
#                                                                                  trash=False,
#                                                                                  temporary_trash=False,
#                                                                                  temporary_deleted=False,
#                                                                                  warehouse=True)
#         steward_free_Sale_bar_informations = StewardFreeSaleBarInformation.objects.filter(
#             steward=steward,
#             production_date__date__gte=two_days_ago,
#             production_date__date__lte=today,
#             trash=False,
#             temporary_trash=False,
#             temporary_deleted=False,
#             warehouse=True)
#
#         segmentations = PosSegmentation.objects.filter(guild=steward, production_date__date__gte=two_days_ago,
#                                                        production_date__date__lte=today, trash=False, warehouse=True)
#         transactions = ProductsTransactions.objects.filter(product=product, transaction__paid=True,
#                                                            transaction__date__date__gte=two_days_ago,
#                                                            transaction__date__date__lte=today, trash=False,
#                                                            warehouse=True)
#
#         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_data = {
#                 'day': day,
#                 'amount': (total_governmental_input - total_governmental_output) - archives_governmental_weight,
#             }
#             free_data = {
#                 'day': day,
#                 'amount': (total_free_input - total_free_output) - archives_free_weight,
#             }
#
#             governmental_list.append(governmental_data)
#             free_list.append(free_data)
#         final_dict['governmental'] = governmental_list
#         final_dict['free'] = free_list
#
#         return Response(final_dict, status=status.HTTP_200_OK)

class StewardRemainWeightViewSet(GenericAPIView):
    permission_classes = [TokenHasReadWriteScope]

    def get(self, request):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        steward = Guilds.objects.get(user=user, active=True, trash=False)
        product = RolesProducts.objects.filter(guild=steward, trash=False, name='مرغ گرم').first()
        target_date = request.GET.get('date')
        today = datetime.now().date() if not target_date else datetime.strptime(target_date, "%Y-%m-%d").date()
        month_ago = today - timedelta(days=30)
        yesterday = today - timedelta(days=1)
        two_days_ago = yesterday - timedelta(days=1)

        days = [month_ago + timedelta(days=i) for i in range(31)]
        target_days = {two_days_ago, yesterday, today}

        archives_vals = list(WarehouseArchive.objects.filter(
            Q(steward=steward) | Q(guild=steward),
            trash=False,
            date__date__gte=month_ago,
            date__date__lte=today,
            warehouse=True,
        ).values('date__date', 'quota', 'weight'))

        # allocations_vals = list(StewardAllocation.objects.filter(
        #     Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(to_steward=steward),
        #     trash=False,
        #     calculate_status=True,
        #     warehouse=True,
        #     steward_warehouse=True
        # ).values('production_date__date', 'date__date', 'quota', 'real_weight_of_carcasses', 'receiver_state'))

        allocations_vals = StewardAllocation.objects.filter(
            Q(guilds=steward) | Q(to_guilds=steward) | Q(steward=steward) | Q(to_steward=steward),
            trash=False,
            calculate_status=True,
            warehouse=True,
            production_date__isnull=False,
            steward_warehouse=True
        )
        input_allocations_vals = allocations_vals.filter(Q(to_guilds=steward,to_steward__isnull=True) | Q(to_steward=steward,to_guilds__isnull=True),receiver_state='accepted').values('production_date__date', 'date__date', 'quota', 'real_weight_of_carcasses', 'receiver_state')
        output_allocations_vals = allocations_vals.filter(Q(guilds=steward,steward__isnull=True) | Q(steward=steward,guilds__isnull=True),receiver_state__in=('accepted','pending')).values('production_date__date', 'date__date', 'quota', 'real_weight_of_carcasses', 'receiver_state')


        free_bar_vals = list(StewardFreeBarInformation.objects.filter(
            steward=steward,
            date__date__gte=month_ago,
            date__date__lte=today,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True
        ).values('date__date', 'weight_of_carcasses'))

        free_sale_vals = list(StewardFreeSaleBarInformation.objects.filter(
            steward=steward,
            production_date__date__gte=month_ago,
            production_date__date__lte=today,
            trash=False,
            temporary_trash=False,
            temporary_deleted=False,
            warehouse=True
        ).values('production_date__date', 'quota', 'weight_of_carcasses'))

        seg_vals = list(PosSegmentation.objects.filter(
            guild=steward,
            production_date__date__gte=month_ago,
            production_date__date__lte=today,
            trash=False,
            warehouse=True
        ).values('production_date__date', 'quota', 'weight'))

        pos_vals = list(ProductsTransactions.objects.filter(
            product=product,
            transaction__paid=True,
            transaction__date__date__gte=month_ago,
            transaction__date__date__lte=today,
            trash=False,
            warehouse=True
        ).values('transaction__date__date', 'price_approved', 'cur_weight'))

        archives_daily = {}
        for a in archives_vals:
            d = a['date__date']
            q = a['quota']
            w = a['weight'] or 0
            if d not in archives_daily:
                archives_daily[d] = {'governmental': 0, 'free': 0}
            archives_daily[d][q] += w

        input_alloc_daily = {}
        output_alloc_daily = {}
        # for a in allocations_vals:
        #     date_field = 'date__date' if a['receiver_state'] == 'accepted' else 'production_date__date'
        #     w = a['real_weight_of_carcasses'] or 0
        #     q = a['quota']
        #     if a['receiver_state'] == 'accepted':  # input
        #         if a[date_field] not in input_alloc_daily:
        #             input_alloc_daily[a[date_field]] = {'governmental': 0, 'free': 0}
        #         input_alloc_daily[a[date_field]][q] += w
        #         print(w)
        #     else:  # output
        #         if a[date_field] not in output_alloc_daily:
        #             output_alloc_daily[a[date_field]] = {'governmental': 0, 'free': 0}
        #         output_alloc_daily[a[date_field]][q] += w
        for a in input_allocations_vals:
            date_field = 'date__date'
            w = a['real_weight_of_carcasses'] or 0
            q = a['quota']
            if a[date_field] not in input_alloc_daily:
                    input_alloc_daily[a[date_field]] = {'governmental': 0, 'free': 0}
            input_alloc_daily[a[date_field]][q] += w


        for a in output_allocations_vals:
            date_field = 'production_date__date'
            w = a['real_weight_of_carcasses'] or 0
            q = a['quota']
            if a[date_field] not in output_alloc_daily:
                    output_alloc_daily[a[date_field]] = {'governmental': 0, 'free': 0}
            output_alloc_daily[a[date_field]][q] += w


        free_bar_daily = {}
        for f in free_bar_vals:
            d = f['date__date']
            free_bar_daily[d] = free_bar_daily.get(d, 0) + (f['weight_of_carcasses'] or 0)

        free_sale_daily = {}
        for f in free_sale_vals:
            d = f['production_date__date']
            q = f['quota']
            w = f['weight_of_carcasses'] or 0
            if d not in free_sale_daily:
                free_sale_daily[d] = {'governmental': 0, 'free': 0}
            free_sale_daily[d][q] += w

        seg_daily = {}
        for s in seg_vals:
            d = s['production_date__date']
            q = s['quota']
            w = s['weight'] or 0
            if d not in seg_daily:
                seg_daily[d] = {'governmental': 0, 'free': 0}
            seg_daily[d][q] += w

        pos_daily = {}
        for p in pos_vals:
            d = p['transaction__date__date']
            w = p['cur_weight'] or 0
            if d not in pos_daily:
                pos_daily[d] = {'governmental': 0, 'free': 0}
            if p['price_approved']:
                pos_daily[d]['governmental'] += w
            else:
                pos_daily[d]['free'] += w

        governmental_list = []
        free_list = []

        for day in days:
            gov_in = input_alloc_daily.get(day, {}).get('governmental', 0)
            free_in = input_alloc_daily.get(day, {}).get('free', 0) + free_bar_daily.get(day, 0)

            gov_out = (
                    output_alloc_daily.get(day, {}).get('governmental', 0) +
                    free_sale_daily.get(day, {}).get('governmental', 0) +
                    seg_daily.get(day, {}).get('governmental', 0) +
                    (pos_daily.get(day, {}).get('governmental', 0) // 1000)
            )

            free_out = (
                    output_alloc_daily.get(day, {}).get('free', 0) +
                    free_sale_daily.get(day, {}).get('free', 0) +
                    seg_daily.get(day, {}).get('free', 0) +
                    (pos_daily.get(day, {}).get('free', 0) // 1000)
            )

            governmental_list.append({
                'day': day,
                'governmental': gov_in,
                'amount': (gov_in - gov_out) - archives_daily.get(day, {}).get('governmental', 0) if (
                                                                                                             gov_in - gov_out) - archives_daily.get(
                    day, {}).get('governmental', 0) > 0 else 0,
                'active': day in target_days
            })

            free_list.append({
                'day': day,
                'amount': (free_in - free_out) - archives_daily.get(day, {}).get('free', 0) if (
                                                                                                       free_in - free_out) - archives_daily.get(
                    day, {}).get('free', 0) > 0 else 0,
                'active': day in target_days
            })

        return Response({
            'governmental': governmental_list,
            'free': free_list
        }, status=status.HTTP_200_OK)


class TotalStewardRemainWeightViewSet(GenericAPIView):
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TotalStewardRemainWeightSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsForPostationFilterSet
    filterset_fields = [
        'user__first_name',
        'user__last_name',
        'user__fullname',
        'user__mobile',
        'guilds_name'
    ]

    def get(self, request):
        owner_type = request.GET.get('owner_type')
        guild_steward_filters = {'trash': False, 'total_remain_warehouse_weight__gt': 0, 'active': True}
        guild_steward_filters['steward'] = True if owner_type == 'steward' else False
        guild_steward = Guilds.objects.filter(**guild_steward_filters).order_by('id')

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guild_steward)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(guild_steward, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)


# class TotalStewardRemainWeightViewSet(GenericAPIView):
#     permission_classes = [TokenHasReadWriteScope]
#     serializer_class = TotalStewardRemainWeightSerializer
#     pagination_class = CustomPagination
#     filter_backends = [DjangoFilterBackend]
#     filterset_class = GuildsForPostationFilterSet
#     filterset_fields = [
#         'user__first_name',
#         'user__last_name',
#         'user__fullname',
#         'user__mobile',
#         'guilds_name'
#     ]
#
#     def get(self, request):
#         from collections import defaultdict
#         from datetime import datetime, timedelta
#
#         owner_type = request.GET.get('owner_type')
#         filters = {'trash': False, 'total_remain_warehouse_weight__gt': 0, 'steward': owner_type == 'steward'}
#         guilds = Guilds.objects.filter(**filters).order_by('id')
#
#         if request.GET.get('search') == 'filter' and request.GET.get('value') not in ["", "undefined"]:
#             value = request.GET['value']
#             for f in self.filterset_fields:
#                 query = QueryDict(f'{f}__contains={value}')
#                 qs = self.filterset_class(data=query, queryset=guilds).qs
#                 if qs.exists():
#                     guilds = qs
#                     break
#
#         guild_ids = list(guilds.values_list('id', flat=True))
#         if not guild_ids:
#             return Response([])
#
#         allocations = StewardAllocation.objects.filter(
#             Q(guilds_id__in=guild_ids) | Q(to_guilds_id__in=guild_ids) |
#             Q(steward_id__in=guild_ids) | Q(to_steward_id__in=guild_ids),
#             trash=False, calculate_status=True, warehouse=True, steward_warehouse=True
#         ).values('guilds_id', 'to_guilds_id', 'steward_id', 'to_steward_id', 'quota', 'receiver_state',
#                  'real_weight_of_carcasses', 'date', 'production_date')
#
#         free_bars = StewardFreeBarInformation.objects.filter(
#             steward_id__in=guild_ids, trash=False, temporary_trash=False, temporary_deleted=False, warehouse=True
#         ).values('steward_id', 'date', 'weight_of_carcasses')
#
#         free_sales = StewardFreeSaleBarInformation.objects.filter(
#             steward_id__in=guild_ids, trash=False, temporary_trash=False, temporary_deleted=False, warehouse=True
#         ).values('steward_id', 'production_date', 'quota', 'weight_of_carcasses')
#
#         segmentations = PosSegmentation.objects.filter(
#             guild_id__in=guild_ids, trash=False, warehouse=True
#         ).values('guild_id', 'production_date', 'quota', 'weight')
#
#         archives = WarehouseArchive.objects.filter(
#             Q(guild_id__in=guild_ids) | Q(steward_id__in=guild_ids), trash=False
#         ).values('guild_id', 'steward_id', 'date', 'quota', 'weight')
#
#         data = defaultdict(lambda: defaultdict(lambda: {'gov': 0, 'free': 0}))
#         today = datetime.now().date()
#         exclude_days = {today, today - timedelta(days=1), today - timedelta(days=2)}
#
#         def add(gid, day, gov, free):
#             if not gid or not day or day in exclude_days:
#                 return
#             data[gid][day]['gov'] += gov
#             data[gid][day]['free'] += free
#
#         for a in allocations:
#             for gid in [a['guilds_id'], a['to_guilds_id'], a['steward_id'], a['to_steward_id']]:
#                 if not gid or gid not in guild_ids:
#                     continue
#                 quota = a['quota']
#                 val = a['real_weight_of_carcasses'] or 0
#                 if a['receiver_state'] == 'accepted' and a['date']:
#                     add(gid, a['date'], val if quota == 'governmental' else 0, val if quota == 'free' else 0)
#                 if a['production_date']:
#                     add(gid, a['production_date'], -val if quota == 'governmental' else 0, -val if quota == 'free' else 0)
#
#         for b in free_bars:
#             add(b['steward_id'], b['date'], 0, b['weight_of_carcasses'] or 0)
#
#         for s in free_sales:
#             val = s['weight_of_carcasses'] or 0
#             add(s['steward_id'], s['production_date'], -val if s['quota'] == 'governmental' else 0, -val if s['quota'] == 'free' else 0)
#
#         for seg in segmentations:
#             val = seg['weight'] or 0
#             add(seg['guild_id'], seg['production_date'], -val if seg['quota'] == 'governmental' else 0, -val if seg['quota'] == 'free' else 0)
#
#         for arc in archives:
#             gid = arc['guild_id'] or arc['steward_id']
#             val = arc['weight'] or 0
#             add(gid, arc['date'], -val if arc['quota'] == 'governmental' else 0, -val if arc['quota'] == 'free' else 0)
#
#         precomputed = {}
#         for gid, days in data.items():
#             gov_by_day = defaultdict(float)
#             free_by_day = defaultdict(float)
#             for d, v in days.items():
#                 if v['gov'] > 0:
#                     gov_by_day[d.strftime('%Y-%m-%d')] += v['gov']
#                 if v['free'] > 0:
#                     free_by_day[d.strftime('%Y-%m-%d')] += v['free']
#
#             precomputed[gid] = {
#                 'governmental': [{'day': day, 'amount': amt} for day, amt in sorted(gov_by_day.items())],
#                 'free': [{'day': day, 'amount': amt} for day, amt in sorted(free_by_day.items())],
#             }
#
#         page_size = request.query_params.get('page_size')
#         if page_size:
#             self.pagination_class.page_size = int(page_size)
#
#         page = self.paginate_queryset(guilds)
#         context = {'precomputed_data': precomputed}
#         serializer = self.get_serializer(page or guilds, many=True, context=context)
#
#         if page:
#             return self.get_paginated_response(serializer.data)
#         return Response(serializer.data, status=status.HTTP_200_OK)

class WarehouseArchiveViewSet(viewsets.ModelViewSet):
    queryset = WarehouseArchive.objects.all()
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = WarehouseArchiveSerializer
    pagination_class = CustomPagination
    filterset_class = WarehouseArchiveFilterSet

    def create(self, request, *args, **kwargs):
        now = datetime.now()
        now_time = now.time()
        role = request.data.get('role')
        image = request.data.get('image')
        owner_key = request.data['owner_key']
        archive_type = request.data['archive_type']
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        date = datetime.strptime(str(request.data['date']), '%Y-%m-%d').date()
        date = datetime(year=date.year, month=date.month,
                        day=date.day,
                        hour=now_time.hour,
                        minute=now_time.minute,
                        second=now_time.second)
        request.data.pop('date')
        request.data.pop('owner_key')
        request.data.pop('archive_type')
        request.data.pop('role')
        if 'image' in request.data.keys():
            request.data.pop('image')
        if archive_type == 'kill_house':
            kill_house = KillHouse.objects.get(key=owner_key)
        else:
            guild_steward = Guilds.objects.get(key=owner_key)

        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            archive = serializer.create(validated_data=request.data)
            archive.date = date

            if archive_type == 'kill_house':
                archive.kill_house = kill_house
            elif archive_type == 'steward':
                archive.steward = guild_steward
            else:
                archive.guild = guild_steward

            if image:
                archive.image = send_image_to_server(image)
            archive.registerer = user.fullname
            archive.registerer_mobile = user.mobile
            archive.registerer_role = role
            archive.save()
            if archive.kill_house:
                kill_house_archive_warehousing(archive.kill_house)
            elif archive.steward:
                guild_steward_archive_warehousing(archive.steward)

            else:
                guild_steward_archive_warehousing(archive.guild)

            return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def list(self, request, *args, **kwargs):
        role = request.GET.get('role')
        archive_type = request.GET.get('archive_type')
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        filters = {"trash": False}
        if date1:
            filters['create_date__date__gte'] = date1
            filters['create_date__date__lte'] = date2
        if archive_type == 'kill_house':
            filters['kill_house__isnull'] = False
        elif archive_type == 'steward':
            filters['steward__isnull'] = False

        elif archive_type == 'guild':
            filters['guild__isnull'] = False
        else:
            filters['kill_house__isnull'] = False

        archives = WarehouseArchive.objects.filter(**filters)
        value = request.GET.get('value')
        search = request.GET.get('search')
        if value and search == 'filter':
            if value != 'undefined' and value.strip():
                archives = archives.filter(
                    build_query(self.filterset_class.Meta.fields, value)
                )

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)
        page = self.paginate_queryset(archives)
        if page is not None:
            serializer = self.serializer_class(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = POSDeviceSessionForCompanySerializer(archives, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def destroy(self, request, pk=None, *args, **kwargs):
        archive = WarehouseArchive.objects.get(key=request.GET['key'])
        archive.trash = True
        archive.save()
        if archive.kill_house:
            kill_house_archive_warehousing(archive.kill_house)
        elif archive.steward:
            guild_steward_archive_warehousing(archive.steward)

        else:
            guild_steward_archive_warehousing(archive.guild)
        return Response({"result": " با موفقیت حذف شد !"}, status=status.HTTP_200_OK)


class SmsRecipientViewSet(viewsets.ModelViewSet):
    queryset = SmsRecipient.objects.all()
    serializer_class = SmsRecipientSerializer
    permission_classes = [TokenHasReadWriteScope]


def persian_date_to_datetime(persian_date_str):
    """
    تبدیل تاریخ فارسی (مثل ۱۴۰۰/۰۵/۲۱) به datetime
    """
    if not persian_date_str:
        return None

    try:
        # تبدیل اعداد فارسی به انگلیسی
        persian_numbers = '۰۱۲۳۴۵۶۷۸۹'
        english_numbers = '0123456789'
        translation_table = str.maketrans(persian_numbers, english_numbers)
        english_date = persian_date_str.translate(translation_table)

        # جدا کردن سال، ماه، روز
        parts = english_date.split('/')
        if len(parts) != 3:
            return None

        year = int(parts[0])
        month = int(parts[1])
        day = int(parts[2])

        # استفاده از تابع موجود برای تبدیل
        from panel.convert_date import convert_to_miladi
        return convert_to_miladi(year=year, month=month, day=day)
    except:
        return None


@api_view(["POST"])
@permission_classes([AllowAny])
def create_or_update_guild_by_national_id(request):
    if 'file' not in request.FILES:
        return Response({"result": "فایل اکسل الزامی است"}, status=status.HTTP_400_BAD_REQUEST)

    file = request.FILES['file'].read()
    wb_obj = openpyxl.load_workbook(filename=BytesIO(file))
    sheet = wb_obj.active

    failed_records = []
    success_count = 0
    update_count = 0

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

    for i, row in enumerate(sheet.iter_rows(values_only=True)):
        national_id = str(row[0]) if row[0] else None
        if not national_id:
            continue

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

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

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

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

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

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

            first_name = person_info.get('firstName')
            last_name = person_info.get('lastName')
            father_name = person_info.get('fatherName')
            gender = person_info.get('gender')
            identity_no = person_info.get('identityNo')
            is_alive = person_info.get('isLive', True)
            birth_date = person_info.get('birthDate')
            jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date()
            birthday_str = jalali_date.strftime("%Y-%m-%d")
            city_name = guild_info.get('city')
            address_text = guild_info.get('address')
            postal_code = guild_layer_two.get('postalcode')
            license_number = guild_info.get('licenseNumber')
            license_expire_date = guild_info.get('licenseExpireDate')
            license_issue_date = guild_layer_two.get('licenseIssueDate')
            license_type = guild_info.get('licenseType')
            license_status = guild_info.get('licenseStatus')
            type_activity_name = guild_info.get('isicname')
            mobile = guild_layer_two.get('mobilenumber')
            company_name = guild_layer_two.get('corporationName')
            company_identifier = guild_layer_two.get('nationalId')
            union_name = guild_layer_two.get('unionName')
            phone_number = guild_layer_two.get('phonenumber')

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

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

            try:
                group = Group.objects.get(name__exact="Guilds")
            except Group.DoesNotExist:
                failed_records.append({"national_id": national_id, "reason": "گروه Guilds یافت نشد"})
                continue

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

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

            province = city.province

            existing_guild = Guilds.objects.filter(user__national_id=national_id, trash=False)

            system_profile = SystemUserProfile.objects.filter(national_id=national_id, trash=False)

            if not system_profile:
                if not mobile:
                    failed_records.append(
                        {"national_id": national_id, "reason": "شماره موبایل در اطلاعات صنفی یافت نشد"})
                    continue

                password = "00100"
                data = {
                    "username": mobile,
                    "password": password,
                    "api_key": PROJECT_API_KEY
                }
                req = requests.post(
                    url=ARTA_URL_REGISTER,
                    data=data,
                    verify=False
                )

                if req.status_code == 200:
                    user = User(username=mobile, first_name=first_name, last_name=last_name)
                    user.save()
                    base_id = SystemUserProfile.objects.all()
                    if base_id.count() > 0:
                        base_id = int(base_id.last().base_order) + 1
                    else:
                        base_id = 1000
                    system_profile = SystemUserProfile(
                        mobile=mobile,
                        first_name=first_name,
                        last_name=last_name,
                        fullname=first_name + " " + last_name,
                        user=user,
                        base_order=base_id,
                        password=password,
                        national_id=national_id,
                        national_code=identity_no,
                        city=city,
                        province=province,
                        father_name=father_name,
                        gender=gender,
                        birthday=birthday_str,
                        is_alive=is_alive
                    )
                    system_profile.save()
                else:
                    failed_records.append({"national_id": national_id, "reason": "در ثبت کاربر مشکلی بوجود آمده است"})
                    continue

            else:
                system_profile.national_id = national_id
                system_profile.national_code = identity_no
                system_profile.father_name = father_name
                system_profile.gender = gender
                system_profile.birthday = birthday_str
                system_profile.is_alive = is_alive
                system_profile.save()

            address = SystemAddress(city=city, province=province, address=address_text,
                                    postal_code=postal_code)
            address.save()
            system_profile.role.add(group)

            if not existing_guild:
                wallet = Wallet()
                wallet.save()
            else:
                wallet = existing_guild.wallet

            role = request.data.get('role', 'ProvinceOperator')

            type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first()
            if not type_activity:
                type_activity = TypeActivity.objects.filter(trash=False).first()

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

            if existing_guild:
                try:
                    guilds = existing_guild
                    guilds.guilds_name = guild_info.get('title', '')
                    guilds.license_number = license_number
                    guilds.license_type = license_type
                    guilds.license_status = license_status
                    guilds.is_foreign_national = is_foreign_national
                    guilds.has_partner = has_partner
                    guilds.has_inquiry = True
                    guilds.steward = steward
                    guilds.company_name = company_name
                    guilds.company_identifier = company_identifier
                    guilds.user = system_profile
                    guilds.registerar_fullname = 'سیستمی'
                    guilds.registerar_mobile = '09000000000'
                    guilds.registerar_role = role
                    guilds.address = address
                    guilds.wallet = wallet
                    guilds.type_activity = type_activity.title if type_activity else type_activity_name
                    guilds.area_activity = area_activity.title if area_activity else ''
                    guilds.guild_type_activity = type_activity
                    guilds.guild_area_activity = area_activity
                    guilds.phone_number = phone_number
                    guilds.union_name = union_name

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

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

                    guilds.save()
                    update_count += 1
                except Exception as e:
                    failed_records.append({"national_id": national_id, "reason": f"خطا در آپدیت: {str(e)}"})
                    continue

            else:
                try:
                    guilds = Guilds(
                        guilds_name=guild_info.get('title', ''),
                        license_number=license_number,
                        license_type=license_type,
                        license_status=license_status,
                        is_foreign_national=is_foreign_national,
                        has_partner=has_partner,
                        has_inquiry=True,
                        steward=steward,
                        company_name=company_name,
                        phone_number=phone_number,
                        union_name=union_name,
                        company_identifier=company_identifier,
                        user=system_profile,
                        registerar_fullname='سیستمی',
                        registerar_mobile='09000000000',
                        registerar_role=role,
                        address=address,
                        wallet=wallet,
                        type_activity=type_activity.title if type_activity else type_activity_name,
                        area_activity=area_activity.title if area_activity else '',
                        province_accept_state='pending',
                        guild_type_activity=type_activity,
                        guild_area_activity=area_activity,
                    )

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

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

                    guilds.save()

                    parent_product = NewProduct.objects.all().first()
                    price = BroadcastPrice.objects.filter(trash=False).first()

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

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

                    if role == 'KillHouse':
                        try:
                            user = SystemUserProfile.objects.get(user=request.user)
                            kill_house = KillHouse.objects.filter(kill_house_operator__user=user, trash=False).order_by(
                                'id').first()
                            if kill_house:
                                guilds.kill_house_centers_allocation = [
                                    {"label": kill_house.name, "value": str(kill_house.key)}]
                                guilds.province_accept_state = 'pending'
                                guilds.kill_house_register = True
                                guilds.save()

                                if guilds.steward == True:
                                    guilds.steward_kill_house.add(kill_house)
                                else:
                                    guilds.kill_house.add(kill_house)
                        except:
                            pass

                    elif role == 'Guilds':
                        try:
                            user = SystemUserProfile.objects.get(user=request.user)
                            steward = Steward.objects.get(guilds__user=user, trash=False)

                            guilds.centers_allocation = [
                                {"label": steward.guilds.user.fullname, "value": str(steward.key)}]
                            guilds.province_accept_state = 'pending'
                            guilds.steward_register = True
                            guilds.save()
                        except:
                            pass

                    elif role == 'PosCompany':
                        guilds.province_accept_state = 'pending'
                        guilds.pos_company_register = True
                        guilds.save()

                    success_count += 1

                except Exception as e:
                    failed_records.append({"national_id": national_id, "reason": f"خطا در ساخت: {str(e)}"})
                    continue

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

    return Response({
        "result": "پردازش کامل شد",
        "success_count": success_count,
        "update_count": update_count,
        "failed_count": len(failed_records),
        "failed_records": failed_records
    }, status=status.HTTP_200_OK)


@api_view(["POST"])
@permission_classes([TokenHasReadWriteScope])
def update_guild_by_national_id(request):
    national_id = request.data.get('national_id')
    has_inquery = request.data.get('has_inquiry')
    update_flag = request.data.get('update_flag')
    mobile = request.data.get('mobile')
    steward = request.data.get('steward', False)
    active_register_code = request.data.get('active_register_code', False)

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

    city_name = request.data.get('city')
    address_text = request.data.get('address')
    postal_code = request.data.get('postalcode')
    license_number = request.data.get('licenseNumber')
    license_expire_date = request.data.get('licenseExpireDate')
    license_issue_date = request.data.get('licenseIssueDate')
    license_type = request.data.get('licenseType')
    license_status = request.data.get('licenseStatus')
    type_activity_name = request.data.get('isicname')
    mobilenumber = request.data.get('mobilenumber')
    company_name = request.data.get('corporationName')
    company_identifier = request.data.get('nationalId')
    union_name = request.data.get('unionName')
    phone = request.data.get('phonenumber')
    has_partner_val = request.data.get('hasPartner')
    is_foreigner_val = request.data.get('isForeigner')
    title = request.data.get('title', '')

    try:
        user = SystemUserProfile.objects.get(tras=False, user=request.user)
        registerar_fullname = user.fullname
        registerar_mobile = user.mobile
    except:
        registerar_fullname = 'سیستمی'
        registerar_mobile = '09000000000'

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

    try:
        if not mobile:
            mobile = mobilenumber

        if not mobile:
            return Response({"result": "شماره موبایل الزامی است"},
                            status=status.HTTP_400_BAD_REQUEST)

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

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

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

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

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

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

        province = city.province

        system_profile = SystemUserProfile.objects.filter(Q(national_id=national_id) | Q(mobile=mobile),
                                                          trash=False).first()
        if not system_profile:
            if not mobile:
                return Response({"result": "شماره موبایل الزامی است"},
                                status=status.HTTP_400_BAD_REQUEST)

            password = "123456"
            data = {
                "username": mobile,
                "password": password,
                "api_key": PROJECT_API_KEY
            }

            try:
                req = requests.post(
                    url=ARTA_URL_REGISTER,
                    data=data,
                    verify=False
                )

                if req.status_code == 200:
                    user = User(username=mobile, first_name=first_name, last_name=last_name)
                    user.save()

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

                    system_profile = SystemUserProfile(
                        mobile=mobile,
                        first_name=first_name,
                        last_name=last_name,
                        fullname=first_name + " " + last_name,
                        user=user,
                        base_order=base_id,
                        password=password,
                        national_id=national_id,
                        national_code=identity_no,
                        city=city,
                        province=province,
                        father_name=father_name,
                        gender=gender,
                        birthday=birthday_str,
                        is_alive=is_alive
                    )
                    system_profile.save()
                else:
                    return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است"},
                                    status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            except Exception as e:
                return Response({"result": f"خطا در ثبت کاربر: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            has_killhouse = system_profile.role.filter(name='KillHouse').exists()
            if has_killhouse:
                if request.GET.get('role') == 'AdminX':
                    if system_profile.national_id == national_id:
                        return Response({"result": "کد ملی به نام {} ثبت شده است!".format(system_profile.fullname)},
                                        status=status.HTTP_403_FORBIDDEN)
                    elif system_profile.mobile == mobile:
                        return Response(
                            {"result": "شماره موبایل به نام {} ثبت شده است!".format(system_profile.fullname)},
                            status=status.HTTP_403_FORBIDDEN)
                return Response({"result": "کاربر قبلا در سامانه ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)

            if mobile and system_profile.mobile != mobile:
                if not has_killhouse:
                    first_mobile_number = system_profile.mobile
                    second_mobile_number = mobile
                    data = {
                        "first_mobile_number": first_mobile_number,
                        "second_mobile_number": second_mobile_number,
                    }
                    req = requests.post(
                        url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                        data=data,
                        verify=False
                    )
                    if req.status_code == 200:
                        user = User.objects.get(id=system_profile.user.id)
                        user.username = second_mobile_number
                        user.save()
                        system_profile.mobile = second_mobile_number
                        system_profile.save()
                    else:
                        return Response({"result": "شماره همراه قبلا در سامانه ثبت شده است!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "شماره همراه قبلا در سامانه ثبت شده است!"},
                                    status=status.HTTP_403_FORBIDDEN)
            system_profile.first_name = first_name
            system_profile.last_name = last_name
            system_profile.fullname = first_name + " " + last_name
            system_profile.national_id = national_id
            system_profile.national_code = identity_no
            system_profile.father_name = father_name
            system_profile.gender = gender
            system_profile.birthday = birthday_str
            system_profile.is_alive = is_alive
            system_profile.city = city
            system_profile.province = province
            system_profile.save()

        address = SystemAddress(city=city, province=province, address=address_text, postal_code=postal_code)
        address.save()

        existing_guild = Guilds.objects.filter(user__national_id=national_id, trash=False, active=True).first()

        if not existing_guild:
            wallet = Wallet()
            wallet.save()
        else:
            wallet = existing_guild.wallet

        type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first()
        if not type_activity:
            type_activity = TypeActivity.objects.filter(trash=False).first()

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

        if existing_guild:
            try:
                guilds = existing_guild
                guilds.guilds_name = title
                guilds.license_number = license_number
                guilds.license_type = license_type
                guilds.license_status = license_status
                guilds.is_foreign_national = is_foreign_national
                guilds.has_partner = has_partner
                guilds.has_inquiry = has_inquery
                guilds.steward = steward
                guilds.company_name = company_name
                guilds.company_identifier = company_identifier
                guilds.user = system_profile
                guilds.registerar_fullname = registerar_fullname
                guilds.registerar_mobile = registerar_mobile
                guilds.address = address
                guilds.wallet = wallet
                guilds.type_activity = type_activity.title if type_activity else type_activity_name
                guilds.area_activity = area_activity.title if area_activity else ''
                guilds.guild_type_activity = type_activity
                guilds.guild_area_activity = area_activity
                guilds.union_name = union_name
                guilds.phone_number = phone
                guilds.active = True

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

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

                guilds.save()

                guilds_group = Group.objects.get(name__exact="Guilds")
                steward_group = Group.objects.get(name__exact="Steward")

                role_changed = False
                if steward:
                    if system_profile.role.filter(name='Guilds').exists():
                        role_changed = True
                        try:
                            req = requests.post(
                                url=ARTA_URL_REMOVE_USER_ROLE,
                                data={"mobile": system_profile.mobile, "role": "Guilds"},
                                verify=False
                            )
                            if req.status_code == 200 or req.status_code == 400:
                                system_profile.role.remove(guilds_group)
                        except:
                            pass
                    if not system_profile.role.filter(name='Steward').exists():
                        system_profile.role.add(steward_group)
                else:
                    if system_profile.role.filter(name='Steward').exists():
                        role_changed = True
                        try:
                            req = requests.post(
                                url=ARTA_URL_REMOVE_USER_ROLE,
                                data={"mobile": system_profile.mobile, "role": "Steward"},
                                verify=False
                            )
                            if req.status_code == 200 or req.status_code == 400:
                                system_profile.role.remove(steward_group)
                        except:
                            pass
                    if not system_profile.role.filter(name='Guilds').exists():
                        system_profile.role.add(guilds_group)

                # اگر نقش عوض شد، StewardAllocation ها را به‌روزرسانی کن
                if role_changed:
                    update_steward_allocations_on_role_change(system_profile, guilds, steward)

                if active_register_code:
                    number = random.randint(10000, 99000)
                    guilds.register_code = number
                    guilds.active_register_code = True
                    guilds.register_date_register_code = datetime.now()
                    guilds.save()

                    try:
                        send_sms_for_guild(guilds)
                    except:
                        pass

                ser_data = GuildsSerializer(guilds).data
                return Response(ser_data, status=status.HTTP_200_OK)

            except Exception as e:
                return Response({"result": f"خطا در به‌روزرسانی صنف: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if request.GET.get('role') in ('AdminX', 'SuperAdmin'):
                province_accept = 'accepted'
            else:
                province_accept = 'pending'
            has_killhouse = system_profile.role.filter(name='KillHouse').exists()
            if has_killhouse:
                return Response({"result": "کاربر قبلا در سامانه ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)
            try:
                guilds = Guilds(
                    guilds_name=title,
                    license_number=license_number,
                    license_type=license_type,
                    license_status=license_status,
                    is_foreign_national=is_foreign_national,
                    has_partner=has_partner,
                    has_inquiry=has_inquery,
                    steward=steward,
                    company_name=company_name,
                    company_identifier=company_identifier,
                    user=system_profile,
                    registerar_fullname=registerar_fullname,
                    registerar_mobile=registerar_mobile,
                    address=address,
                    wallet=wallet,
                    type_activity=type_activity.title if type_activity else type_activity_name,
                    area_activity=area_activity.title if area_activity else '',
                    province_accept_state=province_accept,
                    guild_type_activity=type_activity,
                    guild_area_activity=area_activity,
                    union_name=union_name,
                    phone_number=phone,
                    active=True,
                )

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

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

                guilds.save()

                guilds_group = Group.objects.get(name__exact="Guilds")
                steward_group = Group.objects.get(name__exact="Steward")

                role_changed = False
                if steward:
                    if system_profile.role.filter(name='Guilds').exists():
                        role_changed = True
                        try:
                            req = requests.post(
                                url=ARTA_URL_REMOVE_USER_ROLE,
                                data={"mobile": system_profile.mobile, "role": "Guilds"},
                                verify=False
                            )
                            if req.status_code == 200:
                                system_profile.role.remove(guilds_group)
                        except:
                            pass
                    if not system_profile.role.filter(name='Steward').exists():
                        system_profile.role.add(steward_group)
                else:
                    if system_profile.role.filter(name='Steward').exists():
                        role_changed = True
                        try:
                            req = requests.post(
                                url=ARTA_URL_REMOVE_USER_ROLE,
                                data={"mobile": system_profile.mobile, "role": "Steward"},
                                verify=False
                            )
                            if req.status_code == 200:
                                system_profile.role.remove(steward_group)
                        except:
                            pass
                    if not system_profile.role.filter(name='Guilds').exists():
                        system_profile.role.add(guilds_group)

                # اگر نقش عوض شد، StewardAllocation ها را به‌روزرسانی کن
                if role_changed:
                    update_steward_allocations_on_role_change(system_profile, guilds, steward)

                parent_product = NewProduct.objects.all().first()
                price = BroadcastPrice.objects.filter(trash=False).first()

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

                    product = RolesProducts(
                        parent_product=parent_product,
                        guild=guilds,
                        name='مرغ گرم',
                        approved_price_status=approved_type,
                        approved_price=approved_price,
                    )
                    product.save()
                if active_register_code:
                    number = random.randint(10000, 99000)
                    guilds.register_code = number
                    guilds.active_register_code = True
                    guilds.register_date_register_code = datetime.now()
                    guilds.save()

                    try:
                        send_sms_for_guild(guilds)
                    except:
                        pass
                ser_data = GuildsSerializer(guilds).data
                return Response(ser_data, status=status.HTTP_201_CREATED)

            except Exception as e:
                return Response({"result": f"خطا در ایجاد صنف: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        return Response({"result": f"خطای کلی: {str(e)}"},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(["POST"])
@permission_classes([AllowAny])
def register_legal_guild(request):
    first_name = request.data.get('first_name')
    last_name = request.data.get('last_name')
    national_id = request.data.get('national_id')
    province_name = request.data.get('province')
    address_text = request.data.get('address')
    unit_name = request.data.get('unit_name')
    mobile = request.data.get('mobile')
    city_name = request.data.get('city')

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

    if not mobile:
        return Response({"result": "شماره موبایل الزامی است"},
                        status=status.HTTP_400_BAD_REQUEST)

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

    try:
        user = SystemUserProfile.objects.get(tras=False, user=request.user)
        registerar_fullname = user.fullname
        registerar_mobile = user.mobile
    except:
        registerar_fullname = 'سیستمی'
        registerar_mobile = '09000000000'

    try:
        # جستجوی شهر
        if base_url_for_sms_report == 'ha':
            city = City.objects.filter(name__icontains='همدان', trash=False).first()
        elif base_url_for_sms_report == 'ku':
            city = City.objects.filter(name__icontains='کردستان', trash=False).first()
        elif base_url_for_sms_report == 'ma':
            city = City.objects.filter(name__icontains='مرکزی', trash=False).first()
        else:
            city = City.objects.filter(name__icontains='تست', trash=False).first()
        province = city.province

        system_profile = SystemUserProfile.objects.filter(Q(national_id=national_id) | Q(mobile=mobile),
                                                          trash=False).first()
        if not system_profile:
            password = "123456"
            data = {
                "username": mobile,
                "password": password,
                "api_key": PROJECT_API_KEY
            }

            try:
                req = requests.post(
                    url=ARTA_URL_REGISTER,
                    data=data,
                    verify=False
                )

                if req.status_code == 200:
                    user = User(username=mobile, first_name=first_name, last_name=last_name)
                    user.save()

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

                    system_profile = SystemUserProfile(
                        mobile=mobile,
                        first_name=first_name,
                        last_name=last_name,
                        fullname=first_name + " " + last_name,
                        user=user,
                        base_order=base_id,
                        password=password,
                        national_id=national_id,
                        city=city,
                        province=province,
                    )
                    system_profile.save()
                else:
                    return Response({"result": "در ثبت کاربر مشکلی بوجود آمده است"},
                                    status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            except Exception as e:
                return Response({"result": f"خطا در ثبت کاربر: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            has_killhouse = system_profile.role.filter(name='KillHouse').exists()
            if has_killhouse:
                if request.GET.get('role') == 'AdminX':
                    if system_profile.national_id == national_id:
                        return Response({"result": "کد ملی به نام {} ثبت شده است!".format(system_profile.fullname)},
                                        status=status.HTTP_403_FORBIDDEN)
                    elif system_profile.mobile == mobile:
                        return Response(
                            {"result": "شماره موبایل به نام {} ثبت شده است!".format(system_profile.fullname)},
                            status=status.HTTP_403_FORBIDDEN)
                return Response({"result": "کاربر قبلا در سامانه ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)

            if mobile and system_profile.mobile != mobile:
                if not has_killhouse:
                    first_mobile_number = system_profile.mobile
                    second_mobile_number = mobile
                    data = {
                        "first_mobile_number": first_mobile_number,
                        "second_mobile_number": second_mobile_number,
                    }
                    req = requests.post(
                        url=ARTA_URL_CHANGE_MOBILE_NUMBER,
                        data=data,
                        verify=False
                    )
                    if req.status_code == 200:
                        user = User.objects.get(id=system_profile.user.id)
                        user.username = second_mobile_number
                        user.save()
                        system_profile.mobile = second_mobile_number
                        system_profile.save()
                    else:
                        return Response({"result": "شماره همراه قبلا در سامانه ثبت شده است!"},
                                        status=status.HTTP_403_FORBIDDEN)
                else:
                    return Response({"result": "شماره همراه قبلا در سامانه ثبت شده است!"},
                                    status=status.HTTP_403_FORBIDDEN)

            system_profile.first_name = first_name
            system_profile.last_name = last_name
            system_profile.fullname = first_name + " " + last_name
            system_profile.national_id = national_id
            system_profile.city = city
            system_profile.province = province
            system_profile.save()

        address = SystemAddress(city=city, province=province, address=address_text)
        address.save()

        existing_guild = Guilds.objects.filter(user__national_id=national_id, trash=False, active=True,
                                               is_real_person=False).first()

        if not existing_guild:
            wallet = Wallet()
            wallet.save()
        else:
            wallet = existing_guild.wallet

        type_activity = TypeActivity.objects.filter(trash=False, key=request.data.get('type_activity')).first()
        area_activity = AreaActivity.objects.filter(trash=False).first()

        if existing_guild:
            try:
                guilds = existing_guild
                guilds.guilds_name = unit_name
                guilds.license_number = national_id
                guilds.user = system_profile
                guilds.registerar_fullname = registerar_fullname
                guilds.registerar_mobile = registerar_mobile
                guilds.address = address
                guilds.wallet = wallet
                guilds.type_activity = type_activity.title if type_activity else ''
                guilds.area_activity = area_activity.title if area_activity else ''
                guilds.guild_type_activity = type_activity
                guilds.guild_area_activity = area_activity
                guilds.city_name = city_name
                guilds.province_name = province_name
                guilds.active = True
                guilds.is_real_person = False
                guilds.save()

                guilds_group = Group.objects.get(name__exact="Guilds")
                if not system_profile.role.filter(name='Guilds').exists():
                    system_profile.role.add(guilds_group)

                ser_data = GuildsSerializer(guilds).data
                return Response(ser_data, status=status.HTTP_200_OK)

            except Exception as e:
                return Response({"result": f"خطا در به‌روزرسانی صنف: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        else:
            if request.GET.get('role') in ('AdminX', 'SuperAdmin'):
                province_accept = 'accepted'
            else:
                province_accept = 'pending'
            has_killhouse = system_profile.role.filter(name='KillHouse').exists()
            if has_killhouse:
                return Response({"result": "کاربر قبلا در سامانه ثبت شده است!"}, status=status.HTTP_403_FORBIDDEN)
            try:
                guilds = Guilds(
                    guilds_name=unit_name,
                    license_number=national_id,  # استفاده از national_id به عنوان شماره صنف
                    user=system_profile,
                    registerar_fullname=registerar_fullname,
                    registerar_mobile=registerar_mobile,
                    address=address,
                    wallet=wallet,
                    type_activity=type_activity.title if type_activity else '',
                    area_activity=area_activity.title if area_activity else '',
                    province_accept_state=province_accept,
                    guild_type_activity=type_activity,
                    guild_area_activity=area_activity,
                    city_name=city_name,
                    province_name=province_name,
                    active=True,
                    is_real_person=False,
                )

                guilds.save()

                guilds_group = Group.objects.get(name__exact="Guilds")
                if not system_profile.role.filter(name='Guilds').exists():
                    system_profile.role.add(guilds_group)

                parent_product = NewProduct.objects.all().first()
                price = BroadcastPrice.objects.filter(trash=False).first()

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

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

                ser_data = GuildsSerializer(guilds).data
                return Response(ser_data, status=status.HTTP_201_CREATED)

            except Exception as e:
                return Response({"result": f"خطا در ایجاد صنف: {str(e)}"},
                                status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        return Response({"result": f"خطای کلی: {str(e)}"},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class TotalGuildStewardWarehouseArchiveDashboardViewSet(GenericAPIView):
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = TotalGuildStewardWarehouseArchiveDashboardSerializer
    pagination_class = CustomPagination
    filter_backends = [DjangoFilterBackend]
    filterset_class = GuildsForArchiveFilterSet
    filterset_fields = [
        'guilds_name',
        'user__mobile',
        'user__fullname',
        'user__first_name',
        'user__last_name'

    ]

    def get(self, request):
        date1 = request.GET.get('date1')
        date2 = request.GET.get('date2')
        owner_type = request.GET.get('owner_type')
        if owner_type == 'steward':
            archives_filters = {"trash": False, "steward__isnull": False}
        else:
            archives_filters = {"trash": False, "guild__isnull": False}

        if date1:
            archives_filters['create_date__date__gte'] = date1
            archives_filters['create_date__date__lte'] = date2

        archives = WarehouseArchive.objects.filter(**archives_filters)

        if owner_type == 'steward':
            guilds = Guilds.objects.filter(id__in=archives.values_list('steward__id', flat=True), trash=False)
        else:
            guilds = Guilds.objects.filter(id__in=archives.values_list('guild__id', flat=True), trash=False)

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

        page_size = request.query_params.get('page_size', None)
        if page_size:
            self.pagination_class.page_size = int(page_size)

        page = self.paginate_queryset(guilds)
        if page is not None:
            serializer = self.get_serializer(page, many=True,
                                             context={'date1': date1, 'date2': date2, 'owner_type': owner_type})
            return self.get_paginated_response(serializer.data)

        serializer = self.serializer_class(guilds, many=True,
                                           context={'date1': date1, 'date2': date2, 'owner_type': owner_type})
        return Response(serializer.data, status=status.HTTP_200_OK)


class MarketDailyLimitationViewset(viewsets.ModelViewSet):
    queryset = MarketDailyLimitation.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = MarketDailyLimitationSerializer

    def get_object(self):
        instance, created = MarketDailyLimitation.objects.get_or_create(
            trash=False)
        return instance

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

    def update(self, request, *args, **kwargs):
        user = SystemUserProfile.objects.get(user=request.user, trash=False)
        instance = self.get_object()
        data = request.data.copy()
        data.update({
            "register_fullname": user.fullname,
            "register_mobile": user.mobile,
        })
        serializer = self.get_serializer(instance, data=data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)


class HatchingArchivePercentViewset(viewsets.ModelViewSet):
    queryset = HatchingArchivePercent.objects.filter(trash=False)
    permission_classes = [TokenHasReadWriteScope]
    serializer_class = HatchingArchivePercentSerializer

    def get_object(self):
        instance, created = HatchingArchivePercent.objects.get_or_create(
            trash=False)
        return instance

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

    def update(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([AllowAny])
@csrf_exempt
def check_steward_allocation_role_mismatch(request):
    fixed_count = 0
    problems = []

    steward_guilds = Guilds.objects.filter(steward=True, trash=False, active=True)

    for guild in steward_guilds:
        wrong_allocations = StewardAllocation.objects.filter(
            (Q(guilds=guild) | Q(to_guilds=guild)),
            trash=False
        )

        for allocation in wrong_allocations:
            if allocation.to_cold_house or allocation.other_cold_house:
                continue

            if allocation.guilds == guild:
                allocation.steward = guild
                allocation.guilds = None
            elif allocation.to_guilds == guild:
                allocation.to_steward = guild
                allocation.to_guilds = None

            if allocation.to_cold_house or allocation.other_cold_house:
                pass
            elif allocation.to_steward:
                if allocation.steward:
                    allocation.type = 'steward_steward'
                elif allocation.kill_house:
                    allocation.type = 'killhouse_steward'
            elif allocation.to_guilds:
                if allocation.steward:
                    allocation.type = 'steward_guild'
                elif allocation.kill_house:
                    allocation.type = 'killhouse_guild'

            allocation.save()
            fixed_count += 1

            problems.append({
                'guild_id': guild.id,
                'guild_name': guild.guilds_name,
                'guild_user_mobile': guild.user.mobile if guild.user else None,
                'guild_user_fullname': guild.user.fullname if guild.user else None,
                'allocation_id': allocation.id,
                'allocation_key': str(allocation.key) if allocation.key else None,
                'fixed': True
            })

    normal_guilds = Guilds.objects.filter(steward=False, trash=False, active=True)

    for guild in normal_guilds:
        wrong_allocations = StewardAllocation.objects.filter(
            (Q(steward=guild) | Q(to_steward=guild)),
            trash=False
        )

        for allocation in wrong_allocations:
            if allocation.to_cold_house or allocation.other_cold_house:
                continue

            if allocation.steward == guild:
                allocation.guilds = guild
                allocation.steward = None
            elif allocation.to_steward == guild:
                allocation.to_guilds = guild
                allocation.to_steward = None

            if allocation.to_cold_house or allocation.other_cold_house:
                pass
            elif allocation.to_steward:
                if allocation.steward:
                    allocation.type = 'steward_steward'
                elif allocation.kill_house:
                    allocation.type = 'killhouse_steward'
            elif allocation.to_guilds:
                if allocation.steward:
                    allocation.type = 'steward_guild'
                elif allocation.kill_house:
                    allocation.type = 'killhouse_guild'

            allocation.save()
            fixed_count += 1

            problems.append({
                'guild_id': guild.id,
                'guild_name': guild.guilds_name,
                'guild_user_mobile': guild.user.mobile if guild.user else None,
                'guild_user_fullname': guild.user.fullname if guild.user else None,
                'allocation_id': allocation.id,
                'allocation_key': str(allocation.key) if allocation.key else None,
                'fixed': True
            })

    return Response({
        'result': 'اصلاح کامل شد',
        'total_fixed': fixed_count,
        'fixed_allocations': problems
    }, status=status.HTTP_200_OK)


@api_view(["GET"])
@permission_classes([TokenHasReadWriteScope])
@csrf_exempt
def get_dispenser_user_info(request):
    national_code = request.GET.get('national_code')
    if not national_code:
        return Response({'result': 'ورود کد ملی الزامیست!'}, status=status.HTTP_403_FORBIDDEN)
    if Dispenser.objects.filter(trash=False, user__national_id=national_code).exists():
        return Response({'result': 'این توزیع کننده قبلا ثبت شده!'}, status=status.HTTP_403_FORBIDDEN)
    person_response = requests.get(
        f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person"
    )
    person_data = person_response.json()
    return Response(person_data, status=status.HTTP_200_OK)
