import datetime import hashlib import random import re import difflib from collections import defaultdict, Counter from datetime import timedelta from io import BytesIO import xml.etree.ElementTree as ET import jdatetime import openpyxl import requests from bs4 import BeautifulSoup from dateutil.relativedelta import relativedelta from django.contrib.auth.models import User, Group from django.db.models import Q, F, Sum, Avg, Count, Min from django.http import HttpResponse from django.http import QueryDict, JsonResponse from django.views.decorators.csrf import csrf_exempt from oauth2_provider.contrib.rest_framework.permissions import TokenHasReadWriteScope from oauth2_provider.models import AccessToken from openpyxl import Workbook from openpyxl.styles import Alignment from requests.adapters import HTTPAdapter from requests.packages.urllib3.util.ssl_ import create_urllib3_context from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import api_view, permission_classes from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import AllowAny from rest_framework.response import Response from url_filter.integrations.drf import DjangoFilterBackend from LiveStock.helpers import build_query from panel.ProvinceOperator.serializers import PoultryScienceReportSerializer from panel.filterset import PoultryScienceReportFilterSet from authentication.filterset import ( SystemUserProfileFilteSet ) from authentication.models import SystemUserProfile, Province, SystemAddress, City from authentication.register import ARTA_REGISTER from authentication.sahandsms.sms import USERNAME_SMS_FINANCIAL, PASSWORD_SMS_FINANCIAL, kill_house_price from authentication.serializer.serializer import SystemUserProfileSerializer from authentication.sms_management import send_sms_for_kill_house_not_add_to_inventory, send_sms_for_guild, \ send_sms_for_guild_for_register, steward_allocation_sms, guild_register_password, guild_register_username, \ send_sms_for_sale_bar_for_steward, send_sms_for_sale_bar, send_sms_request from authentication.views import ARTA_URL_CHANGE_MOBILE_NUMBER ARTA_URL_CHECK_USER_EXISTS = "https://userbackend.rasadyar.com/api/check_user_exists/" from general_urls import base_url_for_sms_report from helper_eata import chat_id_mali, token from panel.ProvinceOperator.serializers import \ NewProvinceAutoAllocationSerializer, GuildsSerializer from panel.ProvinceOperator.helpers import guild_steward_allocations_product_warehousing from panel.KillHouse.helpers import kill_house_allocations_product_warehousing, kill_house_archive_warehousing from panel.ReportingPanel.filterset import ( PoultryRequestFilterSet, KillHouseRequestFilterSet, CityOperatorCheckFilterSet, ProvinceOperatorCheckFilterSet, VetOperatorCheckFilterSet, PoultryHatchingFilterSet, PoultryFilterSet, UserProfileFilterSet ) from panel.ReportingPanel.models import SearchFields from panel.models import ( PoultryRequest, KillHouseRequest, CityOperatorCheckRequest, ProvinceCheckOperatorRequest, VetCheckRequest, Poultry, PoultryHatching, ProvinceKillRequest, ProvinceFactorToKillHouse, KillHouseAssignmentInformation, KillHouseFactorToProvince, PovinceInspector, CityOperator, ProvinceOperator, VetFarm, KillHouseVet, ProvinceAutoAllocation, KillHouse, IranProvinces, IranCities, AgeNotificationPoultry, CookieSamasat, LastUpdate, Wallet, KillHouseFreeSaleBarInformation, KillRequest, KillHouseFreeBarInformation, ChickenCommissionPrices, RolesProducts, ColdHouse, StewardAllocation, ProductsTransactions, PosMachineTransactions, POSMachine, Guilds, PosSegmentation, PoultryRequestQuarantineCode, ChainAllocation, ManagementSendSms, StewardFreeSaleBarInformation, POSTransactions, SmsRecipient, EvacuationHatchingDetail, HatchingLossManagement, ChickenAgeRange, PoultryScience, PoultryScienceReport, WarehouseArchive ) from ticket.helper import send_image_to_server_for_poultry_science from panel.poultry.serializers import ( PoultryRequestSerializer, PoultrySerializer, PoultryHatchingSerializer, PoultryRequestForGeneralCasestatusSerializer, ChickenCommissionPricesForDashboardSerializer ) from ticket.models import MessageSupport, TicketSupport from .helper import ( poultry_request_fields, user_fields, city_operator_fields, province_operator_fields, kill_house_operator_fields, vet_operator_fields, poultry_hatching_fields, poultry_filterset_fields, poultry_hatching_filterset_fields ) from .serializer import SearchFieldsSerializer, DetailsGeneraWageSerializer, GenaeralWageSerailizer, \ DashboardDetailsGeneraWageSerializer, NewDetailsGeneraWageSerializer, IranProvinceSerializer, IranCitiesSerializer, \ AgeNotificationPoultrySerilizer, CookieSamasatSerilizer, HatchingLossManagementSerializer from ..KillHouse.helpers import kill_house_allocations_product_warehousing, market_poultry_request_remain_quantity, \ kill_house_cold_house_allocations, cold_house_warehousing, kill_house_free_buying_product_warehousing, \ kill_house_free_sale_product_warehousing from ..ProvinceOperator.helpers import guild_steward_allocations_product_warehousing, \ guild_steward_free_sale_product_warehousing from ..admin import PROJECT_API_KEY from ..convert_date import convert_to_miladi from ..helper_excel import percent_of_losses, create_value, create_header, create_header_freez, shamsi_date, \ excel_description, to_locale_str, convert_str_to_date from ..helper import check_mobile_number from ..validate_headers import PosDeviceValidator def check_quarantine_code(code): session = requests.Session() session.mount('https://', SSLAdapter()) data = {'gid': str(code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') try: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: return True except: return False class CustomPagination(PageNumberPagination): page_size = 10 class ReportingAllPoultryRequests(viewsets.ModelViewSet): queryset = PoultryRequest.objects.all() city_queryset = CityOperatorCheckRequest.objects.all() province_queryset = ProvinceCheckOperatorRequest.objects.all() kill_house_queryset = KillHouseRequest.objects.all() vet_queryset = VetCheckRequest.objects.all() poultry_hatching_queryset = PoultryHatching.objects.all() serializer_class = PoultryRequestSerializer permission_classes = [AllowAny] filter_backends = [DjangoFilterBackend] filterset_class = PoultryRequestFilterSet kill_house_filter_class = KillHouseRequestFilterSet city_operator_filter_class = CityOperatorCheckFilterSet province_operator_filter_class = ProvinceOperatorCheckFilterSet vet_operator_filter_class = VetOperatorCheckFilterSet poultry_hatching_filter_class = PoultryHatchingFilterSet filterset_fields = poultry_request_fields user_filterset_fields = user_fields city_operator_filter_fields = city_operator_fields province_operator_filter_fields = province_operator_fields kill_house_operator_filter_fields = kill_house_operator_fields vet_operator_filter_fields = vet_operator_fields poultry_hatching_filter_fields = poultry_hatching_fields def list(self, request, *args, **kwargs): # refresh(request.user.id) query_val = [] city_operator_query_val = [] province_operator_query_val = [] kill_house_operator_query_val = [] vet_operator_query_val = [] poultry_hatching_query_val = [] user_val = [] poultry_query_li = [] hatching_poultry_li = [] limited_query = [] city_limited_query = [] province_limited_query = [] kill_house_limited_query = [] vet_limited_query = [] poultry_hatching_limited_query = [] limited_dict = {} province_limited_dict = {} city_limited_dict = {} kill_house_limited_dict = {} vet_limited_dict = {} poultry_hatching_limited_dict = {} user_query = [] user_dict = {} values_item = [] total_tons = [] if 'type' in request.GET: if request.GET['value'] != "": if request.GET['type'] == 'filter': if 'value' in request.GET: values = request.GET['value'].split(',') for item in values: if item != "": values_item.append(item) for val in values_item: if not query_val: for item in self.filterset_fields: query = QueryDict('{0}={1}'.format(item, val)) if (self.filterset_class(data=query, queryset=self.queryset)).filter(): ps = self.filterset_class(data=query, queryset=self.queryset) filtered_city_operator = ps.filter() if filtered_city_operator: limited_query.append(query) if not city_operator_query_val: for item in self.city_operator_filter_fields: query = QueryDict('{0}={1}'.format(item, val)) if ( self.city_operator_filter_class(data=query, queryset=self.city_queryset)).filter(): ps = self.city_operator_filter_class(data=query, queryset=self.city_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: city_limited_query.append(query) if not province_operator_query_val: for item in self.province_operator_filter_fields: query = QueryDict('{0}={1}'.format(item, val)) if (self.city_operator_filter_class(data=query, queryset=self.province_queryset)).filter(): ps = self.city_operator_filter_class(data=query, queryset=self.province_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: province_limited_query.append(query) if not kill_house_operator_query_val: for item in self.kill_house_operator_filter_fields: query = QueryDict('{0}={1}'.format(item, val)) if (self.kill_house_filter_class(data=query, queryset=self.kill_house_queryset)).filter(): ps = self.kill_house_filter_class(data=query, queryset=self.kill_house_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: kill_house_limited_query.append(query) if not vet_operator_query_val: for item in self.vet_operator_filter_fields: query = QueryDict('{0}={1}'.format(item, val)) if ( self.vet_operator_filter_class(data=query, queryset=self.vet_queryset)).filter(): ps = self.vet_operator_filter_class(data=query, queryset=self.vet_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: vet_limited_query.append(query) if not poultry_hatching_query_val: for item in self.poultry_hatching_filter_fields: query = QueryDict('{0}={1}'.format(item, val)) if (self.poultry_hatching_filter_class(data=query, queryset=self.poultry_hatching_queryset)).filter(): ps = self.poultry_hatching_filter_class(data=query, queryset=self.poultry_hatching_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: poultry_hatching_limited_query.append(query) if not user_val: for user_item in self.user_filterset_fields: query = QueryDict('{0}__exact={1}'.format(user_item, val)) if (SystemUserProfileFilteSet( data=query, queryset=SystemUserProfile.objects.all()) ).filter(): ps = SystemUserProfileFilteSet( data=query, queryset=SystemUserProfile.objects.all() ) filtered_poultry_user = ps.filter() if filtered_poultry_user: user_query.append(query) for i in limited_query: for key, value in i.items(): limited_dict[key] = value if len(values_item) != len(limited_dict): pass else: for i in PoultryRequest.objects.filter(**limited_dict): query_val.append(i) for i in city_limited_query: for key, value in i.items(): city_limited_dict[key] = value if len(values_item) != len(city_limited_dict): pass else: for i in self.city_queryset.filter(**city_limited_dict): query_val.append(i.poultry_request) for i in province_limited_query: for key, value in i.items(): province_limited_dict[key] = value if len(values_item) != len(province_limited_dict): pass else: for i in self.province_queryset.filter(**province_limited_dict): query_val.append(i.city_request_Poultry.poultry_request) for i in kill_house_limited_query: for key, value in i.items(): kill_house_limited_dict[key] = value if len(values_item) != len(kill_house_limited_dict): pass else: for i in self.kill_house_queryset.filter(**kill_house_limited_dict): query_val.append(i.province_request.city_request_Poultry.poultry_request) for i in vet_limited_query: for key, value in i.items(): vet_limited_dict[key] = value if len(values_item) != len(vet_limited_dict): pass else: for i in self.vet_queryset.filter(**vet_limited_dict): query_val.append( i.kill_house_request.province_request.city_request_Poultry.poultry_request) for i in poultry_hatching_limited_query: for key, value in i.items(): poultry_hatching_limited_dict[key] = value if len(values_item) != len(poultry_hatching_limited_dict): pass else: for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict): poultry_query_li.append(i.poultry) hatching_poultry_li.append(i) for i in user_query: for key, value in i.items(): user_dict[key] = value if len(values_item) != len(user_dict): pass else: for i in SystemUserProfile.objects.filter(**user_dict): user_val.append(i) if 'hatching_date' in request.GET: date_li = [] query_li = [] if request.GET['hatching_date'] != "": date = request.GET['hatching_date'].split(',') date_split_1 = date[0].split('-') date_split_2 = date[1].split('-') main_date_1 = datetime.datetime( int(date_split_1[0]), int(date_split_1[1]), int(date_split_1[2]) ) main_date_2 = datetime.datetime( int(date_split_2[0]), int(date_split_2[1]), int(date_split_2[2]) ) date_li.append(main_date_1) date_li.append(main_date_2) for i in PoultryHatching.objects.all(): if date_li[0] <= i.date <= date_li[1]: if i.poultry not in poultry_query_li: poultry_query_li.append(i.poultry) if 'hatching_info' in request.GET: serializer = PoultryHatchingSerializer(hatching_poultry_li, many=True) data = {'hatching_info': serializer.data} return Response(data, status=status.HTTP_200_OK) if 'number_of_incubators' in request.GET: if request.GET['number_of_incubators'] != "": num = request.GET['number_of_incubators'].split(',') for i in PoultryHatching.objects.all(): if int(num[0]) <= int(i.quantity) <= int(num[1]): if i.poultry not in poultry_query_li: poultry_query_li.append(i.poultry) if 'number_of_requests' in request.GET: if request.GET['number_of_requests'] != "": num = request.GET['number_of_requests'].split(',') for i in Poultry.objects.all(): if int(num[0]) <= int(i.number_of_requests) <= int(num[1]): if i not in poultry_query_li: poultry_query_li.append(i) if 'total_capacity' in request.GET: if request.GET['total_capacity'] != "": num = request.GET['total_capacity'].split(',') for i in Poultry.objects.all(): if int(num[0]) <= int(i.total_capacity) <= int(num[1]): if i not in poultry_query_li: poultry_query_li.append(i) if 'tons_for_slaughter' in request.GET: total = 0 total_li = [] if request.GET['tons_for_slaughter'] != "": tons_date = request.GET['tons_for_slaughter'] date_split = tons_date.split('-') main_date = (jdatetime.datetime( int(date_split[0]), int(date_split[1]), int(date_split[2])).togregorian()) for item in self.queryset: if item.send_date.strftime("%Y-%m-%d") == main_date.strftime("%Y-%m-%d"): total += item.quantity total_li.append(item) serializer = self.serializer_class(total_li, many=True) return Response({'poultry_req': serializer.data, 'total_quantity': total}) if 'total_tons_in_date' in request.GET: if request.GET['total_tons_in_date'] != "": age_li = [] total_tons_split = request.GET['total_tons_in_date'].split(',') total = 0 splited_date = total_tons_split[0].split('-') date1 = jdatetime.date( int(splited_date[0]), int(splited_date[1]), int(splited_date[2]) ).togregorian() for item in PoultryHatching.objects.all(): if item.date != None: date2 = datetime.date( int(item.date.year), int(item.date.month), int(item.date.day), ) age = (date1 - date2) if 48 >= age.days >= int(total_tons_split[1]): total += item.quantity total_tons.append(item.poultry) age_li.append(age.days) if 'show' in request.GET: if request.GET['show'] == 'active': poultry_req = self.queryset.filter(final_state="pending") serializer = self.serializer_class(poultry_req, many=True) return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK) if request.GET['show'] == "deactive": poultry_req = self.queryset.filter(final_state="complete") serializer = self.serializer_class(poultry_req, many=True) return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK) if request.GET['show'] == "all": poultry_req = self.queryset serializer = self.serializer_class(poultry_req, many=True) return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK) serializer = self.serializer_class(query_val, many=True) user_serializer = SystemUserProfileSerializer(user_val, many=True) poultry_serializer = PoultrySerializer(poultry_query_li, many=True) final_output_data = { 'poultry_req': serializer.data, 'poultry': poultry_serializer.data, 'user_detail': user_serializer.data, } return Response(final_output_data, status=status.HTTP_200_OK) serializer = PoultryRequestSerializer( self.queryset.filter(send_date=(datetime.datetime.now() - datetime.timedelta(days=1))), many=True ) data = {'poultry_req': serializer.data} return Response(data, status=status.HTTP_200_OK) class SearchFieldsViewSet(viewsets.ModelViewSet): queryset = SearchFields.objects.all() serializer_class = SearchFieldsSerializer permission_classes = [TokenHasReadWriteScope] class NewReportingAllPoultryRequests(viewsets.ModelViewSet): userprofile_queryset = SystemUserProfile.objects.all() userprofile_serializer_class = SystemUserProfileSerializer userprofile_filterset_class = UserProfileFilterSet queryset = Poultry.objects.all() serializer_class = PoultrySerializer permission_classes = [TokenHasReadWriteScope] filter_backends = [DjangoFilterBackend] filterset_class = PoultryFilterSet poultry_filterset_f = poultry_filterset_fields poultry_hatching_queryset = PoultryHatching.objects.all() poultry_hatching_filter_class = PoultryHatchingFilterSet poultry_hatching_filterset_f = poultry_hatching_filterset_fields poultry_hatching_serializer_class = PoultryHatchingSerializer def list(self, request, *args, **kwargs): # refresh(request.user.id) query_val = [] poultry_hatching_query_val = [] limited_dict = {} values_item = [] limited_query = [] poultry_hatching_limited_query = [] poultry_hatching_limited_dict = {} if request.GET['type'] == 'filter': if 'value' in request.GET and request.GET['value'] != "": values = request.GET['value'].split(',') for item in values: if item != "": values_item.append(item) for val in values_item: if not query_val: for item in self.poultry_filterset_f: query = QueryDict('{0}={1}'.format(item, val)) if (self.filterset_class(data=query, queryset=self.queryset)).filter(): ps = self.filterset_class(data=query, queryset=self.queryset) filtered_poultry = ps.filter() if filtered_poultry: limited_query.append(query) if not poultry_hatching_query_val: for item in self.poultry_hatching_filterset_f: query = QueryDict('{0}={1}'.format(item, val)) if (self.poultry_hatching_filter_class(data=query, queryset=self.poultry_hatching_queryset)).filter(): ps = self.poultry_hatching_filter_class(data=query, queryset=self.poultry_hatching_queryset) filtered_city_operator = ps.filter() if filtered_city_operator: poultry_hatching_limited_query.append(query) for i in limited_query: for key, value in i.items(): limited_dict[key] = value # # if len(values_item) != len(limited_dict): # pass # else: if len(limited_dict) > 0: for i in Poultry.objects.filter(**limited_dict): query_val.append(i) for i in poultry_hatching_limited_query: for key, value in i.items(): poultry_hatching_limited_dict[key] = value # if len(values_item) == len(poultry_hatching_limited_dict): # pass # else: for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict): if i.poultry in query_val: pass else: if len(limited_dict) > 0: pass else: query_val.append(i.poultry) values_item_count = len(values_item) if values_item_count != len(limited_dict): if len(poultry_hatching_limited_dict) == 0: query_val = [] if 'double_hatching_date' in request.GET: date_li = [] query_li = [] if request.GET['double_hatching_date'] != "": date = request.GET['double_hatching_date'].split(',') date_split_1 = date[0].split('-') date_split_2 = date[1].split('-') main_date_1 = datetime.datetime( int(date_split_1[0]), int(date_split_1[1]), int(date_split_1[2]) ) main_date_2 = datetime.datetime( int(date_split_2[0]), int(date_split_2[1]), int(date_split_2[2]) ) date_li.append(main_date_1) date_li.append(main_date_2) for i in PoultryHatching.objects.all(): if date_li[0].year <= i.date.year and date_li[0].month <= i.date.month and date_li[ 0].day <= i.date.day and i.date.year <= date_li[1].year and i.date.month <= date_li[ 1].month and i.date.day <= date_li[1].day: if i.poultry not in query_val: query_val.append(i.poultry) if 'single_hatching_date' in request.GET: date_li = [] query_li = [] if request.GET['single_hatching_date'] != "": date = request.GET['single_hatching_date'] date_split = date.split('-') main_date = datetime.datetime( int(date_split[0]), int(date_split[1]), int(date_split[2]) ) date_li.append(main_date) for i in PoultryHatching.objects.all(): if date_li[0].year == i.date.year and date_li[0].month == i.date.month and date_li[ 0].day == i.date.day: if i.poultry not in query_val: query_val.append(i.poultry) if 'double_age' in request.GET: age = request.GET['double_age'].split(',') age1 = int(age[0]) age2 = int(age[1]) hatching = PoultryHatching.objects.filter(state='pending') if hatching.count() > 0: for hatch in hatching: chicken_age = (datetime.datetime.now() - hatch.date).days + 1 if age1 <= chicken_age and chicken_age <= age2: if hatch.poultry in query_val: pass else: query_val.append(hatch.poultry) if 'single_age' in request.GET: age = int(request.GET['single_age']) hatching = PoultryHatching.objects.filter(state='pending') if hatching.count() > 0: for hatch in hatching: chicken_age = (datetime.datetime.now() - hatch.date).days + 1 if age == chicken_age: if hatch.poultry in query_val: pass else: query_val.append(hatch.poultry) serializer = self.serializer_class(query_val, many=True) return Response(serializer.data, status=status.HTTP_200_OK) class ForcastViewSet(viewsets.ModelViewSet): queryset = PoultryHatching.objects.all() permission_classes = [TokenHasReadWriteScope] serializer_class = PoultryHatchingSerializer def list(self, request, *args, **kwargs): # refresh(request.user.id) user = SystemUserProfile.objects.get(user=request.user) from datetime import datetime, timedelta date1 = datetime.strptime(request.GET['date1'], '%Y-%m-%d') date2 = datetime.strptime(request.GET['date2'], '%Y-%m-%d') d = request.GET['day'] days_interval = (date2 - date1).days hatching_dict = {} quantity = 0 poultry_list_id = [] poultry_list = [] interal_dict = {} final_list = [] hatchs = PoultryHatching.objects.filter(poultry__address__province=user.province, state='pending') if hatchs.count() > 0: for i in range(days_interval + 1): first_date = date1 + timedelta(days=i) second_date = first_date - timedelta(days=int(d)) for hatch in hatchs: if hatch.date.year == second_date.year and hatch.date.month == second_date.month and hatch.date.day == second_date.day: quantity += hatch.quantity if hatch.poultry in poultry_list: pass else: poultry_list.append(hatch.poultry) for p in poultry_list: interal_dict = { "name": p.user.fullname, "mobile": p.user.mobile, "unitname": p.unit_name, "province": p.user.province.name, "city": p.user.city.name, } poultry_list_id.append(interal_dict) hatching_dict.update({"date": str(first_date), "quantity": quantity, "poultry": poultry_list_id}) quantity = 0 final_list.append(hatching_dict) hatching_dict = {} poultry_list_id = [] poultry_list = [] return Response(final_list, status=status.HTTP_200_OK) class PoultryReporttViewSet(viewsets.ModelViewSet): queryset = PoultryHatching.objects.all() permission_classes = [TokenHasReadWriteScope] serializer_class = PoultryHatchingSerializer def list(self, request, *args, **kwargs): # refresh(request.user.id) user = SystemUserProfile.objects.get(user=request.user) poultry_request_list = [] dates = [] hatching_list = [] average_weight_chart_list = [] quantity = 0 losses = 0 poultry_requests = PoultryRequest.objects.filter(poultry__user=user, trash=False).order_by('send_date') if poultry_requests.count() > 0: for poultry_request in poultry_requests: total_amount = 0 average_weight = 0 average_fee = 0 sales_price = 0 paid_state = None if ProvinceKillRequest.objects.filter( province_request__city_request_Poultry__poultry_request=poultry_request, state='accepted').exists(): age = (poultry_request.send_date - poultry_request.hatching.date).days + 1 else: age = (datetime.datetime.now() - poultry_request.hatching.date).days + 1 poultry_request_dict = { "hatching_period": poultry_request.hatching.period, "date": poultry_request.send_date.date(), "hatching_date": poultry_request.hatching.date, "hatching_chicken_breed": poultry_request.hatching.chicken_breed, "quantity": poultry_request.quantity, "age": age, "weight_of_suffering": 2.5, "request_id": poultry_request.id, } province_factors = ProvinceFactorToKillHouse.objects.filter( province_check_req__poultry_request=poultry_request) if province_factors.count() > 0: factor_count = province_factors.count() factor_counter = 0 paid_state = 'pending' for factor in province_factors: if factor.poultry_factor != None: total_amount += factor.poultry_factor.shares['poultryShareWithProfit'] if factor.poultry_factor.paid_state == 'paid': factor_counter += 1 else: total_amount += factor.shares['poultryShareWithProfit'] if factor.paid_state == 'paid': factor_counter += 1 average_weight += factor.total_weight sales_price += factor.factor_fee average_fee = factor.province_check_req.fee if factor_count == factor_counter: paid_state = 'paid' sales_price = sales_price / factor_count average_weight = average_weight / factor_count average_weight_dict = { "date": poultry_request.send_date.date(), "weight": average_weight, } average_weight_chart_list.append(average_weight_dict) poultry_request_dict.update({ "total_amount": total_amount, "average_weight": average_weight, "average_fee": average_fee, "sales_price": sales_price, "paid_state": paid_state, }) poultry_request_list.append(poultry_request_dict) poultry_hatchings = PoultryHatching.objects.filter(trash=False).order_by('date') if poultry_hatchings.count() > 0: for poultry_hatching in poultry_hatchings: if poultry_hatching.date.date() in dates: pass else: dates.append(poultry_hatching.date.date()) for date in dates: hatching = PoultryHatching.objects.filter(date__year=date.year, date__month=date.month, date__day=date.day) for hatch in hatching: quantity += hatch.quantity losses += hatch.losses internal_hatching_dict = { "date": date, "quantity": quantity, "losses": losses, } hatching_list.append(internal_hatching_dict) quantity = 0 losses = 0 final_dict = { "table": poultry_request_list, "hatching_chart": hatching_list, "weight_chart": average_weight_chart_list, } return Response(final_dict, status=status.HTTP_200_OK) # ویوست مربوط به نامه جهاد واستانداری class PoultryRequestletterReportViewSet(viewsets.ModelViewSet): queryset = PoultryRequest.objects.all() permission_classes = [AllowAny] serializer_class = PoultryRequestSerializer def list(self, request, *args, **kwargs): province = Province.objects.get(id=2) from datetime import datetime # refresh(request.user.id) if 'general_report' in request.GET: date = datetime.strptime(request.GET['date'], '%Y-%m-%d') poultry_requests_list = [] poultry_requests_dict = {} poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province, send_date__year=date.year, send_date__month=date.month, send_date__day=date.day).order_by('send_date') if poultry_requests.count() > 0: for poultry_request in poultry_requests: poultry_requests_dict.update({ 'poultry_name': poultry_request.poultry.unit_name, 'quantity': poultry_request.previous_quantity, 'weight': poultry_request.Index_weight, 'age': (poultry_request.send_date.date() - poultry_request.hatching.date.date()).days + 1, 'confirmed_quantity': poultry_request.quantity, 'remain_quantity': poultry_request.hatching.left_over, }) poultry_requests_list.append(poultry_requests_dict) poultry_requests_dict = {} return Response(poultry_requests_list, status=status.HTTP_200_OK) elif 'daily_report' in request.GET: now = datetime.now().date() date_list = [] hatching_list = [] poultry_request_detail_list = [] poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province).order_by('-send_date') if poultry_requests.count() > 0: for poultry_request in poultry_requests: if poultry_request.send_date.date() in date_list: pass else: date_list.append(poultry_request.send_date.date()) for date in date_list: quantity = 0 remain_quantity = 0 province_quantity = 0 average_weight = 0 total_poultry_request_quantity = 0 accepted_request_quantity = 0 poultry_requests_list = PoultryRequest.objects.filter(poultry__address__province=province, send_date__year=date.year, send_date__month=date.month, send_date__day=date.day) for internal_poultry_reqs in poultry_requests_list: if internal_poultry_reqs.hatching in hatching_list: pass else: hatching_list.append(internal_poultry_reqs.hatching) remain_quantity += internal_poultry_reqs.hatching.left_over quantity += internal_poultry_reqs.previous_quantity average_weight += internal_poultry_reqs.Index_weight province_quantity += internal_poultry_reqs.quantity total_poultry_request_quantity += internal_poultry_reqs.quantity if internal_poultry_reqs.province_state == 'accepted': accepted_request_quantity += internal_poultry_reqs.quantity average_weight = round(average_weight / poultry_requests_list.count(), 2) poultry_request_detail_list.append({ 'today': now, 'date': date, 'province': province.name, 'previous_quantity': quantity, 'index_weight': average_weight, 'province_quantity': province_quantity, 'remain_quantity': remain_quantity, 'country_quantity': 0, 'total_poultry_request_quantity': total_poultry_request_quantity, 'accepted_request_quantity': accepted_request_quantity, }) return Response(poultry_request_detail_list, status=status.HTTP_200_OK) class CasestatusViewSet(viewsets.ModelViewSet): queryset = PoultryRequest.objects.all() permission_classes = [AllowAny] serializer_class = PoultryRequestSerializer def list(self, request, *args, **kwargs): poultry_request_list = [] user = SystemUserProfile.objects.get(user=request.user) date = datetime.datetime.strptime(str(request.GET['date']), '%Y-%m-%d') if request.GET['role'] == 'CityOperator': city_operator = CityOperator.objects.get(user=user, trash=False) poultry_requests = PoultryRequest.objects.filter(send_date__date=date, poultry__city_operator=city_operator.unit_name, trash=False).order_by('id') elif request.GET['role'] in ['VetFarm', 'CityCommerce', 'CityJahad', 'CityPoultry']: poultry_requests = PoultryRequest.objects.filter(send_date__date=date, poultry__address__city=user.city, trash=False).order_by('id') else: poultry_requests = PoultryRequest.objects.filter(send_date__date=date, poultry__address__province=user.province, trash=False).order_by('id') if poultry_requests: for poultry_request in poultry_requests: vet_farm = VetFarm.objects.filter(poultry=poultry_request.poultry, trash=False) if vet_farm.count() > 0: vet_farm = vet_farm.last() vet_farm_name = vet_farm.vet.user.fullname vet_farm_mobile = vet_farm.vet.user.mobile else: vet_farm_name = None vet_farm_mobile = None poultry_request_dict = {} poultry_request_dict.update({"poultry": { "user_fullname": poultry_request.poultry.user.fullname, "user_mobile": poultry_request.poultry.user.mobile, "poultry_name": poultry_request.poultry.unit_name, "poultry_city": poultry_request.poultry.address.city.name, "poultry_province": poultry_request.poultry.address.province.name, "poultry_request_quantity": poultry_request.quantity, "poultry_request_remain_quantity": poultry_request.remain_quantity, "freezing": poultry_request.freezing, "chicken_breed": poultry_request.chicken_breed, "send_date": poultry_request.send_date, "index_weight": poultry_request.Index_weight, "vet_farm_name": vet_farm_name, "vet_farm_mobile": vet_farm_mobile, } }) city_operator = CityOperator.objects.filter(key=poultry_request.city_operator.key, trash=False) if city_operator: city_operator = city_operator.last() city_operator_name = city_operator.user.fullname city_operator_mobile = city_operator.user.mobile city_operator_province = city_operator.address.province.name city_operator_city = city_operator.address.city.name else: city_operator_name = None city_operator_mobile = None city_operator_province = None city_operator_city = None city = CityOperatorCheckRequest.objects.filter(poultry_request=poultry_request, trash=False) if city: city = city.last() poultry_request_dict['city_state'] = { "operator_name": city_operator_name, "operator_mobile": city_operator_mobile, "operator_province": city_operator_province, "operator_city": city_operator_city, "state": city.state, } else: poultry_request_dict['city_state'] = { "operator_name": city_operator_name, "operator_mobile": city_operator_mobile, "operator_province": city_operator_province, "operator_city": city_operator_city, "state": 'pending', } role = Group.objects.get(name='ProvinceOperator') province_operator = ProvinceOperator.objects.filter( address__province__name=poultry_request.poultry.address.province.name, user__role=role, trash=False) if province_operator: province_operator = province_operator.last() province_operator_name = province_operator.user.fullname province_operator_mobile = province_operator.user.mobile province_operator_provinc = province_operator.address.province.name province_operator_city = province_operator.address.city.name else: province_operator_name = None province_operator_mobile = None province_operator_provinc = None province_operator_city = None province = ProvinceCheckOperatorRequest.objects.filter(poultry_request=poultry_request, trash=False) if province: province = province.last() poultry_request_dict['province_state'] = { "province_operator_name": province_operator_name, "province_operator_mobile": province_operator_mobile, "province_operator_provinc": province_operator_provinc, "province_operator_city": province_operator_city, "state": province.state, } else: poultry_request_dict.update({"province_state": { "province_operator_name": province_operator_name, "province_operator_mobile": province_operator_mobile, "province_operator_provinc": province_operator_provinc, "province_operator_city": province_operator_city, "state": 'pending', }}) province_kill_requests = ProvinceKillRequest.objects.filter(trash=False, province_request__poultry_request=poultry_request) if province_kill_requests: province_kill_request_list = [] for province_kill_request in province_kill_requests: province_kill_request_dict = {} province_kill_request_dict = { "state": province_kill_request.state, "buyer_name": province_kill_request.kill_request.kill_house.name, "buyer_mobile": province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile, "quantity": province_kill_request.main_quantity, } buyer_type = None if province_kill_request.kill_request.kill_house.killer == False: buyer_type = 'kill_house' else: buyer_type = 'killer' province_kill_request_dict.update({ "buyer_type": buyer_type, }) kill_house_requests = KillHouseRequest.objects.filter(trash=False, province_kill_request=province_kill_request) if kill_house_requests: kill_house_request_list = [] for kill_house_request in kill_house_requests: kill_house_vet = KillHouseVet.objects.filter( kill_house=kill_house_request.kill_request.kill_house, trash=False) if kill_house_vet.count() > 0: kill_house_vet = kill_house_vet.last() kill_house_vet_name = kill_house_vet.vet.user.fullname kill_house_vet_mobile = kill_house_vet.vet.user.mobile else: kill_house_vet_name = None kill_house_vet_mobile = None kill_house_request_dict = {} kill_house_request_dict = { "vet_state": kill_house_request.vet_state, "kill_house_vet_name": kill_house_vet_name, "kill_house_vet_mobile": kill_house_vet_mobile, "driver_name": kill_house_request.add_car.driver.driver_name, "driver_mobile": kill_house_request.add_car.driver.driver_mobile, "pelak": kill_house_request.add_car.driver.pelak, "health_code": kill_house_request.add_car.driver.health_code, "quantity": kill_house_request.quantity, "traffic_code": kill_house_request.traffic_code, "clearance_code": kill_house_request.clearance_code, "bar_code": kill_house_request.bar_code, } bar = KillHouseAssignmentInformation.objects.filter(trash=False, kill_house_request=kill_house_request) if bar: bar = bar.last() kill_house_request_dict.update({ "bar": { "car_weight_without_load": bar.car_weight_without_load, "car_weight_without_load_image": bar.car_weight_without_load_image, "car_weight_with_load": bar.car_weight_with_load, "car_weight_with_load_image": bar.car_weight_with_load_image, "net_weight": bar.net_weight, "state": bar.state, "real_quantity": bar.real_quantity, "exploited_carcass": bar.exploited_carcass } }) else: kill_house_request_dict.update({ "bar": None }) province_factor = ProvinceFactorToKillHouse.objects.filter( province_check_info__kill_house_assignment__kill_house_request=kill_house_request, trash=False) if province_factor: province_factor = province_factor.last() kill_house_request_dict.update({"province_factor": { "total_weight": province_factor.total_weight, "factor_fee": province_factor.factor_fee, "total_price": province_factor.total_price, "paid_state": province_factor.paid_state, } }) else: kill_house_request_dict.update({"province_factor": None}) kill_house_factor = KillHouseFactorToProvince.objects.filter( province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request, trash=False) if kill_house_factor: kill_house_factor = kill_house_factor.last() kill_house_request_dict.update({"kill_house_factor": { "payment_code": kill_house_factor.payment_code, "state": kill_house_factor.state, "factor_image": kill_house_factor.factor_image, "message": kill_house_factor.message, } }) else: kill_house_request_dict.update({"kill_house_factor": None}) kill_house_request_list.append(kill_house_request_dict) province_kill_request_dict.update({"kill_house_requests": kill_house_request_list}) else: province_kill_request_dict.update({"kill_house_requests": None}) province_kill_request_list.append(province_kill_request_dict) poultry_request_dict.update({"province_kill_requests": province_kill_request_list}) else: poultry_request_dict.update({"province_kill_requests": None}) province_inspector = PovinceInspector.objects.filter(poultry_request=poultry_request, trash=False) if province_inspector: province_inspector = province_inspector.last() poultry_request_dict.update({"province_inspector": { "state": province_inspector.state }}) else: poultry_request_dict.update({"province_inspector": None}) poultry_request_list.append(poultry_request_dict) return Response(poultry_request_list, status=status.HTTP_200_OK) class GeneralCasestatusViewSet(viewsets.ModelViewSet): queryset = PoultryRequest.objects.all() permission_classes = [AllowAny] serializer_class = PoultryRequestSerializer pagination_class = CustomPagination filter_backends = [DjangoFilterBackend] filterset_class = PoultryRequestFilterSet filterset_fields = [ 'poultry__unit_name', 'poultry__user__fullname', 'poultry__user__mobile', 'order_code', ] def list(self, request, *args, **kwargs): poultry_reqs = [] poultry_requests = [] user = SystemUserProfile.objects.get(user=request.user) date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if request.GET['role'] == 'CityOperator': city_operator = CityOperator.objects.get(user=user) poultry_reqs = PoultryRequest.objects.filter( poultry__address__province=user.province, poultry__city_operator=city_operator.unit_name, send_date__date__gte=date1, send_date__date__lte=date2, trash=False ).order_by('id').select_related('poultry__user') elif request.GET['role'] == 'CityCommerce' or request.GET['role'] == 'VetFarm': poultry_reqs = PoultryRequest.objects.filter( poultry__address__province=user.province, poultry__address__city=user.city, send_date__date__gte=date1, send_date__date__lte=date2, trash=False ).order_by('id').select_related('poultry__user') else: poultry_reqs = PoultryRequest.objects.filter( poultry__address__province=user.province, send_date__date__gte=date1, send_date__date__lte=date2, trash=False).order_by('id').select_related('poultry__user') if 'search' in request.GET: if request.GET['search'] == 'filter': if request.GET['value'] != "": for item in self.filterset_fields: query = QueryDict('{0}__contains={1}'.format(item, request.GET['value'])) if (self.filterset_class( data=query, queryset=poultry_reqs ) ).filter(): ps = self.filterset_class(data=query, queryset=poultry_reqs) poultry_requests = ps.filter() poultry_reqs = [] if len(poultry_requests) == 0 else poultry_requests page_size = request.query_params.get('page_size', None) if page_size: self.pagination_class.page_size = int(page_size) page = self.paginate_queryset(poultry_reqs) if page is not None: serializer = PoultryRequestForGeneralCasestatusSerializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = PoultryRequestForGeneralCasestatusSerializer(poultry_reqs, many=True) return Response(serializer.data, status=status.HTTP_200_OK) class HatchingQueryViewSet(viewsets.ModelViewSet): queryset = PoultryHatching serializer_class = PoultryHatchingSerializer permission_classes = [AllowAny] def list(self, request, *args, **kwargs): hatchings = PoultryHatching.objects.filter(trash=False).order_by('-date') if hatchings: hatchings_list = [] quantity = 0 for hatching in hatchings: poultry_requests = PoultryRequest.objects.filter( hatching=hatching, trash=False, state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted') ) quantity_req = sum(poultry_req.quantity for poultry_req in poultry_requests) quantity += hatching.quantity hatching_dict = { "poultry_name": hatching.poultry.unit_name, "quantity": hatching.quantity, "breed": hatching.breed, "left_over": hatching.left_over, "date": hatching.date.date(), "period": hatching.period, "poultry_request": quantity_req } hatchings_list.append(hatching_dict) return Response(hatchings_list) class BuyerRemittance(viewsets.ModelViewSet): queryset = ProvinceAutoAllocation.objects.all() permission_classes = [AllowAny] serializer_class = NewProvinceAutoAllocationSerializer def list(self, request, *args, **kwargs): if 'allocation_key' in request.GET: serializer = NewProvinceAutoAllocationSerializer( ProvinceAutoAllocation.objects.filter(key=request.GET['allocation_key'], trash=False, ).select_related( 'poultry_request'), many=True) return Response(serializer.data, status=status.HTTP_200_OK) elif 'poultry_request_key' in request.GET: poultry_request = PoultryRequest.objects.filter(key=request.GET['poultry_request_key']).prefetch_related( 'poultry_request_auto_quantity_province', ).last() province_auto_allocations = poultry_request.poultry_request_auto_quantity_province.all().select_related( 'poultry_request', 'province_kill_request', 'daily_quota__kill_house__kill_house_operator__user', 'daily_quota__killer_kill_house__kill_house_operator__user') poultry_requests_list = [] kill_house_list = [] killer_list = [] for a in province_auto_allocations: if a.poultry_request not in poultry_requests_list: poultry_requests_list.append(a.poultry_request) num1 = 0 for b in province_auto_allocations: if b.daily_quota == a.daily_quota: num1 += b.quantity * b.poultry_request.Index_weight dict1 = { "buyer_name": a.daily_quota.kill_house.name, "weight": num1 } if dict1 not in killer_list: killer_list.append(dict1) if a.daily_quota.killer_kill_house == None: for b in province_auto_allocations: if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house: num1 += b.quantity * b.poultry_request.Index_weight dict2 = { "kill_house_name": a.daily_quota.kill_house.name, "weight": num1 } if dict2 not in kill_house_list: kill_house_list.append(dict2) allocation_list = [] for allocation in province_auto_allocations: if allocation.daily_quota.killer_kill_house: kill_house = allocation.daily_quota.killer_kill_house else: kill_house = allocation.daily_quota.kill_house allocation_dict = { "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname, "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile, "quantity": allocation.quantity, "kill_house": { "kill_house_fullname": kill_house.kill_house_operator.user.fullname, "kill_house_mobile": kill_house.kill_house_operator.user.mobile, } } allocation_list.append(allocation_dict) internal_poultry_req_dict = { "poultry_fullname": poultry_request.poultry.user.fullname, "base_order": poultry_request.poultry.user.base_order, "poultry_mobile": poultry_request.poultry.user.mobile, "poultry_quantity": poultry_request.quantity, "index_weight": poultry_request.Index_weight, "date": poultry_request.send_date, "allocations": allocation_list, } final_dict = { "poultry": internal_poultry_req_dict, "buyer": killer_list, "kill_house": kill_house_list } return Response(final_dict, status=status.HTTP_200_OK) elif 'auto_allocation' in request.GET: now = datetime.datetime.now().date() date = datetime.datetime.strptime(str(request.GET['date']), '%Y-%m-%d').date() if 'date' in request.GET else now allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related( 'poultry_request', 'province_kill_request', 'daily_quota__kill_house__kill_house_operator__user', 'daily_quota__killer_kill_house__kill_house_operator__user' ) poultry_requests_list = [] final_poultry_requests_list = [] kill_house_list = [] killer_list = [] for a in allocations: if a.poultry_request not in poultry_requests_list: poultry_requests_list.append(a.poultry_request) num1 = 0 for b in allocations: if b.daily_quota == a.daily_quota: num1 += b.quantity * b.poultry_request.Index_weight dict1 = { "buyer_name": a.daily_quota.kill_house.name, "weight": num1 } if dict1 not in killer_list: killer_list.append(dict1) if a.daily_quota.killer_kill_house == None: for b in allocations: if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house: num1 += b.quantity * b.poultry_request.Index_weight dict2 = { "kill_house_name": a.daily_quota.kill_house.name, "weight": num1 } if dict2 not in kill_house_list: kill_house_list.append(dict2) allocation_list = [] for poultry_request in poultry_requests_list: for allocation in allocations: if allocation.poultry_request != poultry_request: continue kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house allocation_dict = { "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname, "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile, "quantity": allocation.quantity, "kill_house": { "kill_house_fullname": kill_house.kill_house_operator.user.fullname, "kill_house_mobile": kill_house.kill_house_operator.user.mobile, } } allocation_list.append(allocation_dict) internal_poultry_req_dict = { "poultry_fullname": poultry_request.poultry.user.fullname, "poultry_mobile": poultry_request.poultry.user.mobile, "poultry_quantity": poultry_request.quantity, "index_weight": poultry_request.Index_weight, "date": poultry_request.send_date, "allocations": allocation_list, } final_poultry_requests_list.append(internal_poultry_req_dict) final_dict = { "poultry": final_poultry_requests_list, "buyer": killer_list, "kill_house": kill_house_list, } return Response(final_dict, status=status.HTTP_200_OK) elif 'poultry_remittance' in request.GET: now = datetime.datetime.now().date() date = datetime.datetime.strptime(str(request.GET['date']), '%Y-%m-%d').date() if 'date' in request.GET else now allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related( 'poultry_request', 'province_kill_request', 'daily_quota__kill_house__kill_house_operator__user', 'daily_quota__killer_kill_house__kill_house_operator__user' ) poultry_requests_list = [] final_poultry_requests_list = [] allocation_list = [] for a in allocations: if a.poultry_request not in poultry_requests_list: poultry_requests_list.append(a.poultry_request) for poultry_request in poultry_requests_list: for allocation in allocations: if allocation.poultry_request != poultry_request: continue kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house allocation_dict = { "buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname, "buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile, "quantity": allocation.quantity, "kill_house": { "kill_house_fullname": kill_house.kill_house_operator.user.fullname, "kill_house_mobile": kill_house.kill_house_operator.user.mobile, } } allocation_list.append(allocation_dict) internal_poultry_req_dict = { "poultry_fullname": poultry_request.poultry.user.fullname, "poultry_mobile": poultry_request.poultry.user.mobile, "poultry_quantity": poultry_request.quantity, "date": poultry_request.send_date, "allocations": allocation_list, } final_poultry_requests_list.append(internal_poultry_req_dict) return Response(final_poultry_requests_list, status=status.HTTP_200_OK) elif 'factor_to_province' in request.GET: factor = ProvinceFactorToKillHouse.objects.get( key=request.GET['factor_to_province'], paid_state='pending') # serializer = ProvinceFactorToKillHousePdfSerializer(factor) # return Response(serializer.data,status=status.HTTP_200_OK) economic_code_kill_house = factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code if factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code else None economic_code_poultry = factor.province_check_req.poultry_request.poultry.user.national_code if factor.province_check_req.poultry_request.poultry.user.national_code else None dict1 = { "buyer_name": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.name, # "economic_code_kill_house":economic_code_kill_house, # "national_id_kill_house":None, "serial_number_kill_house": factor.province_check_req.poultry_request.poultry.user.base_order, "adders_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.address, # "register_number_kill_house":None, "postal_code_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.postal_code, "poultry_name": factor.province_check_req.poultry_request.poultry.unit_name + ' ' + factor.province_check_req.poultry_request.poultry.user.fullname, # "economic_code_poultry":economic_code_poultry, # "national_id_poultry":None, "adders_poultry": factor.province_check_req.poultry_request.poultry.address.address, # "register_number_poultry":None, "postal_code_poultry": factor.province_check_req.poultry_request.poultry.address.postal_code, "factor_bar_code": factor.factor_bar_code, "amount": factor.total_weight, "chicken_price": factor.factor_fee, "total_price": factor.total_price, } return Response(dict1, status=status.HTTP_200_OK) class DetailsGeneralWageViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] serializer_class = GenaeralWageSerailizer queryset = ProvinceKillRequest.objects.filter( state__in=('pending', 'accepted'), trash=False, archive_wage=False, first_car_allocated_quantity=0, return_to_province=False).exclude(union_share=0, company_share=0, guilds_share=0) def list(self, request, *args, **kwargs): ser_general = self.serializer_class(self.queryset).data return Response(ser_general['general'], status=status.HTTP_200_OK) class DetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] serializer_class = DetailsGeneraWageSerializer # serializer_class = NewDetailsGeneraWageSerializer queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user', 'kill_house_operator__user__city').exclude( out_province=True) def list(self, request, *args, **kwargs): ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data return Response(ser_data, status=status.HTTP_200_OK) class NewDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] serializer_class = NewDetailsGeneraWageSerializer queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user', 'kill_house_operator__user__city').exclude( out_province=True) def list(self, request, *args, **kwargs): ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data return Response(ser_data, status=status.HTTP_200_OK) class DashboardDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] serializer_class = DashboardDetailsGeneraWageSerializer queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user', 'kill_house_operator__user__city').exclude( out_province=True) def list(self, request, *args, **kwargs): ser_data = self.serializer_class(self.queryset, context={'request': request}).data return Response(ser_data, status=status.HTTP_200_OK) class DataReportPercentagesViewSet(viewsets.ModelViewSet): permission_classes = [TokenHasReadWriteScope] serializer_class = DetailsGeneraWageSerializer queryset = KillHouseRequest.objects.filter(trash=False).order_by('kill_request__recive_date') def list(self, request, *args, **kwargs): user = request.user if request.GET['role'] == 'CityOperator': city_operator = CityOperator.objects.get(user__user=user, trash=False) kill_requests = self.queryset.filter( province_request__poultry_request__poultry__city_operator=city_operator.unit_name) else: kill_requests = self.queryset all_list = {} if request.GET['type'] == 'year': has_code_list = [] quarantine_quantity_list = [] assignment_state_archive_list = [] accepted_assignment_real_weight_list = [] hasnt_code_list = [] difference_bar_list = [] ware_house_confirmation_list = [] ware_house_accepted_real_weight_list = [] weight_year_list = [] now = datetime.datetime.now().date() start_date = now - relativedelta(years=1) # محاسبه تاریخ یک سال پیش current_date = start_date while current_date <= now: kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month, kill_request__recive_date__date__year=current_date.year) has_code_year = len(kill_request.filter(clearance_code__isnull=False)) quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False)) assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True')) accepted_assignment_real_weight = kill_request.aggregate( total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0 accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get( 'total_quantity') or 0 hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True)) difference_bar = len(kill_request.filter( Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity')))) ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True)) ware_house_accepted_real_weight = kill_request.aggregate( total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0 dict_has_code_year = { 'date': current_date, 'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_quarantine_quantity_year = { 'date': current_date, 'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_assignment_state_archive_year = { 'date': current_date, 'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_accepted_assignment_real_weight_year = { 'date': current_date, 'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_hasnt_code_year = { 'date': current_date, 'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_difference_bar_year = { 'date': current_date, 'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_ware_house_confirmation_year = { 'date': current_date, 'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_ware_house_accepted_real_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight, 2) if accepted_assignment_real_weight > 0 else 0 } has_code_list.append(dict_has_code_year) quarantine_quantity_list.append(dict_quarantine_quantity_year) assignment_state_archive_list.append(dict_assignment_state_archive_year) accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year) hasnt_code_list.append(dict_hasnt_code_year) difference_bar_list.append(dict_difference_bar_year) ware_house_confirmation_list.append(dict_ware_house_confirmation_year) ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year) weight_year_list.append(dict_weight_year) current_date += relativedelta(months=1) all_list['hasCode'] = has_code_list all_list['quarantineQuantity'] = quarantine_quantity_list all_list['assignmentStateArchive'] = assignment_state_archive_list all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list all_list['hasntCode'] = hasnt_code_list all_list['differenceBar'] = difference_bar_list all_list['wareHouseConfirmation'] = ware_house_confirmation_list all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list all_list['weightYear'] = weight_year_list elif request.GET['type'] == 'sixMonths': has_code_list = [] quarantine_quantity_list = [] assignment_state_archive_list = [] accepted_assignment_real_weight_list = [] hasnt_code_list = [] difference_bar_list = [] ware_house_confirmation_list = [] ware_house_accepted_real_weight_list = [] weight_year_list = [] now = datetime.datetime.now().date() start_date = now - relativedelta(months=5) # محاسبه تاریخ شش ماه پیش current_date = start_date while current_date <= now: kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month, kill_request__recive_date__date__year=current_date.year) has_code_year = len(kill_request.filter(clearance_code__isnull=False)) quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False)) assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True')) accepted_assignment_real_weight = kill_request.aggregate( total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0 accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get( 'total_quantity') or 0 hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True)) difference_bar = len(kill_request.filter( Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity')))) ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True)) ware_house_accepted_real_weight = kill_request.aggregate( total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0 dict_has_code_year = { 'date': current_date, 'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_quarantine_quantity_year = { 'date': current_date, 'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_assignment_state_archive_year = { 'date': current_date, 'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_accepted_assignment_real_weight_year = { 'date': current_date, 'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_hasnt_code_year = { 'date': current_date, 'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_difference_bar_year = { 'date': current_date, 'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_ware_house_confirmation_year = { 'date': current_date, 'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_ware_house_accepted_real_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight, 2) if accepted_assignment_real_weight > 0 else 0 } has_code_list.append(dict_has_code_year) quarantine_quantity_list.append(dict_quarantine_quantity_year) assignment_state_archive_list.append(dict_assignment_state_archive_year) accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year) hasnt_code_list.append(dict_hasnt_code_year) difference_bar_list.append(dict_difference_bar_year) ware_house_confirmation_list.append(dict_ware_house_confirmation_year) ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year) weight_year_list.append(dict_weight_year) current_date += relativedelta(months=1) all_list['hasCode'] = has_code_list all_list['quarantineQuantity'] = quarantine_quantity_list all_list['assignmentStateArchive'] = assignment_state_archive_list all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list all_list['hasntCode'] = hasnt_code_list all_list['differenceBar'] = difference_bar_list all_list['wareHouseConfirmation'] = ware_house_confirmation_list all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list all_list['weightYear'] = weight_year_list elif request.GET['type'] == 'threeMonths': has_code_list = [] quarantine_quantity_list = [] assignment_state_archive_list = [] accepted_assignment_real_weight_list = [] hasnt_code_list = [] difference_bar_list = [] ware_house_confirmation_list = [] ware_house_accepted_real_weight_list = [] weight_year_list = [] now = datetime.datetime.now().date() start_date = now - relativedelta(months=2) # محاسبه تاریخ سه ماه پیش current_date = start_date while current_date <= now: kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month, kill_request__recive_date__date__year=current_date.year) has_code_year = len(kill_request.filter(clearance_code__isnull=False)) quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False)) assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True')) accepted_assignment_real_weight = kill_request.aggregate( total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0 accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get( 'total_quantity') or 0 hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True)) difference_bar = len(kill_request.filter( Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity')))) ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True)) ware_house_accepted_real_weight = kill_request.aggregate( total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0 dict_has_code_year = { 'date': current_date, 'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_quarantine_quantity_year = { 'date': current_date, 'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_assignment_state_archive_year = { 'date': current_date, 'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_accepted_assignment_real_weight_year = { 'date': current_date, 'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_hasnt_code_year = { 'date': current_date, 'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_difference_bar_year = { 'date': current_date, 'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_ware_house_confirmation_year = { 'date': current_date, 'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_ware_house_accepted_real_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight, 2) if accepted_assignment_real_weight > 0 else 0 } has_code_list.append(dict_has_code_year) quarantine_quantity_list.append(dict_quarantine_quantity_year) assignment_state_archive_list.append(dict_assignment_state_archive_year) accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year) hasnt_code_list.append(dict_hasnt_code_year) difference_bar_list.append(dict_difference_bar_year) ware_house_confirmation_list.append(dict_ware_house_confirmation_year) ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year) weight_year_list.append(dict_weight_year) current_date += relativedelta(months=1) all_list['hasCode'] = has_code_list all_list['quarantineQuantity'] = quarantine_quantity_list all_list['assignmentStateArchive'] = assignment_state_archive_list all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list all_list['hasntCode'] = hasnt_code_list all_list['differenceBar'] = difference_bar_list all_list['wareHouseConfirmation'] = ware_house_confirmation_list all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list all_list['weightYear'] = weight_year_list else: has_code_list = [] quarantine_quantity_list = [] assignment_state_archive_list = [] accepted_assignment_real_weight_list = [] hasnt_code_list = [] difference_bar_list = [] ware_house_confirmation_list = [] ware_house_accepted_real_weight_list = [] weight_year_list = [] now = datetime.datetime.now().date() last_year = now - relativedelta(months=1) # محاسبه تاریخ یک ماه پیش current_date = last_year while current_date <= now: kill_request = kill_requests.filter(kill_request__recive_date__date=current_date) has_code_year = len(kill_request.filter(clearance_code__isnull=False)) quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False)) assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True')) accepted_assignment_real_weight = kill_request.aggregate( total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0 accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get( 'total_quantity') or 0 hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True)) difference_bar = len(kill_request.filter( Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity')))) ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True)) ware_house_accepted_real_weight = kill_request.aggregate( total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0 dict_has_code_year = { 'date': current_date, 'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_quarantine_quantity_year = { 'date': current_date, 'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_assignment_state_archive_year = { 'date': current_date, 'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_accepted_assignment_real_weight_year = { 'date': current_date, 'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_hasnt_code_year = { 'date': current_date, 'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_difference_bar_year = { 'date': current_date, 'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0 } dict_ware_house_confirmation_year = { 'date': current_date, 'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len( kill_request) > 0 else 0 } dict_ware_house_accepted_real_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight, 2) if accepted_real_weight > 0 else 0 } dict_weight_year = { 'date': current_date, 'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight, 2) if accepted_assignment_real_weight > 0 else 0 } has_code_list.append(dict_has_code_year) quarantine_quantity_list.append(dict_quarantine_quantity_year) assignment_state_archive_list.append(dict_assignment_state_archive_year) accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year) hasnt_code_list.append(dict_hasnt_code_year) difference_bar_list.append(dict_difference_bar_year) ware_house_confirmation_list.append(dict_ware_house_confirmation_year) ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year) weight_year_list.append(dict_weight_year) current_date += relativedelta(days=1) # به روز بعد بروید all_list['hasCode'] = has_code_list all_list['quarantineQuantity'] = quarantine_quantity_list all_list['assignmentStateArchive'] = assignment_state_archive_list all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list all_list['hasntCode'] = hasnt_code_list all_list['differenceBar'] = difference_bar_list all_list['wareHouseConfirmation'] = ware_house_confirmation_list all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list all_list['weightYear'] = weight_year_list return Response(all_list) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def check_excel(request): url = request.GET.get('url') if not url: return JsonResponse({'status': 'error', 'message': 'URL parameter is missing'}, status=400) try: r = requests.head(f'https://{base_url_for_sms_report}backend.rasadyar.com/{url}') return JsonResponse({'status': r.status_code}) except requests.RequestException as e: return JsonResponse({'status': 'error', 'message': str(e)}, status=500) class SSLAdapter(HTTPAdapter): def __init__(self, *args, **kwargs): self.context = create_urllib3_context() self.context.options |= 0x4 # OP_LEGACY_SERVER_CONNECT super().__init__(*args, **kwargs) def init_poolmanager(self, *args, **kwargs): kwargs['ssl_context'] = self.context return super().init_poolmanager(*args, **kwargs) def build_response(self, req, resp): resp = super().build_response(req, resp) return resp @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def find_gid_code(request): date = datetime.datetime.now().date() - datetime.timedelta(days=7) kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False, quarantine_quantity__isnull=True).only( 'quarantine_code_state', 'clearance_code', 'quarantine_quantity' ).order_by('-id') session = requests.Session() session.mount('https://', SSLAdapter()) for kill in kill_house_request: if kill.clearance_code is None: kill.quarantine_code_state = 'noclearance' else: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': kill.quarantine_code_state = 'notconfirmed' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None else: table = context.find_all('table') if table[5:6]: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_quantity = int(number) if kill.quarantine_code_state is not None: kill.quarantine_code_state = None else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': kill.quarantine_code_state = 'contradiction' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None kill.save() return HttpResponse('ok') def get_gid(clearance_code): kill = KillHouseRequest.objects.filter(clearance_code=clearance_code, trash=False).order_by('id') session = requests.Session() session.mount('https://', SSLAdapter()) if kill: if len(kill) > 1: for k in kill[1:]: if k.quarantine_quantity is not None: k.quarantine_quantity = None k.quarantine_code_state = 'merge' k.save() kill = kill.first() if kill.quarantine_code_state != 'merge': data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': kill.quarantine_code_state = 'notconfirmed' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) kill.inquiry_date = date.date() send_date = kill.kill_request.recive_date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_quantity = int(number) if kill.quarantine_code_state is not None: kill.quarantine_code_state = None for i in table[4:5]: rows = i.find_all('tr') pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', style='font-family:Tahoma').text.strip() kill.inquiry_pelak = pelak_txt td = rows[1].find_all('td')[1] driver_txt = td.find('span', class_='dynamictxt').text.strip() kill.inquiry_driver = driver_txt for r in rows: tds = r.find_all('td', colspan="2") if len(tds) >= 2: origin_td = tds[0] origin_text = origin_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_origin = origin_text destination_td = tds[1] destination_text = destination_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_destination = destination_text else: kill.quarantine_code_state = 'contradiction' kill.quarantine_quantity = None else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': kill.quarantine_code_state = 'contradiction' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None kill.save() def cron_find_gid_code(): date = datetime.datetime.now().date() - datetime.timedelta(days=7) kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False, quarantine_quantity__isnull=True, clearance_code__isnull=False).only( 'quarantine_code_state', 'clearance_code', 'quarantine_quantity' ).order_by('-id') session = requests.Session() session.mount('https://', SSLAdapter()) for kill in kill_house_request: if kill.quarantine_code_state != 'merge': if kill.clearance_code is None: kill.quarantine_code_state = 'noclearance' else: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': kill.quarantine_code_state = 'notconfirmed' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) kill.inquiry_date = date.date() send_date = kill.kill_request.recive_date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_quantity = int(number) if kill.quarantine_code_state is not None: kill.quarantine_code_state = None for i in table[4:5]: rows = i.find_all('tr') pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', style='font-family:Tahoma').text.strip() kill.inquiry_pelak = pelak_txt td = rows[1].find_all('td')[1] driver_txt = td.find('span', class_='dynamictxt').text.strip() kill.inquiry_driver = driver_txt for r in rows: tds = r.find_all('td', colspan="2") if len(tds) >= 2: origin_td = tds[0] origin_text = origin_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_origin = origin_text destination_td = tds[1] destination_text = destination_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_destination = destination_text else: kill.quarantine_code_state = 'contradiction' kill.quarantine_quantity = None else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': kill.quarantine_code_state = 'contradiction' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None kill.save() class IranProvinceViewSet(viewsets.ModelViewSet): queryset = IranProvinces.objects.all().order_by('id') serializer_class = IranProvinceSerializer permission_classes = [AllowAny] class IranCityViewSet(viewsets.ModelViewSet): queryset = IranCities.objects.all().order_by('id') serializer_class = IranCitiesSerializer permission_classes = [AllowAny] def list(self, request, *args, **kwargs): query = self.queryset.filter(province_id__name=request.GET.get('name')) ser_data = self.serializer_class(query, many=True).data return Response(ser_data, status=status.HTTP_200_OK) def fix_image_voilation_hatching(request): hatchings = PoultryHatching.objects.filter(violation_image__isnull=False) for h in hatchings: h.violation_image1 = [h.violation_image] h.save() return HttpResponse('ok') def fix_image_voilation_hatching_return(request): hatchings = PoultryHatching.objects.filter(violation_image1__isnull=False) for h in hatchings: h.violation_image = h.violation_image1 h.save() return HttpResponse('ok') class AgeNotificationPoultryViewSet(viewsets.ModelViewSet): queryset = AgeNotificationPoultry.objects.all() serializer_class = AgeNotificationPoultrySerilizer permission_classes = [AllowAny] def list(self, request, *args, **kwargs): query = self.queryset.filter(trash=False) ser_data = self.serializer_class(query, many=True).data return Response(ser_data, status=status.HTTP_200_OK) def update(self, request, *args, **kwargs): query = self.queryset.get(key=request.data['notif_key']) request.data.pop('notif_key') ser_data = self.serializer_class(query) ser_data.update(instance=query, validated_data=request.data) return Response(ser_data.data, status=status.HTTP_200_OK) def destroy(self, request, *args, **kwargs): query = self.queryset.get(key=request.GET['notif_key']) query.trash = True query.save() return Response({'result': 'با موفقیت حذف شد.'}, status=status.HTTP_200_OK) def send_sms_for_poultry_from_age_notification(): notif_poultry = AgeNotificationPoultry.objects.filter(trash=False) if notif_poultry: for n in notif_poultry: poultry_hatchings = PoultryHatching.objects.filter( archive=False, allow_hatching='pending', trash=False, left_over__gt=(F('quantity') * n.losses_percent) / 100, chicken_age=n.poultry_age ).values_list('poultry__user__mobile', flat=True).distinct() mobile_numbers = ','.join(poultry_hatchings) if len(mobile_numbers) > 0: req = send_sms_request( f"http://webservice.sahandsms.com/newsmswebservice.asmx/SendPostUrl?username={USERNAME_SMS_FINANCIAL}&password={PASSWORD_SMS_FINANCIAL}&from=30002501&to={mobile_numbers}&message={n.message}") def remove_access_token(): ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/" requests.get( url=ARTA_remove_access_token, verify=False ) now = datetime.datetime.now() accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3)) for access in accesses: access.expires = now - timedelta(days=2) access.save() def kill_house_not_add_to_inventory(): now = datetime.datetime.now().date() - timedelta(days=2) kill_houses = KillHouse.objects.filter(trash=False, out_province=False).select_related('kill_house_operator__user') for kill_house in kill_houses: kill_request = len(KillHouseRequest.objects.filter(Q(killhouse_user=kill_house) | Q(killer=kill_house), trash=False, ware_house_confirmation=False, calculate_status=True, kill_request__recive_date__date__lte=now)) if kill_request > 0: send_sms_for_kill_house_not_add_to_inventory(kill_house.kill_house_operator.user.mobile, kill_request) class CookieSamasatViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] queryset = CookieSamasat.objects.first() serializer_class = CookieSamasatSerilizer def list(self, request, *args, **kwargs): cookie = CookieSamasat.objects.all().first() if not cookie: cookie = CookieSamasat( cookie='-', table_name='-' ) cookie.save() ser_data = self.serializer_class(cookie).data return Response(ser_data, status=status.HTTP_200_OK) def update(self, request, *args, **kwargs): query = CookieSamasat.objects.first() if base_url_for_sms_report == 'test': province_list = ['bu', 'ma', 'ha'] for name in province_list: requests.put(f"https://{name}backend.rasadyar.com/cookie-samasat/0/", data=request.data) serializer = self.serializer_class(query, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # def create_poultry(phone_number,full_name,city,province): # group = Group.objects.get(name__exact="Poultry") # hashed_password=None # password=None # user = User(username=phone_number, first_name=first_name, last_name=last_name, password=hashed_password) # user.save() # base_id = SystemUserProfile.objects.all() # if base_id.count() > 0: # base_id = int(base_id.last().base_order) + 1 # else: # base_id = 1000 # system_profile = SystemUserProfile( # mobile=phone_number, # first_name=first_name, # last_name=last_name, # fullname=first_name + '' + last_name, # user=user, # base_order=base_id, # password=password, # birthday=str(datetime.datetime.now().date()), # city=city, # province=province # ) # system_profile.save() # system_profile.role.add(group) # wallet = Wallet() # wallet.save() # درست نیست @api_view(["PUT"]) @permission_classes([AllowAny]) @csrf_exempt def api_update_poultry_hatching(request): not_find_list = [] for data in request.data['Data']: breeding_uniq_id = data['PartIdCode'] licence_number = data['RequestCode'] hatching_quantity = data['BaseHatchingCount'] poultry_name = data['UnitName'] losses = data['EvacuationCount'] health_certificate = data['DesCertId'] evacuation_details = data.get('EvacuationDetail') or [] if isinstance(evacuation_details, dict): evacuation_details = [evacuation_details] report_type_field_map = { 'تلفات ناشی از بیماری': 'total_disease_losses', 'معدوم سازی گله': 'total_flock_destruction', 'تلفات عادی گله': 'total_normal_flock_losses', 'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses', 'تلفات ناشی از آتش سوزی': 'total_fire_losses', } evacuation_losses = {} evacuation_fields = set() for detail in evacuation_details: if not isinstance(detail, dict): continue report_type = (detail.get('ReportTypeString') or '').strip() field_name = report_type_field_map.get(report_type) if not field_name: continue try: good_count = int(detail.get('GoodCount') or 0) except (TypeError, ValueError): continue evacuation_losses[field_name] = evacuation_losses.get(field_name, 0) + good_count evacuation_fields.add(field_name) def apply_evacuation_losses(instance): for field in evacuation_fields: setattr(instance, field, evacuation_losses.get(field, 0)) poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first() if not poultry: not_find_list.append(breeding_uniq_id) continue poultry.unit_name = poultry_name poultry.save() hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id') if hatch: period = hatch.last().period + 1 else: period = 1 hatching_date = data['HatchingDatePersian'].split('/') date = convert_to_miladi( year=int(hatching_date[0]), month=int(hatching_date[1]), day=int(hatching_date[2]) ) poultry_hatching = hatch.filter(trash=False, archive=False, state='pending', allow_hatching='pending').order_by('id') if not poultry_hatching.exists(): if not hatch.filter(archive=True, state='complete', allow_hatching="True", licence_number=licence_number).exists(): hatching = PoultryHatching( poultry=poultry, date=date, quantity=hatching_quantity, breed=[ {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], period=period, chicken_breed='*ترکیبی', hall=1, left_over=hatching_quantity, latest_hatching_change={ "role": "UnitWindow", "date": str(datetime.datetime.now().date()), "full_name": "" }, licence_number=licence_number, breeding_unique_id=breeding_uniq_id, losses=losses, health_certificate=health_certificate ) apply_evacuation_losses(hatching) hatching.save() else: previouse_hatching = poultry_hatching.last() hatchings = poultry_hatching.filter(licence_number=licence_number) if not hatchings: if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses): previouse_hatching.violation = True previouse_hatching.save() hatching = PoultryHatching( poultry=poultry, date=date, quantity=hatching_quantity, breed=[ {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], period=period, chicken_breed='*ترکیبی', hall=1, left_over=hatching_quantity, latest_hatching_change={ "role": "UnitWindow", "date": str(datetime.datetime.now().date()), "full_name": "" }, licence_number=licence_number, breeding_unique_id=breeding_uniq_id, losses=losses, health_certificate=health_certificate ) apply_evacuation_losses(hatching) hatching.save() else: last_hatchings = hatchings.first() if last_hatchings.health_certificate is None: last_hatchings.health_certificate = health_certificate last_hatchings.date = date last_hatchings.quantity = hatching_quantity last_hatchings.losses = losses apply_evacuation_losses(last_hatchings) last_hatchings.save() update = LastUpdate.objects.first() update.update_date = datetime.datetime.now() update.save() return Response(not_find_list, status=status.HTTP_201_CREATED) @api_view(["PUT"]) @permission_classes([AllowAny]) @csrf_exempt def api_update_chicken_breed(request): for data in request.data['Data']: breeding_uniq_id = data['PartIdCode'] breed = data['PedigreeName'] health_certificate = data['CertId'] poultry_hatching = PoultryHatching.objects.filter(Q(poultry__breeding_unique_id=breeding_uniq_id, health_certificate__isnull=True) | Q( poultry__breeding_unique_id=breeding_uniq_id, health_certificate__isnull=False, health_certificate=health_certificate) , violation=False, trash=False, allow_hatching='pending', state='pending', ).order_by( 'id').last() if poultry_hatching: if poultry_hatching.chicken_breed == '*ترکیبی': poultry_hatching.chicken_breed = breed elif poultry_hatching.chicken_breed != breed and poultry_hatching.chicken_breed != '*ترکیبی': poultry_hatching.chicken_breed = 'ترکیبی' else: continue poultry_hatching.save() return Response({"result": "انجام شد."}, status=status.HTTP_201_CREATED) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def api_update_poultry_hatching_from_rsi(request): not_find_list = [] r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}') for data in r.json(): breeding_uniq_id = data['PartIdCode'] licence_number = data['RequestCode'] hatching_quantity = data['ChickCountSum'] CertId = data['CertId'] poultry_name = data.get('UnitName', None) losses = data.get('Evacuation', 0) province = data['ProvinceName'] city = data['CityName'] PersonTypeName = data['PersonTypeName'] InteractTypeName = data['InteractTypeName'] UnionTypeName = data['UnionTypeName'] date = convert_str_to_date(str(data['Date']), with_datetime=True) samasat_discharge_percentage = data['samasat_discharge_percentage'] evacuation_details = data.get('EvacuationDetail') or [] if isinstance(evacuation_details, dict): evacuation_details = [evacuation_details] report_type_field_map = { 'تلفات ناشی از بیماری': 'total_disease_losses', 'معدوم سازی گله': 'total_flock_destruction', 'تلفات عادی گله': 'total_normal_flock_losses', 'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses', 'تلفات ناشی از آتش سوزی': 'total_fire_losses', } evacuation_detail_fields = [ 'PartIdCode', 'RequestId', 'MoReportId', 'ReportType', 'ReportTypeString', 'ReportDate', 'ReportDateShamsi', 'MoReason', 'MoDate', 'MoDateShamsi', 'MoStartDay', 'MoEndDay', 'MoReportSubId', 'ReportStatus', 'GoodCount', 'Message', 'ErrorCode', 'IsDeleted', 'RegDate', 'RegDateShamsi', 'RegDateShamsiWithTime', 'RegDateShamsiOnlyTime', 'ExternalId', 'StringId', 'IsPersisted', 'AllowInsert', 'AllowUpdate', 'ModalCss', 'GridContainerParametersModel', 'MenuUserAccess', 'MenuUserAccessId', 'LogTableName', 'LogTableAlias', 'PageTitle', ] report_type_fields = set(report_type_field_map.values()) report_type_field_list = list(report_type_fields) def build_unique_key(detail_payload): external_id = detail_payload.get('ExternalId') if external_id: return f"external:{external_id}" string_id = detail_payload.get('StringId') if string_id: return f"string:{string_id}" return "fallback:" + "|".join( str(detail_payload.get(key) or '') for key in ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate')) def sync_evacuation_detail_records(hatching_instance): if not hatching_instance.pk: return def normalize_good_count(value): if value in (None, ''): return None try: return int(value) except (TypeError, ValueError): try: return int(float(value)) except (TypeError, ValueError): return None retained_ids = set() seen_unique_keys = set() for detail in evacuation_details: if not isinstance(detail, dict): continue detail_payload = {field: detail.get(field) for field in evacuation_detail_fields} detail_payload['GoodCount'] = normalize_good_count(detail_payload.get('GoodCount')) if not any(value not in (None, '') for value in detail_payload.values()): continue unique_key = build_unique_key(detail_payload) if unique_key in seen_unique_keys: continue seen_unique_keys.add(unique_key) external_id = detail_payload.get('ExternalId') string_id = detail_payload.get('StringId') lookup_kwargs = {'hatching': hatching_instance} if external_id: lookup_kwargs['ExternalId'] = external_id elif string_id: lookup_kwargs['StringId'] = string_id else: lookup_key_fields = ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate') lookup_kwargs.update({field: detail_payload.get(field) for field in lookup_key_fields}) defaults = detail_payload.copy() defaults['hatching'] = hatching_instance try: detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create( defaults=defaults, **lookup_kwargs ) except EvacuationHatchingDetail.MultipleObjectsReturned: EvacuationHatchingDetail.objects.filter(**lookup_kwargs).delete() detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create( defaults=defaults, **lookup_kwargs ) retained_ids.add(detail_instance.pk) if retained_ids: hatching_instance.evacuation_details.exclude(pk__in=retained_ids).delete() else: hatching_instance.evacuation_details.all().delete() def apply_evacuation_losses(instance): totals = {field: 0 for field in report_type_fields} detail_qs = instance.evacuation_details.filter(trash=False, IsDeleted=False) for detail in detail_qs: report_type = (detail.ReportTypeString or '').strip() field_name = report_type_field_map.get(report_type) if not field_name: continue totals[field_name] += detail.GoodCount or 0 for field, value in totals.items(): setattr(instance, field, value) hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id') try: if not hatch: poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first() if not poultry: first_name = data['poultry']['FirstName'] last_name = data['poultry']['LastName'] mobile = data['poultry']['Mobile'] system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first() province = Province.objects.filter(trash=False, name__exact=province).first() city = City.objects.filter(trash=False, name__exact=city).first() if not system_profile: data = { "username": mobile, "first_name": first_name, "last_name": last_name, "password": '123456', "national_code": '0', "role": "Poultry", "api_key": PROJECT_API_KEY } req = requests.post( url=ARTA_REGISTER, data=data, verify=False ) if req.status_code == 200: hashed_password = hashlib.sha256(str('123456').encode()).hexdigest() user = User.objects.filter(username=mobile).first() if not user: user = User(username=mobile, first_name=first_name, last_name=last_name, password=hashed_password) user.save() base_id = SystemUserProfile.objects.all() if base_id.count() > 0: base_id = int(base_id.last().base_order) + 1 else: base_id = 1000 system_profile = SystemUserProfile( mobile=mobile, first_name=str(first_name), last_name=str(last_name), fullname=str(first_name) + ' ' + str(last_name), user=user, base_order=base_id, password='123456', birthday=str(datetime.datetime.now().date()), city=city, province=province, ) system_profile.save() else: not_find_list.append(breeding_uniq_id) group = Group.objects.get(name__exact="Poultry") if not system_profile.role.filter(name="Poultry"): system_profile.role.add(group) wallet = Wallet() wallet.save() poultry = Poultry( user=system_profile, unit_name=poultry_name, system_code=data.get('poultry', {}).get('SystemCode', None), epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None), breeding_unique_id=breeding_uniq_id, ) address = SystemAddress( province=province, city=city, address=city ) address.save() poultry.address = address poultry.user = system_profile poultry.wallet = wallet poultry.save() poultry.unit_name = poultry_name poultry.save() hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id') if hatch: period = hatch.last().period + 1 else: period = 1 hatching = PoultryHatching( poultry=poultry, date=date, quantity=hatching_quantity, breed=[ {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], period=period, chicken_breed=data["PedigreeName"], hall=1, left_over=hatching_quantity, latest_hatching_change={ "role": "UnitWindow", "date": str(datetime.datetime.now().date()), "full_name": "" }, licence_number=licence_number, breeding_unique_id=breeding_uniq_id, losses=losses, PersonTypeName=PersonTypeName, InteractTypeName=InteractTypeName, UnionTypeName=UnionTypeName, samasat_discharge_percentage=samasat_discharge_percentage, CertId=CertId, predicate_date=date + timedelta( days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None, ) hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1 hatching.save() sync_evacuation_detail_records(hatching) apply_evacuation_losses(hatching) if report_type_field_list: hatching.save(update_fields=report_type_field_list) else: hatching.save() else: last_hatchings = hatch.first() last_hatchings.date = date last_hatchings.quantity = hatching_quantity last_hatchings.losses = losses last_hatchings.PersonTypeName = PersonTypeName last_hatchings.InteractTypeName = InteractTypeName last_hatchings.UnionTypeName = UnionTypeName last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1 last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage last_hatchings.predicate_date = date + timedelta( days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None sync_evacuation_detail_records(last_hatchings) apply_evacuation_losses(last_hatchings) update_fields = [ 'date', 'quantity', 'losses', 'PersonTypeName', 'InteractTypeName', 'UnionTypeName', 'chicken_age', 'samasat_discharge_percentage', 'predicate_date', ] + report_type_field_list last_hatchings.save(update_fields=update_fields) update = LastUpdate.objects.first() update.update_date = datetime.datetime.now() update.save() except: not_find_list.append(breeding_uniq_id) if not_find_list: token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde" chat_id = '10046800' url = f'https://eitaayar.ir/api/{token}/sendMessage' base_message = f'{base_url_for_sms_report}' \ '\n' messages = [] current_message = base_message new_message_part = ','.join(not_find_list) if len(current_message) + len(new_message_part) > 4000: # محدودیت تعداد کاراکترها messages.append(current_message) current_message = base_message # شروع یک پیام جدید current_message += new_message_part if current_message and current_message != base_message: messages.append(current_message) for message in messages: data = { 'chat_id': chat_id, 'text': message, } r = requests.post(url, data=data, verify=False) return Response(not_find_list, status=status.HTTP_201_CREATED) class HatchingLossManagementViewSet(viewsets.ModelViewSet): permission_classes = [AllowAny] serializer_class = HatchingLossManagementSerializer def get_queryset(self): queryset = HatchingLossManagement.objects.filter(trash=False) if not queryset.exists(): queryset = HatchingLossManagement.objects.filter( pk=HatchingLossManagement.objects.create().pk ) return queryset def get_object(self): return self.get_queryset().first() def list(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response( serializer.data, status=status.HTTP_200_OK, ) def create(self, request, *args, **kwargs): return self._update_instance(request, partial=False) def update(self, request, *args, **kwargs): return self._update_instance(request, partial=False) def _update_instance(self, request, partial): instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) instance = serializer.save() self._recalculate_hatchings() return Response(self.get_serializer(instance).data, status=status.HTTP_200_OK) def _recalculate_hatchings(self): count = 0 hatchings = PoultryHatching.objects.filter(trash=False, archive=False, allow_hatching='pending') for hatching in hatchings.iterator(): hatching.save() count += 1 return count @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def update_hatching(request): r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}') for data in r.json(): print(data['PartIdCode']) return Response(r.json()) def cron_update_poultry_hatching_from_rsi(): not_find_list = [] r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}') for data in r.json(): breeding_uniq_id = data['PartIdCode'] licence_number = data['RequestCode'] hatching_quantity = data['ChickCountSum'] CertId = data['CertId'] poultry_name = data.get('UnitName', None) losses = data.get('Evacuation', 0) province = data['ProvinceName'] city = data['CityName'] PersonTypeName = data['PersonTypeName'] InteractTypeName = data['InteractTypeName'] UnionTypeName = data['UnionTypeName'] date = datetime.datetime.strptime(data['Date'], "%Y-%m-%dT%H:%M:%SZ") samasat_discharge_percentage = data['samasat_discharge_percentage'] hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id') try: if not hatch: poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first() if not poultry: first_name = data['poultry']['FirstName'] last_name = data['poultry']['LastName'] mobile = data['poultry']['Mobile'] system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first() if not system_profile: data = { "username": mobile, "first_name": first_name, "last_name": last_name, "password": '123456', "national_code": '0', "role": "Poultry", "api_key": PROJECT_API_KEY } req = requests.post( url=ARTA_REGISTER, data=data, verify=False ) if req.status_code == 200: hashed_password = hashlib.sha256(str('123456').encode()).hexdigest() user = User.objects.filter(username=mobile).first() if not user: user = User(username=mobile, first_name=first_name, last_name=last_name, password=hashed_password) user.save() base_id = SystemUserProfile.objects.all() if base_id.count() > 0: base_id = int(base_id.last().base_order) + 1 else: base_id = 1000 system_profile = SystemUserProfile( mobile=mobile, first_name=str(first_name), last_name=str(last_name), fullname=str(first_name) + ' ' + str(last_name), user=user, base_order=base_id, password='123456', birthday=str(datetime.datetime.now().date()), ) system_profile.save() else: not_find_list.append(breeding_uniq_id) group = Group.objects.get(name__exact="Poultry") if not system_profile.role.filter(name="Poultry"): system_profile.role.add(group) wallet = Wallet() wallet.save() poultry = Poultry( user=system_profile, unit_name=poultry_name, system_code=data.get('poultry', {}).get('SystemCode', None), epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None), breeding_unique_id=breeding_uniq_id, ) province = Province.objects.filter(trash=False, name__exact=province).first() city = City.objects.filter(trash=False, name__exact=city).first() address = SystemAddress( province=province, city=city, address=city ) address.save() poultry.address = address poultry.user = system_profile poultry.wallet = wallet poultry.save() poultry.unit_name = poultry_name poultry.save() hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id') if hatch: period = hatch.last().period + 1 else: period = 1 hatching = PoultryHatching( poultry=poultry, date=date, quantity=hatching_quantity, breed=[ {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], period=period, chicken_breed=data["PedigreeName"], hall=1, left_over=hatching_quantity, latest_hatching_change={ "role": "UnitWindow", "date": str(datetime.datetime.now().date()), "full_name": "" }, licence_number=licence_number, breeding_unique_id=breeding_uniq_id, losses=losses, PersonTypeName=PersonTypeName, InteractTypeName=InteractTypeName, UnionTypeName=UnionTypeName, samasat_discharge_percentage=samasat_discharge_percentage, CertId=CertId, predicate_date=date + timedelta( days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None, ) hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1 hatching.save() else: last_hatchings = hatch.first() last_hatchings.date = date last_hatchings.quantity = hatching_quantity last_hatchings.losses = losses last_hatchings.PersonTypeName = PersonTypeName last_hatchings.InteractTypeName = InteractTypeName last_hatchings.UnionTypeName = UnionTypeName last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1 last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage last_hatchings.predicate_date = date + timedelta( days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None last_hatchings.save() update = LastUpdate.objects.first() update.update_date = datetime.datetime.now() update.save() except: not_find_list.append(breeding_uniq_id) # poultry = Poultry.objects.filter(breeding_unique_id=breeding_uniq_id).first() # try: # if not poultry: # first_name = data['poultry']['FirstName'] # last_name = data['poultry']['LastName'] # mobile = data['poultry']['Mobile'] # system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first() # if not system_profile: # # data = { # "username": mobile, # "first_name": first_name, # "last_name": last_name, # "password": '123456', # "national_code": '0', # "role": "Poultry", # "api_key": PROJECT_API_KEY # } # req = requests.post( # url=ARTA_REGISTER, # data=data, # verify=False # ) # # if req.status_code == 200: # hashed_password = hashlib.sha256(str('123456').encode()).hexdigest() # user = User.objects.filter(username=mobile).first() # if not user: # user = User(username=mobile, first_name=first_name, last_name=last_name, # password=hashed_password) # user.save() # base_id = SystemUserProfile.objects.all() # if base_id.count() > 0: # base_id = int(base_id.last().base_order) + 1 # else: # base_id = 1000 # system_profile = SystemUserProfile( # mobile=mobile, # first_name=str(first_name), # last_name=str(last_name), # fullname=str(first_name) + ' ' + str(last_name), # user=user, # base_order=base_id, # password='123456', # birthday=str(datetime.datetime.now().date()), # ) # system_profile.save() # # else: # continue # # group = Group.objects.get(name__exact="Poultry") # if not system_profile.role.filter(name="Poultry"): # system_profile.role.add(group) # # wallet = Wallet() # wallet.save() # poultry = Poultry( # user=system_profile, # unit_name=poultry_name, # system_code=data.get('poultry', {}).get('SystemCode',None), # epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode',None), # breeding_unique_id=breeding_uniq_id, # ) # province=Province.objects.filter(trash=False,name__exact=province).first() # city=City.objects.filter(trash=False,name__exact=city).first() # address = SystemAddress( # province=province, # city=city, # address=city # ) # address.save() # poultry.address = address # poultry.user = system_profile # poultry.wallet = wallet # poultry.save() # # poultry.unit_name = poultry_name # poultry.save() # hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id') # if hatch: # period = hatch.last().period + 1 # else: # period = 1 # # # hatching_date = data['HatchingDatePersian'].split('/') # date = data['Date'] # # poultry_hatching = hatch.filter(trash=False,archive=False, state='pending', # allow_hatching='pending').order_by('id') # # if not poultry_hatching.exists(): # if not hatch.filter(archive=True, state='complete', # allow_hatching="True",licence_number=licence_number).exists(): # hatching = PoultryHatching( # poultry=poultry, # date=date, # quantity=hatching_quantity, # breed=[ # {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], # period=period, # chicken_breed=data["PedigreeName"], # hall=1, # left_over=hatching_quantity, # latest_hatching_change={ # "role": "UnitWindow", # "date": str(datetime.datetime.now().date()), # "full_name": "" # }, # licence_number=licence_number, # breeding_unique_id=breeding_uniq_id, # losses=losses, # # ) # hatching.save() # # else: # previouse_hatching = poultry_hatching.last() # # hatchings = poultry_hatching.filter(licence_number=licence_number) # if not hatchings: # if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses): # previouse_hatching.violation = True # previouse_hatching.save() # # hatching = PoultryHatching( # poultry=poultry, # date=date, # quantity=hatching_quantity, # breed=[ # {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}], # period=period, # chicken_breed=data["PedigreeName"], # hall=1, # left_over=hatching_quantity, # latest_hatching_change={ # "role": "UnitWindow", # "date": str(datetime.datetime.now().date()), # "full_name": "" # }, # licence_number=licence_number, # breeding_unique_id=breeding_uniq_id, # losses=losses, # # ) # hatching.save() # else: # last_hatchings=hatchings.first() # # if last_hatchings.health_certificate is None: # # last_hatchings.health_certificate=health_certificate # last_hatchings.date = date # last_hatchings.quantity = hatching_quantity # last_hatchings.losses = losses # last_hatchings.save() # # update = LastUpdate.objects.first() # update.update_date = datetime.datetime.now() # update.save() # except: # not_find_list.append(breeding_uniq_id) if not_find_list: token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde" chat_id = '10046800' url = f'https://eitaayar.ir/api/{token}/sendMessage' base_message = f'{base_url_for_sms_report}' \ '\n' messages = [] current_message = base_message new_message_part = ','.join(not_find_list) if len(current_message) + len(new_message_part) > 4000: # محدودیت تعداد کاراکترها messages.append(current_message) current_message = base_message # شروع یک پیام جدید current_message += new_message_part if current_message and current_message != base_message: messages.append(current_message) for message in messages: data = { 'chat_id': chat_id, 'text': message, } r = requests.post(url, data=data, verify=False) def fix_bar_without_quarantine(request): kill_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False, quarantine_code_state__isnull=False).only('clearance_code') print(len(kill_request)) for kill in kill_request: get_gid(kill.clearance_code) return HttpResponse('ok') def get_gid_out_province(id): kill = KillHouseFreeSaleBarInformation.objects.get(id=id, trash=False) session = requests.Session() session.mount('https://', SSLAdapter()) if kill: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': # kill.quarantine_code_state = 'notconfirmed' # if kill.quarantine_quantity is not None: # kill.quarantine_weight_of_carcasses = None pass else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) send_date = kill.date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: # kill.inquiry_date = date.date() for i in table[5:6]: row = i.find_all('tr') for r in row[0:1]: quantity = r.find_all('td')[1] match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_weight_of_carcasses = int(number) # if kill.quarantine_code_state is not None: # kill.quarantine_code_state=None else: kill.quarantine_weight_of_carcasses = 0 # for i in table[4:5]: # rows = i.find_all('tr') # # pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', # style='font-family:Tahoma').text.strip() # kill.inquiry_pelak=pelak_txt # td=rows[1].find_all('td')[1] # driver_txt = td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_driver=driver_txt # # for r in rows: # tds = r.find_all('td', colspan="2") # if len(tds) >= 2: # origin_td = tds[0] # origin_text = origin_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_origin=origin_text # # destination_td = tds[1] # destination_text = destination_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_destination=destination_text else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': # kill.quarantine_code_state = 'contradiction' if kill.quarantine_weight_of_carcasses > 0: kill.quarantine_weight_of_carcasses = 0 kill.save() def get_gid_out_province_cron_job(): kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0, clearance_code__isnull=False, trash=False) session = requests.Session() session.mount('https://', SSLAdapter()) if kills: for kill in kills: try: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': # kill.quarantine_code_state = 'notconfirmed' # if kill.quarantine_quantity is not None: # kill.quarantine_weight_of_carcasses = None pass else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) # kill.inquiry_date = date.date() if kill.date: send_date = kill.date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[0:1]: quantity = r.find_all('td')[1] match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_weight_of_carcasses = int(number) # if kill.quarantine_code_state is not None: # kill.quarantine_code_state=None else: kill.quarantine_weight_of_carcasses = 0 # for i in table[4:5]: # rows = i.find_all('tr') # # pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', # style='font-family:Tahoma').text.strip() # kill.inquiry_pelak=pelak_txt # td=rows[1].find_all('td')[1] # driver_txt = td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_driver=driver_txt # # for r in rows: # tds = r.find_all('td', colspan="2") # if len(tds) >= 2: # origin_td = tds[0] # origin_text = origin_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_origin=origin_text # # destination_td = tds[1] # destination_text = destination_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_destination=destination_text # else: # for table in table: # p_tags = table.find_all('p') # for p in p_tags: # p_text = p.get_text(strip=True) # if p_text == 'شماره رهگيري وارد شده معتبر نيست.': # kill.quarantine_code_state = 'contradiction' # if kill.quarantine_quantity is not None: # kill.quarantine_quantity = None kill.save() except Exception: continue def get_gid_out_province_manual(request): kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0, clearance_code__isnull=False, trash=False) session = requests.Session() session.mount('https://', SSLAdapter()) if kills: for kill in kills: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': # kill.quarantine_code_state = 'notconfirmed' # if kill.quarantine_quantity is not None: # kill.quarantine_weight_of_carcasses = None pass else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) # kill.inquiry_date = date.date() send_date = kill.date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[0:1]: quantity = r.find_all('td')[1] match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_weight_of_carcasses = int(number) # if kill.quarantine_code_state is not None: # kill.quarantine_code_state=None else: kill.quarantine_weight_of_carcasses = 0 # for i in table[4:5]: # rows = i.find_all('tr') # # pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', # style='font-family:Tahoma').text.strip() # kill.inquiry_pelak=pelak_txt # td=rows[1].find_all('td')[1] # driver_txt = td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_driver=driver_txt # # for r in rows: # tds = r.find_all('td', colspan="2") # if len(tds) >= 2: # origin_td = tds[0] # origin_text = origin_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_origin=origin_text # # destination_td = tds[1] # destination_text = destination_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_destination=destination_text # else: # for table in table: # p_tags = table.find_all('p') # for p in p_tags: # p_text = p.get_text(strip=True) # if p_text == 'شماره رهگيري وارد شده معتبر نيست.': # kill.quarantine_code_state = 'contradiction' # if kill.quarantine_quantity is not None: # kill.quarantine_quantity = None kill.save() return HttpResponse(f'تعداد بار :{len(kills)}') def get_gid_poultry_request(poultry_id): kill = PoultryRequest.objects.filter(id=poultry_id, trash=False).first() session = requests.Session() session.mount('https://', SSLAdapter()) if kill: # if kill.quarantine_code_state!='merge': data = {'gid': str(kill.quarantine_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': kill.quarantine_code_state = 'notconfirmed' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) # kill.inquiry_date = date.date() send_date = kill.send_date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_quantity = int(number) # if kill.quarantine_code_state is not None: # kill.quarantine_code_state=None # for i in table[4:5]: # rows = i.find_all('tr') # # pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', # style='font-family:Tahoma').text.strip() # kill.inquiry_pelak=pelak_txt # td=rows[1].find_all('td')[1] # driver_txt = td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_driver=driver_txt # # for r in rows: # tds = r.find_all('td', colspan="2") # if len(tds) >= 2: # origin_td = tds[0] # origin_text = origin_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_origin=origin_text # # destination_td = tds[1] # destination_text = destination_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_destination=destination_text else: kill.quarantine_quantity = 0 else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': # kill.quarantine_code_state = 'contradiction' if kill.quarantine_quantity > 0: kill.quarantine_quantity = 0 kill.save() def get_gid_poultry_request_quarantine_code(poultry_id): kill = PoultryRequestQuarantineCode.objects.filter(id=poultry_id, trash=False).first() session = requests.Session() session.mount('https://', SSLAdapter()) if kill: # if kill.quarantine_code_state!='merge': data = {'gid': str(kill.quarantine_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': # kill.quarantine_code_state = 'notconfirmed' # if kill.quarantine_quantity is not None: # kill.quarantine_quantity = None if kill.system_quarantine_quantity > 0: kill.system_quarantine_quantity = 0 else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) # kill.inquiry_date = date.date() send_date = kill.poultry_request.send_date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.system_quarantine_quantity = int(number) # if kill.quarantine_code_state is not None: # kill.quarantine_code_state=None # for i in table[4:5]: # rows = i.find_all('tr') # # pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', # style='font-family:Tahoma').text.strip() # kill.inquiry_pelak=pelak_txt # td=rows[1].find_all('td')[1] # driver_txt = td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_driver=driver_txt # # for r in rows: # tds = r.find_all('td', colspan="2") # if len(tds) >= 2: # origin_td = tds[0] # origin_text = origin_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_origin=origin_text # # destination_td = tds[1] # destination_text = destination_td.find('span', class_='dynamictxt').text.strip() # kill.inquiry_destination=destination_text else: kill.system_quarantine_quantity = 0 else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': # kill.quarantine_code_state = 'contradiction' if kill.system_quarantine_quantity > 0: kill.system_quarantine_quantity = 0 kill.save() @api_view(["GET"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def dashboard_monitoring_view(request): now = datetime.datetime.now().date() yesterday = now - timedelta(days=1) hatching = PoultryHatching.objects.filter( state='pending', archive=False, allow_hatching='pending', trash=False ).only( 'quantity', 'killed_quantity', 'left_over', 'chicken_age', 'poultry' ).select_related('poultry') hatching_aggregates = hatching.aggregate( total_quantity=Sum('quantity'), total_killed_quantity=Sum('killed_quantity'), total_left_over=Sum('left_over'), total_left_over_between_40_75=Sum( 'left_over', filter=Q(chicken_age__range=(40, 75)) ), # total_left_over_lt_35=Sum( 'left_over', filter=Q(chicken_age__lt=35) ), total_left_over_between_35_40=Sum( 'left_over', filter=Q(chicken_age__range=(35, 39)) ), total_left_over_between_40_45=Sum( 'left_over', filter=Q(chicken_age__range=(40, 44)) ), total_left_over_between_45_50=Sum( 'left_over', filter=Q(chicken_age__range=(45, 49)) ), total_left_over_between_50_55=Sum( 'left_over', filter=Q(chicken_age__range=(50, 54)) ), total_left_over_between_55_60=Sum( 'left_over', filter=Q(chicken_age__range=(55, 59)) ), total_left_over_between_60_65=Sum( 'left_over', filter=Q(chicken_age__range=(60, 64)) ), total_left_over_between_65_70=Sum( 'left_over', filter=Q(chicken_age__range=(65, 70)) ), total_left_over_gt_70=Sum( 'left_over', filter=Q(chicken_age__gt=70) ), # total_killing_ave_age=Avg('poultry__killing_ave_age') ) kill_house_free_bar = KillHouseFreeBarInformation.objects.filter( trash=False, archive_wage=False, date__date__gte=yesterday ).only( 'quantity', 'live_weight', 'number_of_carcasses', 'weight_of_carcasses', 'send_date', 'type', 'out' ) kill_house_free_bar_aggregates = kill_house_free_bar.aggregate( total_quantity_yesterday_live=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')), total_weight_yesterday_live=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')), total_quantity_yesterday_carcass=Sum('number_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')), total_weight_yesterday_carcass=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')), total_quantity_live=Sum('quantity', filter=Q(create_date__date=now, buy_type='live')), total_weight_live=Sum('live_weight', filter=Q(create_date__date=now, buy_type='live')), total_quantity_carcass=Sum('number_of_carcasses', filter=Q(date__date=now, buy_type='carcass')), total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now, buy_type='carcass')), warehouse_total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now)), # yesterday total_quantity_live_yesterday=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')), total_weight_live_yesterday=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')), total_quantity_carcass_yesterday=Sum('number_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')), total_weight_carcass_yesterday=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')), ) poultry_request = PoultryRequest.objects.filter( trash=False, state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted'), out_province_request_cancel=False, temporary_trash=False, temporary_deleted=False, send_date__date__gte=yesterday ).only( 'quantity', 'Index_weight', 'send_date' ) poultry_request_aggregates = poultry_request.aggregate( total_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=False, out=False)), total_weight=Sum(F('quantity') * F('Index_weight'), filter=Q(send_date__date=now, direct_buying=False, out=False)), total_direct_buying_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=True)), total_direct_buying_weight=Sum(F('quantity') * F('Index_weight'), filter=Q(send_date__date=now, direct_buying=True)), total_quantity_out_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)), poultry_out_province_quantity=Sum('quantity', filter=Q(out=True, send_date__date=now)), poultry_out_province_weight=Sum(F('quantity') * F('Index_weight'), filter=Q(out=True, send_date__date=now)), total_killing_ave_weight=Avg('Index_weight', filter=Q(send_date__date=now)), # yesterday total_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=False, out=False)), total_weight_yesterday=Sum(F('quantity') * F('Index_weight'), filter=Q(send_date__date=yesterday, direct_buying=False, out=False)), total_direct_buying_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=True)), total_direct_buying_weight_yesterday=Sum(F('quantity') * F('Index_weight'), filter=Q(send_date__date=yesterday, direct_buying=True)), poultry_out_province_quantity_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)), poultry_out_province_weight_yesterday=Sum(F('quantity') * F('Index_weight'), filter=Q(out=True, send_date__date=yesterday)), total_killing_ave_weight_yesterday=Avg('Index_weight', filter=Q(send_date__date=now)) ) province_kill_request = ProvinceKillRequest.objects.filter( trash=False, archive_wage=False, return_to_province=False, state__in=('pending', 'accepted'), kill_request__recive_date__date__gte=yesterday ).only( 'total_killed_quantity', 'total_killed_weight', 'kill_request__recive_date' ) province_kill_request_aggregates = province_kill_request.aggregate( total_quantity_yesterday=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=yesterday)), total_weight_yesterday=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=yesterday)), total_quantity=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=now)), total_weight_carcass=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)) * 0.75, province_kill_request_total_weight=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)), province_kill_request_total_weight_yesterday=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=yesterday)) ) kill_house_request = KillHouseRequest.objects.filter( trash=False, kill_request__recive_date__date__gte=yesterday, temporary_trash=False, temporary_deleted=False ).select_related('kill_request').only( 'ware_house_accepted_real_weight', 'weight_loss', 'ware_house_confirmation', 'kill_request__recive_date' ) kill_house_request_aggregates = kill_house_request.aggregate( total_real_weight=Sum( 'ware_house_accepted_real_weight', filter=Q( kill_request__recive_date__date=yesterday, ware_house_confirmation=True ) ), total_weight_loss=Avg( 'weight_loss', filter=Q(kill_request__recive_date__date=yesterday) ), total_quantity=Sum( 'accepted_real_quantity', filter=Q(kill_request__recive_date__date=now) ), total_quantity_yesterday=Sum( 'accepted_real_quantity', filter=Q(kill_request__recive_date__date=yesterday) ), total_weight_yesterday=Sum( 'accepted_real_weight', filter=Q(kill_request__recive_date__date=yesterday) ), total_weight=Sum( 'accepted_real_weight', filter=Q(kill_request__recive_date__date=now) ), total_real_weight_yesterday=Sum( 'ware_house_accepted_real_weight', filter=Q( kill_request__recive_date__date=yesterday, ware_house_confirmation=True ) ) ) kill_request = KillRequest.objects.filter( recive_date__date=now, trash=False, poultry__isnull=True, province_state='accepted' ).only( 'kill_capacity', 'recive_date', 'province_state' ) kill_request_aggregates = kill_request.aggregate( total_quantity=Sum('kill_capacity'), ) if hatching_aggregates['total_left_over_between_40_75'] and poultry_request_aggregates['total_killing_ave_weight']: weight_between_forty_seventy_five = int(hatching_aggregates['total_left_over_between_40_75'] * poultry_request_aggregates['total_killing_ave_weight']) else: weight_between_forty_seventy_five = 0 enter_warehouse_weight = (kill_house_free_bar_aggregates['warehouse_total_weight_carcass'] or 0) + ( kill_house_request_aggregates['total_real_weight_yesterday'] or 0) roles_product = RolesProducts.objects.filter(trash=False) roles_product_aggregates = roles_product.aggregate( total_remain_weight=Sum('total_remain_weight'), total_out_province_allocated_weight=Sum('out_province_allocated_weight'), ) cold_house = ColdHouse.objects.filter(trash=False).only( 'total_remain_weight' ) cold_house_aggregates = cold_house.aggregate( total_freezing_weight=Sum('total_remain_weight') ) kill_house_free_sale_bar_aggregates = KillHouseFreeSaleBarInformation.objects.filter( trash=False ).aggregate( total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'), total_real_weight_of_carcasses_now=Sum('real_weight_of_carcasses', filter=Q(date__date=now)) ) steward_allocation = StewardAllocation.objects.filter( trash=False, calculate_status=True, temporary_trash=False, temporary_deleted=False, receiver_state__in=('accepted', 'pending') ).exclude( seller_type='ColdHouse' ).only( 'real_weight_of_carcasses', 'date' ) steward_allocation_aggregates = steward_allocation.aggregate( total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'), total_real_weight_of_carcasses_now=Sum( 'real_weight_of_carcasses', filter=Q(date__date=now) ), ) chicken_price = ChickenCommissionPrices.objects.filter(trash=False, date__date__gte=now - timedelta(7)).order_by( 'date') ser_data = ChickenCommissionPricesForDashboardSerializer(chicken_price, many=True) province_kill_request_weight = province_kill_request_aggregates['province_kill_request_total_weight'] or 0 province_kill_request_total_weight_yesterday = province_kill_request_aggregates[ 'province_kill_request_total_weight_yesterday'] or 0 province_kill_request_weight_yesterday = province_kill_request_aggregates['total_weight_yesterday'] or 0 bars_live_weight = kill_house_free_bar_aggregates['total_weight_live'] or 0 total_weight_live_yesterday = kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0 bars_carcasses_weight = kill_house_free_bar_aggregates['total_weight_carcass'] or 0 total_weight_carcass_yesterday = kill_house_free_bar_aggregates['total_weight_carcass_yesterday'] or 0 bars_yesterday_carcasses_weight = kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0 bars_yesterday_live_weight = kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0 total_loss_weight = int(((province_kill_request_weight + bars_live_weight) * 0.75) + bars_carcasses_weight) total_loss_weight_yesterday = int(((province_kill_request_total_weight_yesterday + total_weight_live_yesterday) * 0.75) + total_weight_carcass_yesterday) total_yesterday_loss_weight = int(((province_kill_request_weight_yesterday + bars_yesterday_live_weight) * 0.75) + bars_yesterday_carcasses_weight) result = { 'hatching': { 'quantity': hatching_aggregates['total_quantity'] or 0, 'killedQuantity': hatching_aggregates['total_killed_quantity'] or 0, 'leftOver': hatching_aggregates['total_left_over'] or 0, 'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0, 'killingAveAge': int(hatching_aggregates['total_killing_ave_age'] or 0), 'total_left_over_lt_35': int(hatching_aggregates['total_left_over_lt_35'] or 0), 'total_left_over_between_35_40': int(hatching_aggregates['total_left_over_between_35_40'] or 0), 'total_left_over_between_40_45': int(hatching_aggregates['total_left_over_between_40_45'] or 0), 'total_left_over_between_45_50': int(hatching_aggregates['total_left_over_between_45_50'] or 0), 'total_left_over_between_50_55': int(hatching_aggregates['total_left_over_between_50_55'] or 0), 'total_left_over_between_55_60': int(hatching_aggregates['total_left_over_between_55_60'] or 0), 'total_left_over_between_60_65': int(hatching_aggregates['total_left_over_between_60_65'] or 0), 'total_left_over_between_65_70': int(hatching_aggregates['total_left_over_between_65_70'] or 0), 'total_left_over_gt_70': int(hatching_aggregates['total_left_over_gt_70'] or 0), }, 'yesterdayKilling': { 'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_yesterday_live'] or 0, 'weightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0, 'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_yesterday_carcass'] or 0, 'weightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0, 'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity_yesterday'] or 0, 'provinceKillRequestWeight': province_kill_request_aggregates['total_weight_yesterday'] or 0, 'outQuantity': poultry_request_aggregates['total_quantity_out_yesterday'] or 0, # 'weightOfCarcass': kill_house_request_aggregates['total_real_weight'] or 0, # 'losses': round((kill_house_request_aggregates['total_weight_loss'] or 0),1), 'weightOfCarcass': total_yesterday_loss_weight, 'losses': 25, }, 'killing': { 'quantity': poultry_request_aggregates['total_quantity'] or 0, 'total_weight': poultry_request_aggregates['total_weight'] or 0, 'killRequestQuantity': poultry_request_aggregates['total_direct_buying_quantity'] or 0, 'killRequestWeight': poultry_request_aggregates['total_direct_buying_weight'] or 0, # 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0, 'poultry_out_province_quantity': poultry_request_aggregates['poultry_out_province_quantity'] or 0, 'poultry_out_province_weight': poultry_request_aggregates['poultry_out_province_weight'] or 0, 'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_live'] or 0, 'WeightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_live'] or 0, 'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_carcass'] or 0, 'WeightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_carcass'] or 0, 'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity'] or 0, 'provinceKillRequestWeightCarcass': int( province_kill_request_aggregates['province_kill_request_total_weight'] or 0), 'KillHouseRequestQuantity': kill_house_request_aggregates['total_quantity'] or 0, 'KillHouseRequestWeight': kill_house_request_aggregates['total_weight'] or 0, 'total_loss_weight': int(total_loss_weight), }, 'killingYesterday': { 'quantityYesterday': poultry_request_aggregates['total_quantity_yesterday'] or 0, 'total_weightYesterday': poultry_request_aggregates['total_weight_yesterday'] or 0, 'killRequestQuantityYesterday': poultry_request_aggregates['total_direct_buying_quantity_yesterday'] or 0, 'killRequestWeightYesterday': poultry_request_aggregates['total_direct_buying_weight_yesterday'] or 0, # 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0, 'poultry_out_province_quantityYesterday': poultry_request_aggregates[ 'poultry_out_province_quantity_yesterday'] or 0, 'poultry_out_province_weightYesterday': poultry_request_aggregates[ 'poultry_out_province_weight_yesterday'] or 0, 'quantityKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates[ 'total_quantity_live_yesterday'] or 0, 'WeightKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0, 'quantityKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[ 'total_quantity_carcass_yesterday'] or 0, 'WeightKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[ 'total_weight_carcass_yesterday'] or 0, 'provinceKillRequestQuantityYesterday': province_kill_request_aggregates['total_quantity_yesterday'] or 0, 'provinceKillRequestWeightCarcassYesterday': int( province_kill_request_aggregates['province_kill_request_total_weight_yesterday'] or 0), 'KillHouseRequestQuantityYesterday': kill_house_request_aggregates['total_quantity_yesterday'] or 0, 'KillHouseRequestWeightYesterday': kill_house_request_aggregates['total_weight_yesterday'] or 0, 'total_loss_weightYesterday': int(total_loss_weight_yesterday), }, 'inventory': { 'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0, 'weightBetweenFortySeventyFive': weight_between_forty_seventy_five, 'aveWeight': round((poultry_request_aggregates['total_killing_ave_weight'] or 0), 1), 'carcassWeight': int(weight_between_forty_seventy_five * 0.75), }, 'warehouseKillHouse': { 'remainingChickenStock': roles_product_aggregates['total_remain_weight'] or 0, 'remainingFreezingWeight': cold_house_aggregates['total_freezing_weight'] or 0, 'outProvinceAllocatedWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses'] or 0, 'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses'] or 0, }, 'warehouseInformation': { 'enterWarehouseWeight': enter_warehouse_weight, 'outSellWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses_now'] or 0, 'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses_now'] or 0, 'leftOverWarehouseWeight': roles_product_aggregates['total_remain_weight'] or 0, }, 'chickenPrice': ser_data.data } return Response(result, status=status.HTTP_200_OK) def remove_access_token_manual(request): ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/" requests.get( url=ARTA_remove_access_token, verify=False ) now = datetime.datetime.now() accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3)) for access in accesses: access.expires = now - timedelta(days=2) access.save() return HttpResponse('ok') def find_gid_code_manual(request): kill_house_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False, quarantine_quantity__isnull=True).only( 'quarantine_code_state', 'clearance_code', 'quarantine_quantity' ).order_by('-id') session = requests.Session() session.mount('https://', SSLAdapter()) for kill in kill_house_request: if kill.quarantine_code_state != 'merge': if kill.clearance_code is None: kill.quarantine_code_state = 'noclearance' else: data = {'gid': str(kill.clearance_code)} m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'}) context = BeautifulSoup(m.text, 'html.parser') text = context.body.get_text(strip=True) if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.': kill.quarantine_code_state = 'notconfirmed' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None else: table = context.find_all('table') if table[5:6]: row = context.find('div', align="right") if row: content = row.get_text(separator=" ", strip=True) date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content) if date_match: jalali_date = date_match.group(1) year, month, day = map(int, jalali_date.split('/')) date = convert_to_miladi(year=year, month=month, day=day) kill.inquiry_date = date.date() send_date = kill.kill_request.recive_date.date() one_day = timedelta(days=1) if abs(send_date - date.date()) <= one_day: for i in table[5:6]: row = i.find_all('tr') for r in row[1:2]: quantity = r.find('td') match = re.search(r'\d+', quantity.text) if match: number = match.group() kill.quarantine_quantity = int(number) if kill.quarantine_code_state is not None: kill.quarantine_code_state = None for i in table[4:5]: rows = i.find_all('tr') pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr', style='font-family:Tahoma').text.strip() kill.inquiry_pelak = pelak_txt td = rows[1].find_all('td')[1] driver_txt = td.find('span', class_='dynamictxt').text.strip() kill.inquiry_driver = driver_txt for r in rows: tds = r.find_all('td', colspan="2") if len(tds) >= 2: origin_td = tds[0] origin_text = origin_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_origin = origin_text destination_td = tds[1] destination_text = destination_td.find('span', class_='dynamictxt').text.strip() kill.inquiry_destination = destination_text else: kill.quarantine_code_state = 'contradiction' kill.quarantine_quantity = None else: for table in table: p_tags = table.find_all('p') for p in p_tags: p_text = p.get_text(strip=True) if p_text == 'شماره رهگيري وارد شده معتبر نيست.': kill.quarantine_code_state = 'contradiction' if kill.quarantine_quantity is not None: kill.quarantine_quantity = None kill.save() return HttpResponse('ok') @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def get_all_pos_transaction(request): filters = {} date1 = request.GET.get('date1') date2 = request.GET.get('date2') price_type = request.GET.get('price_type') paid = request.GET.get('paid') validator = PosDeviceValidator(request) validation_error = validator.validation_version() if validation_error: return validation_error validation_device = validator.validation_device() if not validation_device: return Response({"result": "نشست شما منقضی شده لطفا مجدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED) pos = POSMachine.objects.get(pos_id=validation_device) filters['trash'] = False filters['pos'] = pos if date1 and date2: date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() filters['date__date__gte'] = date1 filters['date__date__lte'] = date2 if price_type: filters['price_type__in'] = price_type.split(',') if paid: filters['paid'] = True if paid == 'true' else False transactions = PosMachineTransactions.objects.filter(**filters).only('price', 'price_type').order_by('-date') product_transactions = ProductsTransactions.objects.filter(trash=False, transaction__in=transactions).only \ ('price', 'cur_weight', 'targetunit', 'image') transactions_aggregate = transactions.aggregate( total_price=Sum('price'), total_price_cash=Sum('price', filter=Q(price_type='cash')), total_price_credit=Sum('price', filter=Q(price_type='credit')), total_price_card=Sum('price', filter=Q(price_type='card')), ) product_groups = defaultdict(lambda: {'price': 0, 'weight': 0, 'targetunit': None, 'image': None}) for pt in product_transactions: product_groups[pt.name]['price'] += pt.price product_groups[pt.name]['weight'] += pt.cur_weight if not product_groups[pt.name]['targetunit']: product_groups[pt.name]['targetunit'] = pt.targetunit if not product_groups[pt.name]['image']: product_groups[pt.name]['image'] = pt.image unique_products = [{ 'name': name, 'price': data['price'], 'weight': data['weight'], 'targetunit': data['targetunit'], 'image': data['image'] } for name, data in product_groups.items()] result_dict = { 'count': transactions.count(), 'total_price': transactions_aggregate['total_price'] or 0, 'total_price_cash': transactions_aggregate['total_price_cash'] or 0, 'total_price_credit': transactions_aggregate['total_price_credit'] or 0, 'total_price_card': transactions_aggregate['total_price_card'] or 0, 'products': unique_products } return Response(result_dict) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def send_clearance_code_to_rsi(request): date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None kill_house_request = KillHouseRequest.objects.filter( trash=False, temporary_trash=False, temporary_deleted=False, clearance_code__isnull=False ).values_list('clearance_code', flat=True).distinct() kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \ .values_list('quarantine_code', flat=True).distinct() result = list(kill_house_request) + list(kill_house_free_sale) response = requests.post( f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}' f'&date1={date1}&date2={date2}', json=result, headers={'Content-Type': 'application/json'} ) output = BytesIO() workbook = Workbook() worksheet = workbook.active workbook.remove(worksheet) sheet_list = [ 'بار های داخل استان', 'بار های خارج استان' ] for sheet_name in sheet_list: worksheet = workbook.create_sheet(sheet_name) if sheet_name == 'بار های داخل استان': worksheet.sheet_view.rightToLeft = True worksheet.insert_rows(1) cell = worksheet.cell(row=1, column=1) cell.alignment = Alignment(horizontal='center', vertical='center') header_list = [ 'تعداد مرغداران', 'تعداد کشتارگاه ها', 'حجم کشتار', ] create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') value_header_list = [ ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') excel_options = [ 'ردیف', 'تاریخ کشتار', 'مرغدار', 'شناسه یکتا مرغدار', 'شماره مجوز جوجه ریزی', 'شماره موبایل مرغدار', 'شهر مرغدار', 'دامپزشک فارم', 'تلفن دامپزشک فارم', 'کد قرنطینه', 'کشتارگاه', 'شناسه یکتا کشتارگاه', 'استان', 'شهر', 'حجم کشتار', 'سن کشتار', ] m = 1 create_header_freez(worksheet, excel_options, 1, 6, 7, 20) l = 7 unique_poultry_out_false = set() unique_slaughterhouses_out_false = set() total_slaughter_out_false = 0 excel_description(worksheet, 'A1', f'بارهای داخل استان', color='red', row2='B1') if 'date1' in request.GET: date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() from_date1 = shamsi_date(date1) from_date2 = shamsi_date(date2) excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') for data in response.json(): if data['Out'] == False: vet_farm_mobile = '' vet_farm_name = '' vet_farm = VetFarm.objects.filter(trash=False, poultry__breeding_unique_id=data['hatching']['poultry'][ 'PartIdCode']).first() if vet_farm: vet_farm_mobile = vet_farm.vet.user.mobile vet_farm_name = vet_farm.vet.user.fullname unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) unique_slaughterhouses_out_false.add(data['DesUnitName']) total_slaughter_out_false += data['GoodAmount'] date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() list1 = [ m, str(shamsi_date(date, in_value=True)), data['hatching']['poultry']['UnitName'], data['hatching']['poultry']['PartIdCode'], data['hatching']['RequestCode'], data['hatching']['poultry']['Mobile'], data['hatching']['poultry']['City'], vet_farm_name, vet_farm_mobile, data['TrackingCode'], data['DesUnitName'], data['DesPartIdCode'], data['Province'], data['City'], data['GoodAmount'], data['Age'], ] create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) l += 1 m += 1 value_header_list = [ len(unique_poultry_out_false), len(unique_slaughterhouses_out_false), total_slaughter_out_false ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') quantity = sum( data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0 list2 = [ 'مجموع==>', '', '', '', '', '', '', '', '', '', '', '', '', '', quantity, '', ] create_value(worksheet, list2, l + 1, 1, color='green') else: unique_poultry_out_false = set() unique_slaughterhouses_out_false = set() total_slaughter_out_false = 0 worksheet.sheet_view.rightToLeft = True worksheet.insert_rows(1) cell = worksheet.cell(row=1, column=1) cell.alignment = Alignment(horizontal='center', vertical='center') header_list = [ 'تعداد مرغداران', 'تعداد کشتارگاه ها', 'حجم کشتار', ] create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') excel_options = [ 'ردیف', 'تاریخ کشتار', 'مرغدار', 'شناسه یکتا مرغدار', 'شماره مجوز جوجه ریزی', 'شماره موبایل مرغدار', 'شهر مرغدار', 'دامپزشک فارم', 'تلفن دامپزشک فارم', 'کد قرنطینه', 'کشتارگاه', 'شناسه یکتا کشتارگاه', 'استان', 'شهر', 'حجم کشتار', 'سن کشتار', ] m = 1 create_header_freez(worksheet, excel_options, 1, 6, 7, 20) l = 7 unique_poultry = set() unique_slaughterhouses = set() total_slaughter = 0 excel_description(worksheet, 'A1', f'بارهای خارج استان', color='red', row2='B1') if 'date1' in request.GET: date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() from_date1 = shamsi_date(date1) from_date2 = shamsi_date(date2) excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') for data in response.json(): if data['Out'] == True: vet_farm_mobile = '' vet_farm_name = '' vet_farm = VetFarm.objects.filter(trash=False, poultry__breeding_unique_id=data['hatching']['poultry'][ 'PartIdCode']).first() if vet_farm: vet_farm_mobile = vet_farm.vet.user.mobile vet_farm_name = vet_farm.vet.user.fullname unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) unique_slaughterhouses_out_false.add(data['DesUnitName']) total_slaughter_out_false += data['GoodAmount'] date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() list1 = [ m, str(shamsi_date(date, in_value=True)), data['hatching']['poultry']['UnitName'], data['hatching']['poultry']['PartIdCode'], data['hatching']['RequestCode'], data['hatching']['poultry']['Mobile'], data['hatching']['poultry']['City'], vet_farm_mobile, vet_farm_name, data['TrackingCode'], data['DesUnitName'], data['DesPartIdCode'], data['Province'], data['City'], data['GoodAmount'], data['Age'], ] create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) l += 1 m += 1 value_header_list = [ len(unique_poultry_out_false), len(unique_slaughterhouses_out_false), total_slaughter_out_false ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') quantity = sum( data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0 list2 = [ 'مجموع==>', '', '', '', '', '', '', '', '', '', '', '', '', '', quantity, '', ] create_value(worksheet, list2, l + 1, 1, color='green') workbook.save(output) output.seek(0) response = HttpResponse( content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response[ 'Content-Disposition'] = f'attachment; filename="اختلاف قرنطینه.xlsx"'.encode( 'utf-8') response.write(output.getvalue()) return response @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def api_send_clearance_code_to_rsi(request): page = '' search_filter = '' province = f'province={base_url_for_sms_report}' search = request.GET.get('search') value = request.GET.get('value') if search: if search != 'undefined' and value.strip(): search_filter = f'&search={search}&value={value}' date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None kill_house_request = KillHouseRequest.objects.filter( trash=False, temporary_trash=False, temporary_deleted=False, clearance_code__isnull=False ).values_list('clearance_code', flat=True).distinct() kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \ .values_list('quarantine_code', flat=True).distinct() result = list(kill_house_request) + list(kill_house_free_sale) if 'page' in request.GET: page = f'&page={request.GET["page"]}&page_size={request.GET["page_size"]}' response = requests.get( f'https://rsibackend.rasadyar.com/app/api_send_different_bar/?{province}{page}' f'{search_filter}' f'&date1={date1}&date2={date2}', json=result, headers={'Content-Type': 'application/json'} ) return Response(response.json(), status=status.HTTP_200_OK) @api_view(["POST"]) @permission_classes([AllowAny]) @csrf_exempt def create_steward_allocation_from_excel(request): file = request.FILES['file'].read() read = openpyxl.load_workbook(BytesIO(file), data_only=True) sheet = read.active result_list = [] for i, row in enumerate(sheet.iter_rows(values_only=True)): if i <= 1: continue mobile = row[3] kill_house_name = row[4] allocation_type = row[5] date = row[6] sell_type = row[7] seller_type = 'KillHouse' type = 'manual' weight_of_carcasses = row[8] amount = row[9] buyer_type = 'Steward' if allocation_type == 'مباشر' else 'Guild' try: miladi_date = date.split('/') new_date = convert_to_miladi( year=int(miladi_date[0]), month=int(miladi_date[1]), day=int(miladi_date[2]) ) kill_house = KillHouse.objects.filter(name=kill_house_name, trash=False).first() user = SystemUserProfile.objects.filter(trash=False, mobile=mobile).first() if user: to_steward = None to_guild = None if buyer_type == 'Steward': to_steward = Guilds.objects.get(user=user, trash=False) else: to_guild = Guilds.objects.get(user=user, trash=False) product = RolesProducts.objects.get(kill_house=kill_house) steward_allocation = StewardAllocation( date=new_date, real_weight_of_carcasses=weight_of_carcasses, weight_of_carcasses=weight_of_carcasses, product=product, kill_house=kill_house, seller_type=seller_type, allocation_type='killhouse_guild' if allocation_type == 'صنف' else 'killhouse_steward', sell_type='exclusive' if sell_type == 'اختصاصی' else 'free', type=type, amount=amount, total_amount=int(amount * weight_of_carcasses), ) if buyer_type == 'Steward': steward_allocation.to_steward = to_steward else: steward_allocation.to_guilds = to_guild steward_allocation.save() kill_house_allocations_product_warehousing(product) except: result_list.append(mobile) return Response(result_list) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def send_bar_info_from_ticket(request): user = SystemUserProfile.objects.get(trash=False, key=request.GET['key']) date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('id') kill_house_request = KillHouseRequest.objects.filter(trash=False, kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2, temporary_trash=False, temporary_deleted=False) if kill_house_request: message = 'با سلام و احترام' \ '***' \ 'بدینوسیله گزارش اسناد بارهای کشتارگاه ها از مورخه {0} تا {1} به شرح زیر بحضور ایفاد میگردد:' \ '***' \ '***'.format(shamsi_date(date1), shamsi_date(date2)) else: message = 'با سلام و احترام' \ '***' \ ' از مورخه {0} تا {1} باری وجود ندارد.' \ '***' \ '***'.format(shamsi_date(date1), shamsi_date(date2)) m = 1 for kill_house in kill_houses: kill_house_request1 = kill_house_request.filter(trash=False, killhouse_user=kill_house, kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2, temporary_trash=False, temporary_deleted=False) bar_count = kill_house_request1.count() bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count() bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True').count() bar_document_status = kill_house_request1.filter(bar_document_status__isnull=False).count() bar_document_status_titles = kill_house_request1.values_list('bar_document_status__title', flat=True) bars_info = [] if (None not in bar_document_status_titles and bar_document_status_titles) or (bar_assigment_pending_count != 0) \ or (bar_assigment_true_count > 0): message += '{0}) {1} :' \ 'تعداد {2} بار ایجاد شده است.***'.format(m, kill_house.name, to_locale_str(bar_count)) if bar_assigment_pending_count > 0 or bar_assigment_true_count > 0: message += '📑 {1} بار دارای سند(بارنامه) و تعداد {0} بار فاقد سند(بارنامه) میباشد.*** '. \ format(to_locale_str(bar_assigment_pending_count), to_locale_str(bar_assigment_true_count)) if bar_document_status > 0: message += '🌐 از بارهای دارای سند تعداد {0} بار توسط ربات هوش مصنوعی سامانه مورد بررسی قرار گرفت که به شرح زیر میباشد: '. \ format(to_locale_str(bar_document_status)) status_counts = Counter(bar_document_status_titles) for title, count in status_counts.items(): if title: bars_info.append( '***' \ '🚛 {0} بار شامل سند ({1})'.format(to_locale_str(count), title)) if bars_info: message += '.'.join(bars_info) message += '***' \ '-------------------------------------------------------' \ '***' \ '***' m += 1 new_ticket = TicketSupport( user=user, title="استعلام اسناد بارها از مورخه {0} تا {1}".format(shamsi_date(date1), shamsi_date(date2)), status='open', read_only=True, type_ticket='single', parent=None, last_message='Admin', ) new_ticket.save() new_ticket.to_user.add(user) msg = MessageSupport( ticket=new_ticket, message=message, created_by=user, sender='Admin' ) msg.save() return Response({'result': 'با موفقیت انجام شد.'}, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def all_clearance_code_to_rsi(request): date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None # kill_house_request = KillHouseRequest.objects.filter( # trash=False, # temporary_trash=False, # temporary_deleted=False, # clearance_code__isnull=False # ).values_list('clearance_code', flat=True).distinct() # # kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \ # .values_list('quarantine_code', flat=True).distinct() result = [] response = requests.post( f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}' f'&date1={date1}&date2={date2}', json=result, headers={'Content-Type': 'application/json'} ) output = BytesIO() workbook = Workbook() worksheet = workbook.active workbook.remove(worksheet) sheet_list = [ 'بار های داخل استان', 'بار های خارج استان' ] for sheet_name in sheet_list: worksheet = workbook.create_sheet(sheet_name) if sheet_name == 'بار های داخل استان': worksheet.sheet_view.rightToLeft = True worksheet.insert_rows(1) cell = worksheet.cell(row=1, column=1) cell.alignment = Alignment(horizontal='center', vertical='center') header_list = [ 'تعداد مرغداران', 'تعداد کشتارگاه ها', 'حجم کشتار', ] create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') value_header_list = [ ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') excel_options = [ 'ردیف', 'تاریخ کشتار', 'مرغدار', 'شناسه یکتا مرغدار', 'شماره مجوز جوجه ریزی', 'شماره موبایل مرغدار', 'شهر مرغدار', 'دامپزشک فارم', 'تلفن دامپزشک فارم', 'کد قرنطینه', 'وضعیت بار', 'کشتارگاه', 'شناسه یکتا کشتارگاه', 'استان', 'شهر', 'حجم کشتار', 'سن کشتار', ] m = 1 create_header_freez(worksheet, excel_options, 1, 6, 7, 20) l = 7 unique_poultry_out_false = set() unique_slaughterhouses_out_false = set() total_slaughter_out_false = 0 excel_description(worksheet, 'A1', f'بارهای داخل استان', color='red', row2='B1') if 'date1' in request.GET: date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() from_date1 = shamsi_date(date1) from_date2 = shamsi_date(date2) excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') for data in response.json(): if data['Out'] == False: vet_farm_mobile = '' vet_farm_name = '' vet_farm = VetFarm.objects.filter(trash=False, poultry__breeding_unique_id=data['hatching']['poultry'][ 'PartIdCode']).first() if vet_farm: vet_farm_mobile = vet_farm.vet.user.mobile vet_farm_name = vet_farm.vet.user.fullname unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) unique_slaughterhouses_out_false.add(data['DesUnitName']) total_slaughter_out_false += data['GoodAmount'] date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() list1 = [ m, str(shamsi_date(date, in_value=True)), data['hatching']['poultry']['UnitName'], data['hatching']['poultry']['PartIdCode'], data['hatching']['RequestCode'], data['hatching']['poultry']['Mobile'], data['hatching']['poultry']['City'], vet_farm_name, vet_farm_mobile, data['TrackingCode'], data['TrackingStatusDescription'], data['DesUnitName'], data['DesPartIdCode'], data['Province'], data['City'], data['GoodAmount'], data['Age'], ] create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) l += 1 m += 1 value_header_list = [ len(unique_poultry_out_false), len(unique_slaughterhouses_out_false), total_slaughter_out_false ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') quantity = sum( data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0 list2 = [ 'مجموع==>', '', '', '', '', '', '', '', '', '', '', '', '', '', '', quantity, '', ] create_value(worksheet, list2, l + 1, 1, color='green') else: unique_poultry_out_false = set() unique_slaughterhouses_out_false = set() total_slaughter_out_false = 0 worksheet.sheet_view.rightToLeft = True worksheet.insert_rows(1) cell = worksheet.cell(row=1, column=1) cell.alignment = Alignment(horizontal='center', vertical='center') header_list = [ 'تعداد مرغداران', 'تعداد کشتارگاه ها', 'حجم کشتار', ] create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000') excel_options = [ 'ردیف', 'تاریخ کشتار', 'مرغدار', 'شناسه یکتا مرغدار', 'شماره مجوز جوجه ریزی', 'شماره موبایل مرغدار', 'شهر مرغدار', 'دامپزشک فارم', 'تلفن دامپزشک فارم', 'کد قرنطینه', 'وضعیت بار', 'کشتارگاه', 'شناسه یکتا کشتارگاه', 'استان', 'شهر', 'حجم کشتار', 'سن کشتار', ] m = 1 create_header_freez(worksheet, excel_options, 1, 6, 7, 20) l = 7 unique_poultry = set() unique_slaughterhouses = set() total_slaughter = 0 excel_description(worksheet, 'A1', f'بارهای خارج استان', color='red', row2='B1') if 'date1' in request.GET: date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() from_date1 = shamsi_date(date1) from_date2 = shamsi_date(date2) excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3') for data in response.json(): if data['Out'] == True: vet_farm_mobile = '' vet_farm_name = '' vet_farm = VetFarm.objects.filter(trash=False, poultry__breeding_unique_id=data['hatching']['poultry'][ 'PartIdCode']).first() if vet_farm: vet_farm_mobile = vet_farm.vet.user.mobile vet_farm_name = vet_farm.vet.user.fullname unique_poultry_out_false.add(data['hatching']['poultry']['UnitName']) unique_slaughterhouses_out_false.add(data['DesUnitName']) total_slaughter_out_false += data['GoodAmount'] date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() list1 = [ m, str(shamsi_date(date, in_value=True)), data['hatching']['poultry']['UnitName'], data['hatching']['poultry']['PartIdCode'], data['hatching']['RequestCode'], data['hatching']['poultry']['Mobile'], data['hatching']['poultry']['City'], vet_farm_mobile, vet_farm_name, data['TrackingCode'], data['TrackingStatusDescription'], data['DesUnitName'], data['DesPartIdCode'], data['Province'], data['City'], data['GoodAmount'], data['Age'], ] create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35) l += 1 m += 1 value_header_list = [ len(unique_poultry_out_false), len(unique_slaughterhouses_out_false), total_slaughter_out_false ] create_value(worksheet, value_header_list, 3, 4, border_style='thin') quantity = sum( data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0 list2 = [ 'مجموع==>', '', '', '', '', '', '', '', '', '', '', '', '', '', '', quantity, '', ] create_value(worksheet, list2, l + 1, 1, color='green') workbook.save(output) output.seek(0) response = HttpResponse( content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response[ 'Content-Disposition'] = f'attachment; filename="گزارش کلی بار ها.xlsx"'.encode( 'utf-8') response.write(output.getvalue()) return response @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def ticket_different_clearance_code_from_rsi(request): date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None poultry_hatchings_licence_numbers = PoultryHatching.objects.filter(trash=False, licence_number=request.GET.get('licence_number')) for poultry_hatching in poultry_hatchings_licence_numbers: poultry_hatching_licence_number = poultry_hatching.licence_number response = requests.post( f'https://rsibackend.rasadyar.com/app/send_different_bar_with_licence_number/?' f'licence_number={poultry_hatching_licence_number}' f'&date1={date1}&date2={date2}', headers={'Content-Type': 'application/json'} ) kill_house_request = KillHouseRequest.objects.filter(trash=False, province_request__poultry_request__hatching__licence_number =poultry_hatching_licence_number, temporary_trash=False, temporary_deleted=False).order_by( '-kill_request__recive_date') if date1: kill_house_request.filter(kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2) vet_farm = VetFarm.objects.filter(trash=False, poultry=poultry_hatching.poultry).first() code_rasadyar = [] all_quantity_in_rsi = 0 for i in response.json(): all_quantity_in_rsi += i['GoodAmount'] bars_info = [] for kill_req in kill_house_request: if kill_req.clearance_code: quarantine_code = kill_req.clearance_code code_rasadyar.append(quarantine_code) else: quarantine_code = 'ندارد' bars_info.append( 'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format( quarantine_code, to_locale_str(int(kill_req.accepted_real_quantity)), kill_req.killhouse_user.name, shamsi_date(kill_req.kill_request.recive_date) )) poultry_requests = PoultryRequest.objects.filter(trash=False, out=True, state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted'), out_province_request_cancel=False, hatching=poultry_hatching).order_by( '-send_date' ) # code_rsi=[data['TrackingCode'] for data in response.json()] bars_info_rsi = [] rsi_quantity = 0 for poultry_request in poultry_requests: if poultry_request.quarantine_code: quarantine_code = poultry_request.quarantine_code code_rasadyar.append(quarantine_code) else: quarantine_code = 'ندارد' bars_info.append( 'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format( quarantine_code, to_locale_str(int(poultry_request.quantity)), poultry_request.buyer_fullname, shamsi_date(poultry_request.send_date), )) chain_allocations = ChainAllocation.objects.filter(trash=False, poultry_hatching=poultry_hatching).order_by( '-date') for poultry_request in chain_allocations: if poultry_request.quarantine_code: quarantine_code = poultry_request.quarantine_code code_rasadyar.append(quarantine_code) else: quarantine_code = 'ندارد' bars_info.append( 'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format( quarantine_code, to_locale_str(int(poultry_request.quantity)), poultry_request.buyer_name, shamsi_date(poultry_request.date), )) for bar in response.json(): rsi_quantity += bar['GoodAmount'] date_str = str(bar['Date']).split('T')[0] date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date() state = '✅' if bar['TrackingCode'] in code_rasadyar else '❌' bars_info_rsi.append( 'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3}){4}'.format( bar['TrackingCode'], to_locale_str(int(bar['GoodAmount'])), bar['DesUnitName'], shamsi_date(date), state )) bars_details = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info)]) bars_details_rsi = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info_rsi)]) accepted_real_quantity = 0 accepted_real_quantity += kill_house_request.aggregate( total_quantity=Sum('accepted_real_quantity')).get('total_quantity') or 0 accepted_real_quantity += chain_allocations.aggregate( total_quantity=Sum('quantity')).get('total_quantity') or 0 accepted_real_quantity += poultry_requests.aggregate( total_quantity=Sum('quantity')).get('total_quantity') or 0 if rsi_quantity - accepted_real_quantity > 0: new_message = 'در مجموع شما {0} قطعه بدون مجوز کشتار در سامانه قرنطینه ثبت کرده اید.' \ '***' \ 'در صورت تکرار و عدم رعایت موضوع و ضوابط اجرایی در استان،مراتب و گزارش تخلف به مراجع مسئول ارجاع میگردد.' \ '***' \ '***' \ .format(to_locale_str(int(rsi_quantity - accepted_real_quantity))) new_message1 = 'خارج از سامانه مجوز حمل' else: new_message = '' new_message1 = 'اطلاعات زیر' message = " دامپزشک محترم فارم {0}({9})" \ "***" \ "با سلام" \ "***" \ "با توجه بررسی های انجام شده" \ " و استعلامات از پایش کشوری سامانه" \ " رصد یار برای فارم {1} با شناسه یکتا {10} و شماره مجوز جوجه ریزی {11} {12} صادر گردیده است." \ "***" \ "***" \ "اطلاعات مجوز صادر شده در قرنطینه:" \ "***" \ "{2}" \ "***" \ "جمعا {3} بار با مجموع {4} قطعه" \ "***" \ "***" \ "اطلاعات مجوز صادر شده در رصدیار : " \ "***" \ "{5}" \ "***" \ "جمعا {6} بار با مجموع {7} قطعه" \ "***" \ "***" \ "{8}" \ "ربات هوشمند سامانه رصدیار" \ "".format(vet_farm.vet.user.fullname, poultry_hatching.poultry.unit_name, bars_details_rsi, len(response.json()), to_locale_str(int(rsi_quantity)), bars_details, len(kill_house_request), to_locale_str(int(accepted_real_quantity)), new_message, vet_farm.vet.user.mobile, poultry_hatching.poultry.breeding_unique_id, poultry_hatching.licence_number, new_message1) user = SystemUserProfile.objects.filter(trash=False, mobile=request.GET['mobile']).last() new_ticket = TicketSupport( user=user, title="گزارش کشتار جوجه ریزی", status='open', read_only=True, type_ticket='single', parent=None, last_message='Admin', ) new_ticket.save() new_ticket.to_user.add(user) msg = MessageSupport( ticket=new_ticket, message=message, created_by=user, sender='Admin' ) msg.save() return Response('ok', status=status.HTTP_200_OK) def delete_kill_req_cron(): current_time = datetime.datetime.now() kill_requests = KillRequest.objects.filter(Q(market_final_accept=True, market_code_status=True, input_market_code__isnull=True) | Q(market_final_accept=False), trash=False, market=True, market_state='pending', market_expire_date_time__lt=current_time ).select_related('poultry_request') for kill_request in kill_requests: kill_request.trash = True kill_request.market_state_message = { "fullname": "سیستمی", "mobile": "سیستمی", "date": str(datetime.datetime.now()) } kill_request.market_state = 'deleted' kill_request.save() market_poultry_request_remain_quantity(kill_request.poultry_request) def delete_kill_req_manual(request): current_time = datetime.datetime.now() kill_requests = KillRequest.objects.filter(Q(market_final_accept=True, market_code_status=True, input_market_code__isnull=True) | Q(market_final_accept=False), trash=False, market=True, market_state='pending', market_expire_date_time__lt=current_time ).select_related('poultry_request') for kill_request in kill_requests: kill_request.trash = True kill_request.market_state_message = { "fullname": "سیستمی", "mobile": "سیستمی", "date": str(datetime.datetime.now()) } kill_request.market_state = 'deleted' kill_request.save() market_poultry_request_remain_quantity(kill_request.poultry_request) return HttpResponse('ok') def delete_steward_allocation_cron(): current_time = datetime.datetime.now().date() # allow=AllowRegisterCodeForStewardAllocation.objects.filter(trash=False,active=True).first() # if allow: steward_allocation = StewardAllocation.objects.filter(trash=False, date__date=current_time, receiver_state='pending', active_expire_date_time=True, logged_registration_code__isnull=True, kill_house__isnull=False, return_trash=False,to_cold_house__isnull=True).order_by('id') for allocation in steward_allocation: product = allocation.product seller_type = allocation.seller_type to_cold_house = allocation.to_cold_house other_cold_house = allocation.other_cold_house if allocation.other_cold_house else None allocation.trash = True allocation.save() if seller_type == 'KillHouse': kill_house_allocations_product_warehousing(product) if to_cold_house and to_cold_house.kill_house == product.kill_house: kill_house_cold_house_allocations(to_cold_house) elif seller_type == 'ColdHouse': cold_house_warehousing(to_cold_house) if other_cold_house: cold_house_warehousing(other_cold_house) else: guild_steward_allocations_product_warehousing(product) def archive_kill_house_remain_limitation_weight_cron(): production_date = (datetime.datetime.now() - datetime.timedelta(days=3)).date() archive_date = (datetime.datetime.now() - datetime.timedelta(days=3)) kill_houses = KillHouse.objects.filter(trash=False, out_province=False) for kill_house in kill_houses: kill_house_requests = KillHouseRequest.objects.filter(input_warehouse=kill_house, province_request__poultry_request__free_sale_in_province=False, kill_request__recive_date__date=production_date, ware_house_confirmation=True, trash=False, calculate_status=True, warehouse=True) kill_house_allocations = StewardAllocation.objects.filter( kill_house=kill_house, trash=False, calculate_status=True, warehouse=True, system_registration_code=True, receiver_state__in=('pending', 'accepted'), production_date__date=production_date, quota='governmental') kill_house_free_sale_bars = KillHouseFreeSaleBarInformation.objects.filter(kill_house=kill_house, quota='governmental', production_date__date=production_date, trash=False, calculate_status=True, warehouse=True) segmentations = PosSegmentation.objects.filter(kill_house=kill_house, production_date__date=production_date, trash=False, warehouse=True, quota='governmental') kill_house_requests_weight = kill_house_requests.aggregate(total=Sum('ware_house_accepted_real_weight'))[ 'total'] or 0 kill_house_allocations_weight = \ kill_house_allocations.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0 kill_house_free_sale_bars_weight = kill_house_free_sale_bars.aggregate(total=Sum('real_weight_of_carcasses'))[ 'total'] or 0 segmentation_weight = \ segmentations.aggregate(total=Sum('weight'))[ 'total'] or 0 archives = WarehouseArchive.objects.filter(kill_house=kill_house, date__date=production_date, quota='governmental', trash=False) archives_governmental_weight = \ archives.aggregate(total=Sum('weight'))[ 'total'] or 0 total_input = kill_house_requests_weight total_output = kill_house_allocations_weight + kill_house_free_sale_bars_weight + segmentation_weight + archives_governmental_weight total_remain = total_input - total_output if total_remain > 0: if kill_house.ware_house_remaining_weight_archive_percent > 0: percent_limitation_weight = total_input * (kill_house.ware_house_remaining_weight_archive_percent / 100) if percent_limitation_weight >= total_remain: archive = WarehouseArchive( kill_house=kill_house, date=archive_date, quota='governmental', weight=total_remain, registerer='سیستم', registerer_mobile='سیستم', registerer_role='سیستم', description='مانده کمتر از استاندارد تعیین شده', ) archive.save() kill_house_archive_warehousing(archive.kill_house) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def hatching_unknown(request): age_range = ChickenAgeRange.objects.filter(active=True, trash=False).first() if age_range: hatchings = PoultryHatching.objects.filter( state='pending', archive=False, allow_hatching='pending', trash=False, unknown=False, chicken_age__gt=age_range.maximum ) poultries = Poultry.objects.filter(id__in=hatchings.values_list('poultry__id', flat=True)).update( order_limit=True) hatchings.update(unknown=True) return Response("done!") def hatching_unknown_cron(): age_range = ChickenAgeRange.objects.filter(active=True, trash=False).first() if age_range: hatchings = PoultryHatching.objects.filter( state='pending', archive=False, allow_hatching='pending', trash=False, unknown=False, chicken_age__gt=age_range.maximum ) poultries = Poultry.objects.filter(id__in=hatchings.values_list('poultry__id', flat=True)).update( order_limit=True) hatchings.update(unknown=True) @api_view(["GET"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def management_kill_house_dashboard(request): date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() poultry_hatching = PoultryHatching.objects.filter(Q(date__date__gte=date1, date__date__lte=date2) | Q(date__date__lte=date1, archive_date__isnull=True) | Q(date__date__lte=date1, archive_date__gte=date1, archive_date__isnull=False), trash=False).select_related('poultry', 'poultry__user__city') kill_house_request = KillHouseRequest.objects.filter( trash=False, kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2, temporary_trash=False, temporary_deleted=False ).select_related('killhouse_user') aggregate_kill_house_request = kill_house_request.aggregate( total_id=Count('id'), total_accepted_real_quantity=Sum('accepted_real_quantity'), total_accepted_real_weight=Sum('accepted_real_weight'), total_quantity_has_quarantine=Sum('accepted_real_quantity', filter=Q(quarantine_quantity__gt=0)), total_count_has_quarantine=Count('id', filter=Q(quarantine_quantity__gt=0)), total_quarantine_quantity=Sum('quarantine_quantity', filter=Q(quarantine_quantity__gt=0)), total_id_hasnt_code=Count('id', filter=Q(clearance_code__isnull=True)), total_quantity_hasnt_code=Sum('accepted_real_quantity', filter=Q(clearance_code__isnull=True)), total_weight_hasnt_code=Sum('accepted_real_weight', filter=Q(clearance_code__isnull=True)), total_id_hasnt_warehouse=Count('id', filter=Q(ware_house_confirmation=False)), total_quantity_hasnt_warehouse=Sum('accepted_real_quantity', filter=Q(ware_house_confirmation=False)), total_weight_hasnt_warehouse=Sum('accepted_real_weight', filter=Q(ware_house_confirmation=False)), total_id_hasnt_assignment_state_archive=Count('id', filter=Q(assignment_state_archive='pending')), total_quantity_hasnt_assignment_state_archive=Sum('accepted_real_quantity', filter=Q(assignment_state_archive='pending')), total_weight_hasnt_assignment_state_archive=Sum('accepted_real_weight', filter=Q(assignment_state_archive='pending')), total_id_hasnt_killing_age=Count('id', filter=Q(province_request__poultry_request__killing_age__gte=60)), total_quantity_hasnt_killing_age=Sum('accepted_real_quantity', filter=Q(province_request__poultry_request__killing_age__gte=60)), total_weight_hasnt_killing_age=Sum('accepted_real_weight', filter=Q(province_request__poultry_request__killing_age__gte=60)), ) kill_house_req_stats = kill_house_request.values('killhouse_user__name').annotate( total_quantity=Sum('accepted_real_quantity'), transaction_count=Count('id') ).order_by('-total_quantity') top_kill_house_req = kill_house_req_stats.first() if kill_house_req_stats else None kill_house_name_req = "-" total_quantity_top_inner = 0 if top_kill_house_req: kill_house_name_req = top_kill_house_req['killhouse_user__name'] total_quantity_top_inner = top_kill_house_req['total_quantity'] poultry_req_stats = kill_house_request.values( 'province_request__poultry_request__hatching__poultry__unit_name', 'province_request__poultry_request__hatching__poultry__user__city__name') \ .annotate(total_quantity=Sum('accepted_real_quantity'), ).order_by('-total_quantity') top_poultry_req_stats = poultry_req_stats.first() if poultry_req_stats else None top_poultry_req_stats_total_quantity = 0 poultry_req_name_req = "-" poultry_city_req_name_req = "-" if top_poultry_req_stats: poultry_req_name_req = top_poultry_req_stats['province_request__poultry_request__hatching__poultry__unit_name'] poultry_city_req_name_req = top_poultry_req_stats[ 'province_request__poultry_request__hatching__poultry__user__city__name'] top_poultry_req_stats_total_quantity = to_locale_str(top_poultry_req_stats['total_quantity'] or 0) aggregate_hatching = poultry_hatching.aggregate( total_quantity=Sum('quantity'), total_losses_vet=Sum('losses'), total_losses_union=Sum('direct_losses'), total_losses=Sum('total_losses'), killed_quantity=Sum('killed_quantity'), total_killed_weight=Sum('total_killed_weight'), left_over=Sum('left_over'), total_killing_ave_age=Avg('poultry__killing_ave_age') ) top_total_killed_weight = poultry_hatching.values('id').annotate( total_killed_weight=Sum('total_killed_weight'), ).order_by('-total_killed_weight') top_total_killed_weight_first = top_total_killed_weight.first() if top_total_killed_weight else None free_bars = KillHouseFreeBarInformation.objects.filter(date__date__gte=date1, date__date__lte=date2, trash=False, buy_type='live').select_related('kill_house') kill_house_stats = free_bars.values('kill_house__name').annotate( total_quantity=Sum('quantity'), total_live_weight=Sum('live_weight'), transaction_count=Count('id') ).order_by('-total_quantity') top_kill_house = kill_house_stats.first() if kill_house_stats else None kill_house_name = "-" total_quantity_top_out = 0 transaction_count = "-" if top_kill_house: kill_house_name = top_kill_house['kill_house__name'] transaction_count = to_locale_str(top_kill_house['transaction_count'] or 0) total_quantity_top_out = to_locale_str(top_kill_house['total_quantity'] or 0) # out_poultry_req_stats = free_bars.values('poultry_name', 'province', 'city').annotate( total_quantity=Sum('quantity'), ).order_by('-total_quantity') top_out_poultry_req_stats = out_poultry_req_stats.first() if out_poultry_req_stats else None out_top_poultry_req_stats_total_quantity = 0 out_poultry_req_name_req = "-" out_poultry_city_req_name_req = "-" out_poultry_province_req_name_req = "-" if top_out_poultry_req_stats: out_poultry_req_name_req = top_out_poultry_req_stats['poultry_name'] out_poultry_city_req_name_req = top_out_poultry_req_stats['city'] out_poultry_province_req_name_req = top_out_poultry_req_stats['province'] out_top_poultry_req_stats_total_quantity = to_locale_str(top_out_poultry_req_stats['total_quantity'] or 0) # aggregate_free_bars = free_bars.aggregate( id=Count('id'), quantity=Sum('quantity'), live_weight=Sum('live_weight'), ) max_kill_day = free_bars.values('date__date').annotate( daily_quantity=Sum('quantity') ).order_by('-daily_quantity').first() persian_date = '-' daily_quantity = '-' if max_kill_day: persian_date = shamsi_date(max_kill_day['date__date']) daily_quantity = to_locale_str(max_kill_day['daily_quantity']) max_kill_day_req = kill_house_request.values('kill_request__recive_date__date').annotate( daily_quantity=Sum('accepted_real_quantity') ).order_by('-daily_quantity').first() persian_date_req = '-' daily_quantity_req = '-' if max_kill_day_req: persian_date_req = shamsi_date(max_kill_day_req['kill_request__recive_date__date']) daily_quantity_req = to_locale_str(max_kill_day_req['daily_quantity']) kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('name') kill_house_data = [] duc_kill_house_data = [] for kh in kill_houses: new_steward_allocations = StewardAllocation.objects.filter( trash=False, date__date__gte=date1, date__date__lte=date2, kill_house=kh ) in_province_data = kill_house_request.filter( killhouse_user=kh ).aggregate( load_count=Count('id'), quantity=Sum('accepted_real_quantity'), weight=Sum('accepted_real_weight') ) out_province_data = free_bars.filter( kill_house=kh ).aggregate( load_count=Count('id'), quantity=Sum('quantity'), live_weight=Sum('live_weight'), ) in_qty = in_province_data.get('quantity', 0) or 0 in_weight = in_province_data.get('weight', 0) or 0 out_qty = out_province_data.get('quantity', 0) or 0 out_weight = out_province_data.get('live_weight', 0) or 0 total_quantity = in_qty + out_qty total_weight = in_weight + out_weight wight_of_steward = new_steward_allocations.filter(to_steward__isnull=False).aggregate( total_quantity=Sum('real_weight_of_carcasses') ) len_of_steward = new_steward_allocations.filter(to_steward__isnull=False).count() len_of_guild = new_steward_allocations.filter(to_guilds__isnull=False).count() wight_of_guild = new_steward_allocations.filter(to_guilds__isnull=False).aggregate( total_quantity=Sum('real_weight_of_carcasses') ) in_loads = in_province_data.get('load_count', 0) or 0 out_loads = out_province_data.get('load_count', 0) or 0 total_loads = in_loads + out_loads # if in_qty > 0 or out_qty > 0 or in_loads > 0 or out_loads > 0: kill_house_data.append({ 'name': kh.name, 'load_count': to_locale_str(total_loads or 0), 'in_province_quantity': to_locale_str(in_qty or 0), 'in_province_wight': to_locale_str(in_weight or 0), 'out_province_quantity': to_locale_str(out_qty or 0), 'out_province_weight': to_locale_str(out_weight or 0), 'total_quantity': to_locale_str(total_quantity or 0), 'total_weight': to_locale_str(total_weight or 0), 'wight_of_steward': to_locale_str(wight_of_steward['total_quantity'] or 0), 'wight_of_guild': to_locale_str(wight_of_guild['total_quantity'] or 0), 'len_of_steward': to_locale_str(len_of_steward), 'len_of_guild': to_locale_str(len_of_guild), }) free_bars = KillHouseFreeSaleBarInformation.objects.filter( trash=False, date__date__gte=date1, date__date__lte=date2, kill_house__in=kill_houses ).values('kill_house_id', 'kill_house__name').annotate( total_quantity=Sum('weight_of_carcasses') ).order_by('-total_quantity') bar_assigment_pending_count1 = kill_house_request.filter(assignment_state_archive='True') \ .exclude(bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count() steward_allocations = StewardAllocation.objects.filter( trash=False, date__date__gte=date1, date__date__lte=date2, kill_house__in=kill_houses ).values('kill_house_id').annotate( total_quantity=Sum('real_weight_of_carcasses') ) in_province_data = kill_house_request.filter( killhouse_user__in=kill_houses ).values('killhouse_user_id').annotate( total_quantity=Sum('accepted_real_weight') ) in_warehouse_data = kill_house_request.filter( killhouse_user__in=kill_houses, ware_house_confirmation=True ).values('killhouse_user_id').annotate( total_quantity=Sum('ware_house_accepted_real_weight') ) products = RolesProducts.objects.filter( trash=False, kill_house__in=kill_houses ).values('kill_house_id', 'total_remain_weight') steward_dict = {item['kill_house_id']: item['total_quantity'] for item in steward_allocations} free_bar_dict = {item['kill_house_id']: item['total_quantity'] for item in free_bars} in_province_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_province_data} in_warehouse_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_warehouse_data} product_dict = {item['kill_house_id']: item['total_remain_weight'] for item in products} management_kill_house_data = [] for kh in kill_houses: kh_id = kh.id steward_qty = steward_dict.get(kh_id, 0) or 0 free_bar_qty = free_bar_dict.get(kh_id, 0) or 0 in_province_qty = in_province_dict.get(kh_id, 0) or 0 in_warehouse_qty = in_warehouse_dict.get(kh_id, 0) or 0 product_weight = product_dict.get(kh_id, 0) or 0 # if any([in_province_qty, in_warehouse_qty, steward_qty, free_bar_qty]): total = free_bar_qty + steward_qty percent = round(total * 100 / in_province_qty, 1) if in_province_qty else 0 management_kill_house_data.append({ 'name': kh.name, 'in_province_quantity': to_locale_str(in_province_qty), 'in_ware_house_quantity': to_locale_str(in_warehouse_qty), 'steward_allocation_quantity': to_locale_str(steward_qty), 'kill_house_free_bar_quantity': to_locale_str(free_bar_qty), 'all_quantity': to_locale_str(total), 'product': to_locale_str(product_weight), 'percent': percent }) n_steward_allocations_n = StewardAllocation.objects.filter( trash=False, date__date__gte=date1, date__date__lte=date2, kill_house__in=kill_houses ) n_steward_allocations = n_steward_allocations_n.aggregate( total_quantity=Sum('real_weight_of_carcasses') ) n_steward_allocations_to_steward = n_steward_allocations_n.filter(to_steward__isnull=False) aggregate_n_steward_allocations_to_steward = n_steward_allocations_to_steward.aggregate( total_quantity=Sum('real_weight_of_carcasses') ) n_steward_allocations_to_guild = n_steward_allocations_n.filter(to_guilds__isnull=False) aggregate_n_steward_allocations_to_guild = n_steward_allocations_to_guild.aggregate( total_quantity=Sum('real_weight_of_carcasses') ) steward_and_guild = { 'len_of_steward': n_steward_allocations_to_steward.count(), 'wight_of_steward': aggregate_n_steward_allocations_to_steward['total_quantity'] or 0, 'len_of_guild': n_steward_allocations_to_guild.count(), 'wight_of_guild': aggregate_n_steward_allocations_to_guild['total_quantity'] or 0, 'total_weight': n_steward_allocations['total_quantity'] or 0, } n_free_bars = KillHouseFreeSaleBarInformation.objects.filter( trash=False, date__date__gte=date1, date__date__lte=date2, kill_house__in=kill_houses ).aggregate( total_quantity=Sum('weight_of_carcasses') ) n_in_province_data = kill_house_request.filter( killhouse_user__in=kill_houses ).aggregate( total_quantity=Sum('accepted_real_weight') ) n_in_warehouse_data = kill_house_request.filter( killhouse_user__in=kill_houses, ware_house_confirmation=True ).aggregate( total_quantity=Sum('ware_house_accepted_real_weight') ) n_products = RolesProducts.objects.filter( trash=False, kill_house__in=kill_houses ).aggregate( total_quantity=Sum('total_remain_weight') ) all_management_kill_house_data = { 'in_province': n_in_province_data['total_quantity'] or 0, 'in_warehouse': n_in_warehouse_data['total_quantity'] or 0, 'steward_allocations': n_steward_allocations['total_quantity'] or 0, 'free_bars': n_free_bars['total_quantity'] or 0, 'total': (n_free_bars['total_quantity'] or 0) + (n_steward_allocations['total_quantity'] or 0), 'products': n_products['total_quantity'] or 0, } for kh in kill_houses: kill_house_request1 = kill_house_request.filter( killhouse_user=kh ) bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True') bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count() bar_document_status_accepted = bar_assigment_true_count.filter( bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count() bar_document_status_rejected = bar_assigment_true_count.exclude( bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count() # if bar_assigment_true_count.count() > 0 or bar_assigment_pending_count > 0: duc_kill_house_data.append({ 'name': kh.name, 'kill_house_request1_count': kill_house_request1.count(), "bar_assigment_true_count": bar_assigment_true_count.count(), "bar_assigment_pending_count": bar_assigment_pending_count, "bar_document_status_accepted": bar_document_status_accepted, "percent_bar_document_status_accepted": int((bar_document_status_accepted / bar_assigment_true_count.count()) * 100) if bar_assigment_true_count.count() > 0 else 0, "bar_document_status_rejected": bar_document_status_rejected, "percent_bar_document_status_rejected": int((bar_document_status_rejected / bar_assigment_true_count.count()) * 100) if bar_assigment_true_count.count() > 0 else 0, }) different_bar = (aggregate_kill_house_request['total_quantity_has_quarantine'] or 0) \ - (aggregate_kill_house_request['total_quarantine_quantity'] or 0) different_bar_percent = int(different_bar / (aggregate_kill_house_request['total_quarantine_quantity'] or 0) * 100) \ if (aggregate_kill_house_request['total_quarantine_quantity'] or 0) > 0 else 0 result = { 'all_management_kill_house_data': all_management_kill_house_data, 'management_kill_house_data': management_kill_house_data, "poultry_hatching_total_killed_weight": aggregate_hatching['total_killed_weight'] or 0, "total_weight_hasnt_warehouse": aggregate_kill_house_request['total_weight_hasnt_warehouse'] or 0, 'kill_houses_data': kill_house_data, # "kill_house_request_count": to_locale_str(aggregate_kill_house_request['total_id'] or 0), "kill_house_request_quantity": to_locale_str(aggregate_kill_house_request['total_accepted_real_quantity'] or 0), "kill_house_request_weight": to_locale_str(aggregate_kill_house_request['total_accepted_real_weight'] or 0), "kill_house_request_average_weight": round( aggregate_kill_house_request['total_accepted_real_weight'] / aggregate_kill_house_request[ 'total_accepted_real_quantity'], 1) if (aggregate_kill_house_request['total_accepted_real_quantity'] or 0) > 0 else 0, "free_bars_count": to_locale_str(aggregate_free_bars['id'] or 0), "free_bars_quantity": to_locale_str(aggregate_free_bars['quantity'] or 0), "free_bars_live_weight": to_locale_str(aggregate_free_bars['live_weight'] or 0), "kill_house_name": kill_house_name, "transaction_count": transaction_count, "persian_date": persian_date, "daily_quantity": daily_quantity, "persian_date_req": persian_date_req, "daily_quantity_req": daily_quantity_req, 'kill_house_name_req': kill_house_name_req, 'poultry_req_name_req': poultry_req_name_req, 'top_poultry_req_stats_total_quantity': top_poultry_req_stats_total_quantity, 'poultry_city_req_name_req': poultry_city_req_name_req, 'out_poultry_req_name_req': out_poultry_req_name_req, 'out_poultry_city_req_name_req': out_poultry_city_req_name_req, 'out_poultry_province_req_name_req': out_poultry_province_req_name_req, 'out_top_poultry_req_stats_total_quantity': out_top_poultry_req_stats_total_quantity, 'duc_kill_house_data': duc_kill_house_data, 'avg_losses': to_locale_str(int((aggregate_hatching['total_losses'] or 0) / poultry_hatching.count())), 'avg_total_killed_weight': round( (aggregate_hatching['total_killed_weight'] or 0) / (aggregate_hatching['killed_quantity'] or 0), 1), 'total_killing_ave_age': int(aggregate_hatching['total_killing_ave_age'] or 0), 'top_total_killed_weight': to_locale_str(top_total_killed_weight_first['total_killed_weight'] or 0), 'total_quantity_top_inner': to_locale_str(total_quantity_top_inner), 'total_quantity_top_out': total_quantity_top_out, 'bar_assigment_pending_count1': to_locale_str(bar_assigment_pending_count1 or 0), 'base_url': base_url_for_sms_report, "total_quarantine_quantity": to_locale_str(aggregate_kill_house_request['total_quarantine_quantity'] or 0), "total_count_has_quarantine": to_locale_str(aggregate_kill_house_request['total_count_has_quarantine'] or 0), "total_quantity_has_quarantine": to_locale_str( aggregate_kill_house_request['total_quantity_has_quarantine'] or 0), "different": to_locale_str(different_bar or 0), "total_weight_hasnt_code": to_locale_str(aggregate_kill_house_request['total_weight_hasnt_code'] or 0), "total_quantity_hasnt_code": to_locale_str(aggregate_kill_house_request['total_quantity_hasnt_code'] or 0), "total_id_hasnt_code": to_locale_str(aggregate_kill_house_request['total_id_hasnt_code'] or 0), "total_quantity_hasnt_warehouse": to_locale_str( aggregate_kill_house_request['total_quantity_hasnt_warehouse'] or 0), "total_id_hasnt_warehouse": to_locale_str(aggregate_kill_house_request['total_id_hasnt_warehouse'] or 0), "total_weight_hasnt_assignment_state_archive": to_locale_str( aggregate_kill_house_request['total_weight_hasnt_assignment_state_archive'] or 0), "total_quantity_hasnt_assignment_state_archive": to_locale_str( aggregate_kill_house_request['total_quantity_hasnt_assignment_state_archive'] or 0), "total_id_hasnt_assignment_state_archive": to_locale_str( aggregate_kill_house_request['total_id_hasnt_assignment_state_archive'] or 0), "total_weight_hasnt_killing_age": to_locale_str( aggregate_kill_house_request['total_weight_hasnt_killing_age'] or 0), "total_quantity_hasnt_killing_age": to_locale_str( aggregate_kill_house_request['total_quantity_hasnt_killing_age'] or 0), "total_id_hasnt_killing_age": to_locale_str(aggregate_kill_house_request['total_id_hasnt_killing_age'] or 0), 'different_bar_percent': different_bar_percent, "steward_and_guild": steward_and_guild } return Response(result) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def periodic_performance_report_dashboard(request): date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() poultry_hatching = PoultryHatching.objects.filter(Q(date__date__gte=date1, date__date__lte=date2) | Q(date__date__lte=date1, archive_date__isnull=True) | Q(date__date__lte=date1, archive_date__gte=date1, archive_date__isnull=False), trash=False).select_related('poultry', 'poultry__user__city') kill_house_request = KillHouseRequest.objects.filter( trash=False, kill_request__recive_date__date__gte=date1, kill_request__recive_date__date__lte=date2, temporary_trash=False, temporary_deleted=False ).select_related('killhouse_user') aggregate_kill_house_request = kill_house_request.aggregate( total_id=Count('id'), total_accepted_real_quantity=Sum('accepted_real_quantity'), total_accepted_real_weight=Sum('accepted_real_weight'), total_quantity_has_quarantine=Sum('accepted_real_quantity', filter=Q(quarantine_quantity__gt=0)), total_count_has_quarantine=Count('id', filter=Q(quarantine_quantity__gt=0)), total_quarantine_quantity=Sum('quarantine_quantity', filter=Q(quarantine_quantity__gt=0)), total_id_hasnt_code=Count('id', filter=Q(clearance_code__isnull=True)), total_quantity_hasnt_code=Sum('accepted_real_quantity', filter=Q(clearance_code__isnull=True)), total_weight_hasnt_code=Sum('accepted_real_weight', filter=Q(clearance_code__isnull=True)), total_id_hasnt_warehouse=Count('id', filter=Q(ware_house_confirmation=False)), total_quantity_hasnt_warehouse=Sum('accepted_real_quantity', filter=Q(ware_house_confirmation=False)), total_weight_hasnt_warehouse=Sum('accepted_real_weight', filter=Q(ware_house_confirmation=False)), total_id_hasnt_assignment_state_archive=Count('id', filter=Q(assignment_state_archive='pending')), total_quantity_hasnt_assignment_state_archive=Sum('accepted_real_quantity', filter=Q(assignment_state_archive='pending')), total_weight_hasnt_assignment_state_archive=Sum('accepted_real_weight', filter=Q(assignment_state_archive='pending')), total_id_hasnt_killing_age=Count('id', filter=Q(province_request__poultry_request__killing_age__gte=60)), total_quantity_hasnt_killing_age=Sum('accepted_real_quantity', filter=Q(province_request__poultry_request__killing_age__gte=60)), total_weight_hasnt_killing_age=Sum('accepted_real_weight', filter=Q(province_request__poultry_request__killing_age__gte=60)), ) kill_house_req_stats = kill_house_request.values('killhouse_user__name').annotate( total_quantity=Sum('accepted_real_quantity'), transaction_count=Count('id') ).order_by('-total_quantity') top_kill_house_req = kill_house_req_stats.first() if kill_house_req_stats else None kill_house_name_req = "-" total_quantity_top_inner = 0 if top_kill_house_req: kill_house_name_req = top_kill_house_req['killhouse_user__name'] total_quantity_top_inner = top_kill_house_req['total_quantity'] poultry_req_stats = kill_house_request.values( 'province_request__poultry_request__hatching__poultry__unit_name', 'province_request__poultry_request__hatching__poultry__user__city__name') \ .annotate(total_quantity=Sum('accepted_real_quantity'), ).order_by('-total_quantity') top_poultry_req_stats = poultry_req_stats.first() if poultry_req_stats else None top_poultry_req_stats_total_quantity = 0 poultry_req_name_req = "-" poultry_city_req_name_req = "-" if top_poultry_req_stats: poultry_req_name_req = top_poultry_req_stats['province_request__poultry_request__hatching__poultry__unit_name'] poultry_city_req_name_req = top_poultry_req_stats[ 'province_request__poultry_request__hatching__poultry__user__city__name'] top_poultry_req_stats_total_quantity = to_locale_str(top_poultry_req_stats['total_quantity'] or 0) poultry_hatching_gt_60 = poultry_hatching.filter(chicken_age__gt=60) poultry_hatching_has_killed = PoultryRequest.objects.filter(state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted'), trash=False, out=False, hatching__in=poultry_hatching) if poultry_hatching_has_killed: max_age_poultry = poultry_hatching_has_killed.order_by('-killing_age').first() min_age_poultry = poultry_hatching_has_killed.order_by('killing_age').first() max_and_min_dict = {"max_age_poultry": max_age_poultry.killing_age or 0, "max_age_poultry_name": max_age_poultry.hatching.poultry.unit_name or '-', "max_age_poultry_city": max_age_poultry.hatching.poultry.user.city.name if max_age_poultry.hatching.poultry.user.city else '-', "max_age_poultry_quantity": max_age_poultry.hatching.quantity or 0, "max_age_poultry_killed_quantity": max_age_poultry.hatching.killed_quantity or 0, "max_age_poultry_left_over": max_age_poultry.hatching.left_over or 0, "min_age_poultry": min_age_poultry.killing_age or 0, "min_age_poultry_name": min_age_poultry.hatching.poultry.unit_name or '-', "min_age_poultry_city": min_age_poultry.hatching.poultry.user.city.name if min_age_poultry.hatching.poultry.user.city else '-', "min_age_poultry_quantity": min_age_poultry.hatching.quantity or 0, "min_age_poultry_killed_quantity": min_age_poultry.hatching.killed_quantity or 0, "min_age_poultry_left_over": min_age_poultry.hatching.left_over or 0} else: max_and_min_dict = {"max_age_poultry": 0, "max_age_poultry_name": '-', "max_age_poultry_city": '-', "max_age_poultry_quantity": 0, "max_age_poultry_killed_quantity": 0, "max_age_poultry_left_over": 0, "min_age_poultry": 0, "min_age_poultry_name": '-', "min_age_poultry_city": '-', "min_age_poultry_quantity": 0, "min_age_poultry_killed_quantity": 0, "min_age_poultry_left_over": 0} aggregate_poultry_hatching_gt_60 = poultry_hatching_gt_60.aggregate( total_quantity=Sum('quantity'), left_over=Sum('left_over'), ) aggregate_hatching = poultry_hatching.aggregate( total_quantity=Sum('quantity'), total_losses_vet=Sum('losses'), total_losses_union=Sum('direct_losses'), total_losses=Sum('total_losses'), killed_quantity=Sum('killed_quantity'), total_killed_weight=Sum('total_killed_weight'), left_over=Sum('left_over'), total_killing_ave_age=Avg('poultry__killing_ave_age') ) top_total_killed_weight = poultry_hatching.values('id').annotate( total_killed_weight=Sum('total_killed_weight'), ).order_by('-total_killed_weight') top_total_killed_weight_first = top_total_killed_weight.first() if top_total_killed_weight else None free_bars = KillHouseFreeBarInformation.objects.filter(date__date__gte=date1, date__date__lte=date2, trash=False, buy_type='live').select_related('kill_house') kill_house_stats = free_bars.values('kill_house__name').annotate( total_quantity=Sum('quantity'), total_live_weight=Sum('live_weight'), transaction_count=Count('id') ).order_by('-total_quantity') top_kill_house = kill_house_stats.first() if kill_house_stats else None kill_house_name = "-" total_quantity_top_out = 0 transaction_count = "-" if top_kill_house: kill_house_name = top_kill_house['kill_house__name'] transaction_count = to_locale_str(top_kill_house['transaction_count'] or 0) total_quantity_top_out = to_locale_str(top_kill_house['total_quantity'] or 0) # out_poultry_req_stats = free_bars.values('poultry_name', 'province', 'city').annotate( total_quantity=Sum('quantity'), ).order_by('-total_quantity') top_out_poultry_req_stats = out_poultry_req_stats.first() if out_poultry_req_stats else None out_top_poultry_req_stats_total_quantity = 0 out_poultry_req_name_req = "-" out_poultry_city_req_name_req = "-" out_poultry_province_req_name_req = "-" if top_out_poultry_req_stats: out_poultry_req_name_req = top_out_poultry_req_stats['poultry_name'] out_poultry_city_req_name_req = top_out_poultry_req_stats['city'] out_poultry_province_req_name_req = top_out_poultry_req_stats['province'] out_top_poultry_req_stats_total_quantity = to_locale_str(top_out_poultry_req_stats['total_quantity'] or 0) # aggregate_free_bars = free_bars.aggregate( id=Count('id'), quantity=Sum('quantity'), live_weight=Sum('live_weight'), ) max_kill_day = free_bars.values('date__date').annotate( daily_quantity=Sum('quantity') ).order_by('-daily_quantity').first() persian_date = '-' daily_quantity = '-' if max_kill_day: persian_date = shamsi_date(max_kill_day['date__date']) daily_quantity = to_locale_str(max_kill_day['daily_quantity']) max_kill_day_req = kill_house_request.values('kill_request__recive_date__date').annotate( daily_quantity=Sum('accepted_real_quantity') ).order_by('-daily_quantity').first() persian_date_req = '-' daily_quantity_req = '-' if max_kill_day_req: persian_date_req = shamsi_date(max_kill_day_req['kill_request__recive_date__date']) daily_quantity_req = to_locale_str(max_kill_day_req['daily_quantity']) kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('-name') kill_house_data = [] duc_kill_house_data = [] for kh in kill_houses: in_province_data = kill_house_request.filter( killhouse_user=kh ).aggregate( load_count=Count('id'), quantity=Sum('accepted_real_quantity'), weight=Sum('accepted_real_weight') ) out_province_data = free_bars.filter( kill_house=kh ).aggregate( load_count=Count('id'), quantity=Sum('quantity'), live_weight=Sum('live_weight'), ) in_qty = in_province_data.get('quantity', 0) or 0 in_weight = in_province_data.get('weight', 0) or 0 out_qty = out_province_data.get('quantity', 0) or 0 out_weight = out_province_data.get('live_weight', 0) or 0 total_quantity = in_qty + out_qty total_weight = in_weight + out_weight in_loads = in_province_data.get('load_count', 0) or 0 out_loads = out_province_data.get('load_count', 0) or 0 total_loads = in_loads + out_loads if in_qty > 0 or out_qty > 0 or in_loads > 0 or out_loads > 0: kill_house_data.append({ 'name': kh.name, 'load_count': to_locale_str(total_loads or 0), 'load_count_in_province': to_locale_str(in_loads or 0), 'load_count_out_province': to_locale_str(out_loads or 0), 'in_province_quantity': to_locale_str(in_qty or 0), 'in_province_wight': to_locale_str(in_weight or 0), 'out_province_quantity': to_locale_str(out_qty or 0), 'out_province_weight': to_locale_str(out_weight or 0), 'total_quantity': to_locale_str(total_quantity or 0), 'total_weight': to_locale_str(total_weight or 0), }) bar_assigment_pending_count1 = kill_house_request.filter(assignment_state_archive='True') \ .exclude(bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count() tomorrow_of_date1 = date1 + datetime.timedelta(days=1) tomorrow_of_date2 = date2 + datetime.timedelta(days=1) steward_allocations = StewardAllocation.objects.filter( trash=False, date__date__gte=tomorrow_of_date1, date__date__lte=tomorrow_of_date2, kill_house__in=kill_houses ).values('kill_house_id').annotate( total_quantity=Sum('real_weight_of_carcasses') ) free_bars = KillHouseFreeSaleBarInformation.objects.filter( trash=False, date__date__gte=tomorrow_of_date1, date__date__lte=tomorrow_of_date2, kill_house__in=kill_houses ).values('kill_house_id').annotate( total_quantity=Sum('weight_of_carcasses') ) in_province_data = kill_house_request.filter( killhouse_user__in=kill_houses ).values('killhouse_user_id').annotate( total_quantity=Sum('accepted_real_weight') ) in_warehouse_data = kill_house_request.filter( killhouse_user__in=kill_houses, ware_house_confirmation=True ).values('killhouse_user_id').annotate( total_quantity=Sum('ware_house_accepted_real_weight') ) products = RolesProducts.objects.filter( trash=False, kill_house__in=kill_houses ).values('kill_house_id', 'total_remain_weight') steward_dict = {item['kill_house_id']: item['total_quantity'] for item in steward_allocations} free_bar_dict = {item['kill_house_id']: item['total_quantity'] for item in free_bars} in_province_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_province_data} in_warehouse_dict = {item['killhouse_user_id']: item['total_quantity'] for item in in_warehouse_data} product_dict = {item['kill_house_id']: item['total_remain_weight'] for item in products} management_kill_house_data = [] management_kill_house_dict = { 'max_percent': '-', 'max_in_province': '-', 'min_in_province': '-', 'max_out_province': '-', 'min_out_province': '-', 'max_product': '-', } # نگه داشتن مقادیر بیشترین/کمترین max_percent_val = -1 max_in_province_val = -1 min_in_province_val = float("inf") max_out_province_val = -1 min_out_province_val = float("inf") max_product_val = -1 for kh in kill_houses: kh_id = kh.id steward_qty = steward_dict.get(kh_id, 0) or 0 free_bar_qty = free_bar_dict.get(kh_id, 0) or 0 in_province_qty = in_province_dict.get(kh_id, 0) or 0 in_warehouse_qty = in_warehouse_dict.get(kh_id, 0) or 0 product_weight = product_dict.get(kh_id, 0) or 0 if any([in_province_qty, in_warehouse_qty, steward_qty, free_bar_qty]): total = free_bar_qty + steward_qty percent = round(total * 100 / in_province_qty, 1) if in_province_qty else 0 # ==== بیشترین‌ها ==== if percent > max_percent_val: max_percent_val = percent management_kill_house_dict['max_percent'] = kh.name if steward_qty > max_in_province_val: max_in_province_val = steward_qty management_kill_house_dict['max_in_province'] = kh.name if free_bar_qty > max_out_province_val: max_out_province_val = free_bar_qty management_kill_house_dict['max_out_province'] = kh.name if product_weight > max_product_val: max_product_val = product_weight management_kill_house_dict['max_product'] = kh.name # ==== کمترین‌ها ==== if steward_qty < min_in_province_val: min_in_province_val = steward_qty management_kill_house_dict['min_in_province'] = kh.name if free_bar_qty < min_out_province_val: min_out_province_val = free_bar_qty management_kill_house_dict['min_out_province'] = kh.name management_kill_house_data.append({ 'name': kh.name, 'in_province_quantity': to_locale_str(in_province_qty), 'in_ware_house_quantity': to_locale_str(in_warehouse_qty), 'steward_allocation_quantity': to_locale_str(steward_qty), 'kill_house_free_bar_quantity': to_locale_str(free_bar_qty), 'all_quantity': to_locale_str(total), 'product': to_locale_str(product_weight), 'percent': percent }) max_and_min_assigment = { "max_duc_name": '-', "max_duc_accepted_name": '-', "max_duc_rejected_name": '-', "min_duc_name": '-', "min_duc_accepted_name": '-', "min_duc_rejected_name": '-', } # نگه داشتن مقادیر بیشترین/کمترین max_request_count = -1 min_request_count = float("inf") max_true_count = -1 min_true_count = float("inf") max_rejected_count = -1 min_rejected_count = float("inf") for kh in kill_houses: kill_house_request1 = kill_house_request.filter( killhouse_user=kh ) bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True') bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count() bar_document_status_accepted = bar_assigment_true_count.filter( bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد') ).count() bar_document_status_rejected = bar_assigment_true_count.exclude( bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد') ).count() if bar_assigment_true_count.count() > 0 or bar_assigment_pending_count > 0: req_count = kill_house_request1.count() true_count = bar_assigment_true_count.count() rejected_count = bar_document_status_rejected # === بیشترین‌ها === if req_count > max_request_count: max_request_count = req_count max_and_min_assigment["max_duc_name"] = kh.name if true_count > max_true_count: max_true_count = true_count max_and_min_assigment["max_duc_accepted_name"] = kh.name if rejected_count > max_rejected_count: max_rejected_count = rejected_count max_and_min_assigment["max_duc_rejected_name"] = kh.name # === کمترین‌ها === if req_count < min_request_count: min_request_count = req_count max_and_min_assigment["min_duc_name"] = kh.name if true_count < min_true_count: min_true_count = true_count max_and_min_assigment["min_duc_accepted_name"] = kh.name if rejected_count < min_rejected_count: min_rejected_count = rejected_count max_and_min_assigment["min_duc_rejected_name"] = kh.name duc_kill_house_data.append({ 'name': kh.name, 'kill_house_request1_count': req_count, "bar_assigment_true_count": true_count, "bar_assigment_pending_count": bar_assigment_pending_count, "bar_document_status_accepted": bar_document_status_accepted, "percent_bar_document_status_accepted": int( (bar_document_status_accepted / true_count) * 100) if true_count > 0 else 0, "bar_document_status_rejected": rejected_count, "percent_bar_document_status_rejected": int( (rejected_count / true_count) * 100) if true_count > 0 else 0, }) different_bar = (aggregate_kill_house_request['total_quantity_has_quarantine'] or 0) \ - (aggregate_kill_house_request['total_quarantine_quantity'] or 0) different_bar_percent = int(different_bar / (aggregate_kill_house_request['total_quarantine_quantity'] or 0) * 100) \ if (aggregate_kill_house_request['total_quarantine_quantity'] or 0) > 0 else 0 result = { # noqa "poultry_count": len(poultry_hatching.values_list('poultry', flat=True).distinct()), "chain_count": len( poultry_hatching.filter(Q(UnionTypeName='زنجیره') | Q(chain_company__isnull=False)).values_list('poultry', flat=True).distinct()), "poultry_hatching_quantity": aggregate_hatching['total_quantity'] or 0, "poultry_hatching_losses_vet": aggregate_hatching['total_losses_vet'] or 0, "poultry_hatching_losses_union": aggregate_hatching['total_losses_union'] or 0, "poultry_hatching_total_losses": aggregate_hatching['total_losses'] or 0, "poultry_hatching_killed_quantity": aggregate_hatching['killed_quantity'] or 0, "poultry_hatching_total_killed_weight": int(aggregate_hatching['total_killed_weight'] or 0), "poultry_hatching_left_over": aggregate_hatching['left_over'] or 0, "poultry_hatching_gt_60": len(poultry_hatching_gt_60.values_list('poultry', flat=True).distinct()), "poultry_hatching_gt_60_quantity": aggregate_poultry_hatching_gt_60['total_quantity'] or 0, "poultry_hatching_gt_60_left_over": aggregate_poultry_hatching_gt_60['left_over'] or 0, **max_and_min_dict, "kill_house_request_count": aggregate_kill_house_request['total_id'] or 0, "kill_house_request_quantity": aggregate_kill_house_request['total_accepted_real_quantity'] or 0, "kill_house_request_weight": int(aggregate_kill_house_request['total_accepted_real_weight'] or 0), "kill_house_request_average_weight": round( aggregate_kill_house_request['total_accepted_real_weight'] / aggregate_kill_house_request[ 'total_accepted_real_quantity'], 1) if (aggregate_kill_house_request['total_accepted_real_quantity'] or 0) > 0 else 0, "free_bars_count": aggregate_free_bars['id'] or 0, "free_bars_quantity": aggregate_free_bars['quantity'] or 0, "free_bars_live_weight": aggregate_free_bars['live_weight'] or 0, "kill_house_name": kill_house_name, "transaction_count": transaction_count, "persian_date": persian_date, "daily_quantity": daily_quantity, "persian_date_req": persian_date_req, "daily_quantity_req": daily_quantity_req, 'kill_houses_data': kill_house_data, 'kill_house_name_req': kill_house_name_req, 'poultry_req_name_req': poultry_req_name_req, 'top_poultry_req_stats_total_quantity': top_poultry_req_stats_total_quantity, 'poultry_city_req_name_req': poultry_city_req_name_req, 'out_poultry_req_name_req': out_poultry_req_name_req, 'out_poultry_city_req_name_req': out_poultry_city_req_name_req, 'out_poultry_province_req_name_req': out_poultry_province_req_name_req, 'out_top_poultry_req_stats_total_quantity': out_top_poultry_req_stats_total_quantity, 'management_kill_house_data': management_kill_house_data, 'duc_kill_house_data': duc_kill_house_data, 'avg_losses': int((aggregate_hatching['total_losses'] or 0) / poultry_hatching.count()), 'avg_total_killed_weight': round( (aggregate_hatching['total_killed_weight'] or 0) / (aggregate_hatching['killed_quantity'] or 0), 1), 'total_killing_ave_age': int(aggregate_hatching['total_killing_ave_age'] or 0), 'top_total_killed_weight': top_total_killed_weight_first['total_killed_weight'] or 0, 'total_quantity_top_inner': total_quantity_top_inner, 'total_quantity_top_out': total_quantity_top_out, 'bar_assigment_pending_count1': bar_assigment_pending_count1 or 0, 'base_url': base_url_for_sms_report, "total_quarantine_quantity": aggregate_kill_house_request['total_quarantine_quantity'] or 0, "total_count_has_quarantine": aggregate_kill_house_request['total_count_has_quarantine'] or 0, "total_quantity_has_quarantine": aggregate_kill_house_request['total_quantity_has_quarantine'] or 0, "different": different_bar or 0, "total_weight_hasnt_code": aggregate_kill_house_request['total_weight_hasnt_code'] or 0, "total_quantity_hasnt_code": aggregate_kill_house_request['total_quantity_hasnt_code'] or 0, "total_id_hasnt_code": aggregate_kill_house_request['total_id_hasnt_code'] or 0, "total_weight_hasnt_warehouse": aggregate_kill_house_request['total_weight_hasnt_warehouse'] or 0, "total_quantity_hasnt_warehouse": aggregate_kill_house_request['total_quantity_hasnt_warehouse'] or 0, "total_id_hasnt_warehouse": aggregate_kill_house_request['total_id_hasnt_warehouse'] or 0, "total_weight_hasnt_assignment_state_archive": aggregate_kill_house_request['total_weight_hasnt_assignment_state_archive'] or 0, "total_quantity_hasnt_assignment_state_archive": aggregate_kill_house_request['total_quantity_hasnt_assignment_state_archive'] or 0, "total_id_hasnt_assignment_state_archive": aggregate_kill_house_request['total_id_hasnt_assignment_state_archive'] or 0, "total_weight_hasnt_killing_age": aggregate_kill_house_request['total_weight_hasnt_killing_age'] or 0, "total_quantity_hasnt_killing_age": aggregate_kill_house_request['total_quantity_hasnt_killing_age'] or 0, "total_id_hasnt_killing_age": aggregate_kill_house_request['total_id_hasnt_killing_age'] or 0, 'different_bar_percent': different_bar_percent, 'max_and_min_assigment': max_and_min_assigment, 'management_kill_house_dict': management_kill_house_dict, } return Response(result) def create_update_chicken_commission_prices_cron(): now = datetime.datetime.now().date() for day in range(7): past_date = now - timedelta(days=day) past_datetime = datetime.datetime.combine(past_date, datetime.time.min) chicken_commission = ChickenCommissionPrices.objects.get_or_create(date__date=past_date, defaults={'date': past_datetime, 'kill_house_price': kill_house_price})[ 0] # # poultry_request poultry_request = PoultryRequest.objects.filter(trash=False, send_date__date=past_date, state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted'), out=False, amount__gt=0).only( 'amount') print(len(poultry_request)) poultry_request_amount = poultry_request.aggregate(total=Sum('amount'))[ 'total'] or 0 # ProvinceKillRequest province_kill_req = ProvinceKillRequest.objects.filter(trash=False, kill_request__recive_date__date=past_date, state__in=('pending', 'accepted'), kill_house_price__gt=0).only( 'kill_house_price') province_kill_req_kill_house_price = province_kill_req.aggregate(total=Sum('kill_house_price'))[ 'total'] or 0 # KillRequest kill_req = KillRequest.objects.filter(trash=False, recive_date__date=past_date, province_state__in=('accepted', 'pending') , poultry__isnull=False, direct_buying_state__in=('accepted', 'pending'), amount__gt=0).only( 'amount') kill_req_amount = kill_req.aggregate(total=Sum('amount'))[ 'total'] or 0 kill_request_amount = round( kill_req_amount / kill_req.count()) if kill_req.count() > 0 else 0 province_kill_request_amount = round(province_kill_req_kill_house_price / province_kill_req.count()) \ if province_kill_req.count() > 0 else 0 poultry_req_amount = round(poultry_request_amount / poultry_request.count()) if poultry_request.count() > 0 \ else 0 amount = round( kill_req_amount + province_kill_req_kill_house_price + poultry_request_amount) counts = poultry_request.count() + province_kill_req.count() + kill_req.count() chicken_commission.chicken_average_price = round(amount / counts) if counts > 0 else 0 chicken_commission.kill_request_amount = kill_request_amount chicken_commission.province_kill_request_amount = province_kill_request_amount chicken_commission.poultry_request_amount = poultry_req_amount chicken_commission.save() def fix_amount(request): my_tuple = ( 31160, 31310, 31311, 31508, 31509, 31558, 31559, 31642, 31643, 31755, 31756, 31817, 31818, 31850, 31852, 31912, 31913, 32019, 32020) steward_allocations = StewardAllocation.objects.filter(id__in=my_tuple) for steward_allocation in steward_allocations: amount = steward_allocation.amount - 20000 total_amount = amount * steward_allocation.real_weight_of_carcasses steward_allocation.amount = amount steward_allocation.total_amount = total_amount steward_allocation.total_amount_remain = total_amount steward_allocation.save() return HttpResponse('ok') def fix_killing_age(request): poultry_request = PoultryRequest.objects.filter(trash=False, killing_age=1).only('killing_age') for p in poultry_request: p.killing_age = (p.send_date.date() - p.hatching.date.date()).days + 1 p.save() return HttpResponse('ok') @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def get_bar_from_rsi_with_hatching(request): page = '' search_filter = '' search = request.GET.get('search') value = request.GET.get('value') if search: if search != 'undefined' and value.strip(): search_filter = f'&search={search}&value={value}' date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None poultry_hatching = PoultryHatching.objects.filter( key=request.GET['key'] ).first() kill_house_request = KillHouseRequest.objects.filter( trash=False, temporary_trash=False, temporary_deleted=False, clearance_code__isnull=False, province_request__poultry_request__hatching=poultry_hatching ).values_list('clearance_code', flat=True).distinct() kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True, hatching=poultry_hatching) \ .values_list('quarantine_code', flat=True).distinct() result = list(kill_house_request) + list(kill_house_free_sale) if 'page' in request.GET: page = f'&page={request.GET["page"]}&page_size={request.GET["page_size"]}' response = requests.get( f'https://rsibackend.rasadyar.com/app/api_send_different_bar-from-hatching/?{page}' f'{search_filter}' f'&date1={date1}&date2={date2}&licence_number={poultry_hatching.licence_number}', json=result, headers={'Content-Type': 'application/json'} ) return Response(response.json(), status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def driver_from_rsi_excel(request): response = requests.get( f'https://rsibackend.rasadyar.com/app/driver/?all' ) kill_house = KillHouse.objects.filter(trash=False, out_province=False).values_list('unique_identifier', flat=True) excel_options = [ 'ردیف', 'نام راننده', 'نام مالک', 'شهر', 'رهگیری خودرو', 'نوع ماشین', 'پلاک', 'محصول', 'کد کشتارگاه', 'نام کشتارگاه', 'شماره موبایل راننده', ] output = BytesIO() workbook = Workbook() worksheet = workbook.active worksheet.sheet_view.rightToLeft = True worksheet.insert_rows(1) m = 1 create_header_freez(worksheet, excel_options, 1, 1, 2, 20, width=30) l = 2 for data in response.json(): if data['part_id_code'] in kill_house: list1 = [ m, data['driver_name'], data['owner_name'], data['city'], data['tracking_code'], data['car_type'], data['pelak'], data['product'], data['part_id_code'], data['kill_house_name'], ] create_value(worksheet, list1, l, 1, m=m, border_style='thin') m += 1 l += 1 workbook.save(output) output.seek(0) response = HttpResponse( content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response[ 'Content-Disposition'] = f'attachment; filename="راننده ها .xlsx"'.encode( 'utf-8') response.write(output.getvalue()) return response @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def send_again_sms_for_register_code_guild(request): guild = Guilds.objects.get(trash=False, key=request.data['key']) if guild.is_registered == False and not guild.register_date_register_code: number = random.randint(10000, 99000) guild.register_code = number guild.active_register_code = True guild.register_date_register_code = datetime.datetime.now() guild.save() send_sms_for_guild_for_register(guild) elif datetime.datetime.now() > (guild.register_date_register_code + timedelta(minutes=10)): number = random.randint(10000, 99000) guild.register_code = number guild.register_date_register_code = datetime.datetime.now() guild.save() send_sms_for_guild(guild) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) def delete_free_bar_info(request): kill_house_free_bar = KillHouseFreeBarInformation.objects.filter(trash=False, ware_house=False) bar_clearance_code = kill_house_free_bar.values_list('bar_clearance_code', flat=True) bars = requests.post('https://rsibackend.rasadyar.com/app/delete_free_bar_from_rasadyaar/', data=bar_clearance_code) if bars.json(): for bar in bars.json(): delete_kill_req = kill_house_free_bar.filter(bar_clearance_code=bar['TrackingCode']).first() delete_kill_req.trash = True delete_kill_req.save() product = delete_kill_req.product kill_house_free_buying_product_warehousing(product) @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def send_again_sms_steward_allocation(request): steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False) if steward_allocation.to_guilds: mobile = steward_allocation.to_guilds.user.mobile buyer = steward_allocation.to_guilds.guilds_name else: mobile = steward_allocation.to_steward.user.mobile buyer = steward_allocation.to_steward.guilds_name if steward_allocation.kill_house: seller = steward_allocation.kill_house.name else: seller = steward_allocation.guilds.guilds_name date = shamsi_date(steward_allocation.date) weight = steward_allocation.weight_of_carcasses amount = steward_allocation.amount number = str(steward_allocation.registration_code) if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > ( steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \ not steward_allocation.expire_time_ten_minute: steward_allocation.expire_time_ten_minute = datetime.datetime.now() steward_allocation.save() steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) @api_view(["POST"]) @permission_classes([AllowAny]) @csrf_exempt def pos_send_again_sms_steward_allocation(request): steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False) if steward_allocation.to_guilds: mobile = steward_allocation.to_guilds.user.mobile buyer = steward_allocation.to_guilds.guilds_name else: mobile = steward_allocation.to_steward.user.mobile buyer = steward_allocation.to_steward.guilds_name if steward_allocation.kill_house: seller = steward_allocation.kill_house.name else: seller = steward_allocation.guilds.guilds_name date = shamsi_date(steward_allocation.date) weight = steward_allocation.weight_of_carcasses amount = steward_allocation.amount number = str(steward_allocation.registration_code) if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > ( steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \ not steward_allocation.expire_time_ten_minute: steward_allocation.expire_time_ten_minute = datetime.datetime.now() steward_allocation.save() steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) @api_view(["POST"]) @permission_classes([AllowAny]) @csrf_exempt def new_pos_send_again_sms_steward_allocation(request): steward_allocation = StewardAllocation.objects.get(key=request.data['key'], trash=False) if steward_allocation.to_guilds: mobile = steward_allocation.to_guilds.user.mobile buyer = steward_allocation.to_guilds.guilds_name else: mobile = steward_allocation.to_stewards.user.mobile buyer = steward_allocation.to_stewards.name if steward_allocation.kill_house: seller = steward_allocation.kill_house.name else: seller = steward_allocation.guilds.guilds_name date = shamsi_date(steward_allocation.date) weight = steward_allocation.weight_of_carcasses amount = steward_allocation.amount number = str(steward_allocation.registration_code) if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > ( steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \ not steward_allocation.expire_time_ten_minute: steward_allocation.expire_time_ten_minute = datetime.datetime.now() steward_allocation.save() steward_allocation_sms(mobile, date, weight, seller, number, buyer, amount) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def fix_number_from_rsi(request): poultry = Poultry.objects.filter(trash=False).select_related('user').only('user__mobile', 'breeding_unique_id') result = { str(p.breeding_unique_id): p.user.mobile for p in poultry if p.user and p.user.mobile } response = requests.post( f'https://rsibackend.rasadyar.com/app/fix_number/', json=result, headers={'Content-Type': 'application/json'} ) for r in response.json(): for k, v in r.items(): poultry = Poultry.objects.filter(breeding_unique_id=k).first() if poultry: if v is not None: data = { "first_mobile_number": poultry.user.mobile, "second_mobile_number": v, } req = requests.post( url=ARTA_URL_CHANGE_MOBILE_NUMBER, data=data, verify=False ) if req.status_code == 200: second_mobile_number = v user = User.objects.get(username=poultry.user.mobile) user.username = second_mobile_number user.save() user_profile = SystemUserProfile.objects.filter(user=user).first() user_profile.mobile = second_mobile_number user_profile.save() return Response(response.json()) def send_credit_sahandsms_sms(): filters = {} if base_url_for_sms_report == 'ha': filters['username'] = 'hamedan' elif base_url_for_sms_report == 'ku': filters['username'] = 'kurdistan' elif base_url_for_sms_report == 'ma': filters['username__in'] = ['markazi', 'senfmarkazi'] managements = ManagementSendSms.objects.filter(**filters) \ .values('username') \ .annotate(min_id=Min('id')) \ .values_list('min_id', flat=True) managements = ManagementSendSms.objects.filter(id__in=managements) for management in managements: r = requests.get( f"http://webservice.sahandsms.com/newsmswebservice.asmx/GetUserCredit?username={management.username}" f"&password={management.password}") url = f'https://eitaayar.ir/api/{token}/sendMessage' date = datetime.datetime.now().date() if base_url_for_sms_report == 'ma': province = 'مرکزی' elif base_url_for_sms_report == 'ha': province = 'همدان' elif base_url_for_sms_report == 'ku': province = 'کردستان' elif base_url_for_sms_report == 'bu': province = 'بوشهر' else: province = 'تست' date_shamsi = shamsi_date(date).replace('-', '_') base_message = '🗓📢❗ سامانه رصدیار، زنجیره تامین،تولید و توزیع مرغ گوشتی📢❗\n' base_message += f' #گزارش_مانده_حساب_پنل_پیامکی #{date_shamsi}\n' base_message += f' #استان_{province}\n\n' base_message += f'➖➖➖➖➖➖➖➖➖➖\n' messages = [] current_message = base_message root = ET.fromstring(r.content) credit_amount = int(root.text) amount = "{:,}".format(credit_amount) new_message_part = "🔸 نام کاربری پنل : {0} \n".format(management.username) new_message_part += "🔸 مانده حساب پنل : {0} ریال \n".format(amount) # new_message_part = "🔸 نام کاربری پنل {0}: {1} ریال \n".format(management.username, amount) if credit_amount < 1000000: new_message_part += "‼توجه: لطفا برای شارژ پنل پیامکی خود اقدام فرمایید‼" new_message_part += '\n➖➖➖➖➖➖➖➖➖➖\n' if len(current_message) + len(new_message_part) > 4000: messages.append(current_message) current_message = base_message current_message += new_message_part if current_message and current_message != base_message: messages.append(current_message) for message in messages: data = { 'chat_id': chat_id_mali, 'text': message, } response = requests.post(url, data=data, verify=False) @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def send_again_sms_steward_free_sale_bar(request): steward_allocation = StewardFreeSaleBarInformation.objects.get(key=request.data['key'], trash=False) if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > (steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \ not steward_allocation.expire_time_ten_minute: steward_allocation.expire_time_ten_minute = datetime.datetime.now() steward_allocation.save() send_sms_for_sale_bar_for_steward(steward_allocation) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def send_again_sms_kill_house_free_sale_bar(request): steward_allocation = KillHouseFreeSaleBarInformation.objects.get(key=request.data['key'], trash=False) if (steward_allocation.expire_time_ten_minute and datetime.datetime.now() > (steward_allocation.expire_time_ten_minute + timedelta(minutes=10))) or \ not steward_allocation.expire_time_ten_minute: steward_allocation.expire_time_ten_minute = datetime.datetime.now() steward_allocation.save() send_sms_for_sale_bar(steward_allocation) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def send_again_sms_direct_buying_code(request): kill_request = KillRequest.objects.get(key=request.data['key'], trash=False) if (kill_request.expire_time_ten_minute and datetime.datetime.now() > (kill_request.expire_time_ten_minute + timedelta(minutes=10))) or \ not kill_request.expire_time_ten_minute: kill_request.expire_time_ten_minute = datetime.datetime.now() kill_request.save() # Get required data for SMS from authentication.sms_management import confirm_price_poultry_request_direct_buying_sms from panel.helper_excel import shamsi_date mobile = kill_request.poultry.user.mobile poultry_fullname = kill_request.poultry.user.fullname quantity = "{:,}".format(int(kill_request.kill_capacity)) chicken_breed = kill_request.chicken_breed send_date = shamsi_date(kill_request.recive_date.date()) free_sale_in_province = kill_request.poultry_request.free_sale_in_province if kill_request.poultry_request else False amount = kill_request.amount request_kill_house = kill_request.kill_house.name confirm_code = kill_request.direct_buying_code confirm_price_poultry_request_direct_buying_sms( mobile, poultry_fullname, quantity, chicken_breed, send_date, free_sale_in_province, amount, request_kill_house, confirm_code ) else: return Response({'result': 'شما تا 10 دقیقه دیگر مجاز به ارسال کد نمیباشد!'}, status=status.HTTP_403_FORBIDDEN) return Response({'result': 'باموفقیت ارسال شد.'}) def delete_sale_bar(): steward_sale_bar = StewardFreeSaleBarInformation.objects.filter(trash=False, logged_registration_code__isnull=True, system_registration_code=True, active_expire_date_time=True, registration_code__isnull=False) for free_sale_bar in steward_sale_bar: free_sale_bar.trash = True free_sale_bar.save() guild_steward_free_sale_product_warehousing(free_sale_bar.product) kill_house_sale_bar = KillHouseFreeSaleBarInformation.objects.filter(trash=False, logged_registration_code__isnull=True, system_registration_code=True, active_expire_date_time=True, registration_code__isnull=False) for free_sale_bar_kill_house in kill_house_sale_bar: product = free_sale_bar_kill_house.product free_sale_bar_kill_house.trash = True free_sale_bar_kill_house.save() kill_house_free_sale_product_warehousing(product) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def delete_guilds_without_allocation(request): # 1. اول همه صنف‌ها رو می‌گیریم guilds = Guilds.objects.filter(trash=False, active=True).order_by('id') # 2. صنف‌هایی که توزیع دارند رو پیدا می‌کنیم guilds_with_allocation = StewardAllocation.objects.filter( trash=False ).values_list('to_steward_id', 'to_guilds_id') allocated_guild_ids = set() for to_steward_id, to_guilds_id in guilds_with_allocation: if to_steward_id: allocated_guild_ids.add(to_steward_id) if to_guilds_id: allocated_guild_ids.add(to_guilds_id) # 3. از صنف‌ها، فقط اونایی که توزیع ندارند رو می‌گیریم guilds_without_allocation = guilds.exclude(id__in=allocated_guild_ids) # 4. از صنف‌های بدون توزیع، اونایی که اصلاً دستگاه پز ندارند رو پیدا می‌کنیم guilds_without_pos = guilds_without_allocation.annotate( has_pos_machine=Count('guild_pos', filter=Q(guild_pos__trash=False)) ).filter(has_pos_machine=0) deleted_count = 0 # 5. صنف‌هایی که هم توزیع ندارند و هم دستگاه پز ندارند رو حذف می‌کنیم for guild in guilds_without_pos: guild.trash = True guild.save() deleted_count += 1 return Response({ 'result': 'باموفقیت انجام شد.', 'deleted_count': deleted_count, }, status=status.HTTP_200_OK) def get_evacuation_detail_by_request_code(rcode): if not rcode: raise ValueError("پارامتر code الزامی است.") payload = {"RequestCode": rcode} try: external_response = requests.post( "https://rsibackend.rasadyar.com/app/get-evacuation-detail-by-request-code/", json=payload, timeout=15, ) external_response.raise_for_status() except requests.RequestException as exc: raise RuntimeError("عدم امکان اتصال به سرویس تخلیه.") from exc try: return external_response.json() except ValueError as exc: raise ValueError( f"پاسخ نامعتبر از سرویس تخلیه: {external_response.text}" ) from exc def save_mobile_numbers(request): mobile_numbers = [ '09188176737', '09011110919', '09181112717', '09185914818', '09187040838', '09393946626', '09127687317', '09033073493', ] for number in mobile_numbers: SmsRecipient.objects.get_or_create( phone_number=number, defaults={'is_active': True} ) return HttpResponse('ok') def _process_auto_warehouse_steward_allocations(): now = datetime.datetime.now() threshold = now - timedelta(hours=8) total_updated = 0 guilds = Guilds.objects.filter(trash=False, active=True).order_by('id') for guild in guilds: allocations = StewardAllocation.objects.filter( trash=False, receiver_state__in=['accepted', 'pending'], create_date__lte=threshold ).filter( Q(to_steward=guild) | Q(to_guilds=guild), Q(warehouse=False) | Q(steward_warehouse=False) ) for allocation in allocations: if allocation.warehouse is False: allocation.warehouse = True allocation.steward_warehouse = True allocation.save() seller_product = allocation.product buyer_product = None try: if allocation.to_steward: buyer_product = RolesProducts.objects.get( guild=allocation.to_steward, parent_product=seller_product.parent_product ) elif allocation.to_guilds: buyer_product = RolesProducts.objects.get( guild=allocation.to_guilds, parent_product=seller_product.parent_product ) except RolesProducts.DoesNotExist: buyer_product = None if allocation.seller_type == 'KillHouse': if seller_product: kill_house_allocations_product_warehousing(seller_product) if buyer_product: guild_steward_allocations_product_warehousing(buyer_product) else: if seller_product: guild_steward_allocations_product_warehousing(seller_product) if buyer_product: guild_steward_allocations_product_warehousing(buyer_product) total_updated += 1 return total_updated @api_view(['POST', 'GET']) @permission_classes([AllowAny]) def auto_warehouse_steward_allocations(request): updated = _process_auto_warehouse_steward_allocations() return Response({ 'result': 'done', 'updated_allocations': updated }, status=status.HTTP_200_OK) def auto_warehouse_steward_allocations_cron(): try: _process_auto_warehouse_steward_allocations() return HttpResponse('ok') except Exception as e: return HttpResponse(f'error: {e}', status=500) @api_view(["POST"]) @permission_classes([AllowAny]) @csrf_exempt def import_poultry_science_from_excel(request): file_obj = request.FILES.get('file') if not file_obj: return Response({"result": "فایل ارسال نشده است."}, status=status.HTTP_400_BAD_REQUEST) try: workbook = openpyxl.load_workbook(BytesIO(file_obj.read()), data_only=True) except Exception: return Response({"result": "امکان خواندن فایل وجود ندارد."}, status=status.HTTP_400_BAD_REQUEST) sheet = workbook.active rows = list(sheet.iter_rows(values_only=True)) if not rows: return Response({"result": "فایل خالی است."}, status=status.HTTP_400_BAD_REQUEST) expected_headers = ["ردیف", "نام", "نام خانوادگی", "شهرستان کاربر", "کد ملی", "کد نظام مهندسی", "شماره همراه"] header_row = [ str(value).strip() if value is not None else "" for value in rows[0][:len(expected_headers)] ] if header_row != expected_headers: return Response( { "result": "هدر فایل با قالب مورد انتظار همخوانی ندارد.", "expected_headers": expected_headers, "received_headers": header_row }, status=status.HTTP_400_BAD_REQUEST ) group = Group.objects.filter(name__exact="PoultryScience").first() if not group: return Response({"result": "نقش PoultryScience تعریف نشده است."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) latest_base_order = SystemUserProfile.objects.filter(trash=False).order_by('-base_order') \ .values_list('base_order', flat=True).first() next_base_order = (latest_base_order + 1) if latest_base_order else 1000 stats = { "processed_rows": 0, "created_profiles": 0, "updated_profiles": 0, "created_poultry_science": 0, "skipped_rows": 0 } errors = [] def clean_text(value): if value is None: return None text = str(value).strip() return text or None def clean_digits(value): if value is None: return None digits = re.sub(r'\D', '', str(value)) return digits or None def normalize_mobile(value): digits = clean_digits(value) if not digits: return None if digits.startswith('98') and len(digits) == 12: digits = digits[2:] if len(digits) == 10: digits = f'0{digits}' if len(digits) == 11 and not digits.startswith('0'): digits = f'0{digits[1:]}' return digits if check_mobile_number(digits) else None def find_city(name): if not name: return None return City.objects.filter( trash=False ).filter( Q(name__iexact=name) | Q(city_name__iexact=name) ).select_related('province').first() for row_index, row in enumerate(rows[1:], start=2): if not row or not any(row): continue stats["processed_rows"] += 1 first_name = clean_text(row[1]) last_name = clean_text(row[2]) city_name = clean_text(row[3]) national_code = clean_digits(row[4]) engineering_code = clean_digits(row[5]) mobile = normalize_mobile(row[6]) if not mobile: stats["skipped_rows"] += 1 errors.append({"row": row_index, "reason": "شماره همراه نامعتبر است."}) continue city = find_city(city_name) if not city: stats["skipped_rows"] += 1 errors.append({"row": row_index, "reason": "شهرستان یافت نشد.", "city": city_name}) continue system_profile = SystemUserProfile.objects.filter(trash=False, mobile=mobile).last() if not system_profile: password = '2025' register_payload = { "username": mobile, "first_name": first_name or "", "last_name": last_name or "", "password": password, "national_code": national_code or '0', "role": "PoultryScience", "api_key": PROJECT_API_KEY } try: arta_response = requests.post( url=ARTA_REGISTER, data=register_payload, verify=False, timeout=20 ) except requests.RequestException as exc: stats["skipped_rows"] += 1 errors.append({"row": row_index, "reason": f"خطا در ثبت در آرتا: {exc}"}) continue if arta_response.status_code not in (200, 201): stats["skipped_rows"] += 1 errors.append( {"row": row_index, "reason": f"ثبت کاربر در آرتا انجام نشد ({arta_response.status_code})."}) continue hashed_password = hashlib.sha256(password.encode()).hexdigest() user, _ = User.objects.get_or_create( username=mobile, defaults={ "first_name": first_name or "", "last_name": last_name or "", "password": hashed_password } ) if first_name and user.first_name != first_name: user.first_name = first_name if last_name and user.last_name != last_name: user.last_name = last_name user.save() fullname = f"{first_name or ''} {last_name or ''}".strip() or None system_profile = SystemUserProfile.objects.create( mobile=mobile, first_name=first_name, last_name=last_name, fullname=fullname, user=user, base_order=next_base_order, password=password, national_code=national_code, city=city, province=city.province, city_name=city.name, province_name=city.province.name if city.province else None, city_number=city.city_number, province_number=city.province.province_number if city.province else None ) next_base_order += 1 stats["created_profiles"] += 1 else: updated = False if first_name and system_profile.first_name != first_name: system_profile.first_name = first_name updated = True if last_name and system_profile.last_name != last_name: system_profile.last_name = last_name updated = True if national_code and system_profile.national_code != national_code: system_profile.national_code = national_code updated = True if engineering_code and system_profile.system_code != engineering_code: system_profile.system_code = engineering_code updated = True if system_profile.city_id != city.id: system_profile.city = city system_profile.city_name = city.name system_profile.city_number = city.city_number updated = True if system_profile.province_id != (city.province.id if city.province else None): system_profile.province = city.province system_profile.province_name = city.province.name if city.province else None system_profile.province_number = city.province.province_number if city.province else None updated = True fullname = f"{system_profile.first_name or ''} {system_profile.last_name or ''}".strip() if fullname and system_profile.fullname != fullname: system_profile.fullname = fullname updated = True if not system_profile.user: hashed_password = hashlib.sha256('123456'.encode()).hexdigest() user, _ = User.objects.get_or_create( username=mobile, defaults={ "first_name": first_name or system_profile.first_name or "", "last_name": last_name or system_profile.last_name or "", "password": hashed_password } ) system_profile.user = user updated = True else: user = system_profile.user if first_name and user.first_name != first_name: user.first_name = first_name user.save(update_fields=["first_name"]) if last_name and user.last_name != last_name: user.last_name = last_name user.save(update_fields=["last_name"]) if updated: system_profile.save() stats["updated_profiles"] += 1 if not system_profile.role.filter(id=group.id).exists(): system_profile.role.add(group) poultry_science = PoultryScience.objects.filter(trash=False, user=system_profile).first() if not poultry_science: PoultryScience.objects.create(user=system_profile, engineering_code=engineering_code) stats["created_poultry_science"] += 1 else: updated_fields = [] if engineering_code and poultry_science.engineering_code != engineering_code: poultry_science.engineering_code = engineering_code updated_fields.append("engineering_code") if updated_fields: poultry_science.save(update_fields=updated_fields) return Response( { "result": "done", "summary": stats, "errors": errors }, status=status.HTTP_200_OK ) @api_view(["GET"]) @permission_classes([AllowAny]) def sync_guilds_user_profile_from_inquiry(request): """ برگرداندن لیست صنف‌هایی که: - برای کاربرشان کد ملی ثبت شده است (user__national_id خالی/NULL نیست) - هنوز استعلام نشده‌اند (has_inquiry = False) علاوه بر لیست، برای هر صنف استعلام «شخص» و «صنف» انجام می‌شود و فقط اطلاعات کاربر (SystemUserProfile) به‌روزرسانی می‌شود. در صورت موفقیت، روی خود صنف فقط has_inquiry=True ست می‌شود. """ queryset = Guilds.objects.filter( trash=False, user__national_id__isnull=False, steward=True ).exclude(user__national_id__exact="") failed_records = [] updated_ids = [] # کش شهرها برای بهبود کارایی جستجوی شهر all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name')) def _normalize_fa_ar(text): if not text: return text mapping = { 'ك': 'ک', 'ي': 'ی', 'ى': 'ی', '\u0649': 'ی', '\u06CC': 'ی', '\u064A': 'ی', 'ۀ': 'ه', 'ة': 'ه', 'ؤ': 'و', 'أ': 'ا', 'إ': 'ا', 'ٱ': 'ا', '\u200c': ' ', } out = str(text) for src, dst in mapping.items(): out = out.replace(src, dst) return out.strip() def parse_yes_no(val): if not val: return False return str(val).strip() == 'بله' for guild in queryset: national_id = getattr(getattr(guild, "user", None), "national_id", None) if not national_id: failed_records.append( {"guild_id": guild.id, "reason": "کد ملی برای کاربر این صنف ثبت نشده است"} ) continue try: # دریافت اطلاعات شخص try: person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person" ) person_data = person_response.json() if not person_data.get('status'): failed_records.append( {"guild_id": guild.id, "national_id": national_id, "reason": "اطلاعات شخص یافت نشد"} ) continue person_info = person_data.get('data', {}) except Exception as e: failed_records.append( { "guild_id": guild.id, "national_id": national_id, "reason": f"خطا در دریافت اطلاعات شخصی: {str(e)}", } ) continue # دریافت اطلاعات صنفی try: guild_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_id}&type=guild" ) guild_data = guild_response.json() if not guild_data.get('status') or not guild_data.get('data'): failed_records.append( {"guild_id": guild.id, "national_id": national_id, "reason": "اطلاعات صنفی یافت نشد"} ) continue guild_list = guild_data.get('data', []) guild_info = None for g in guild_list: license_status_value = g.get('licenseStatus', '') if license_status_value and 'فعال' in license_status_value: guild_info = g break if not guild_info: failed_records.append( { "guild_id": guild.id, "national_id": national_id, "reason": "هیچ پروانه کسب فعالی برای این کد ملی یافت نشد (تمام پروانه‌ها ابطال شده‌اند)", } ) continue guild_layer_two = guild_info.get('layerTwo', {}) except Exception as e: failed_records.append( { "guild_id": guild.id, "national_id": national_id, "reason": f"خطا در دریافت اطلاعات صنفی: {str(e)}", } ) continue # مقادیر مورد نیاز برای به‌روزرسانی first_name = person_info.get('firstName') last_name = person_info.get('lastName') father_name = person_info.get('fatherName') gender = person_info.get('gender') identity_no = person_info.get('identityNo') is_alive = person_info.get('isLive', True) birth_date = person_info.get('birthDate') try: jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date() birthday_str = jalali_date.strftime("%Y-%m-%d") except Exception: birthday_str = None city_name = guild_info.get('city') mobile_from_guild = guild_layer_two.get('mobilenumber') has_partner = parse_yes_no(guild_layer_two.get('hasPartner')) is_foreign_national = parse_yes_no(guild_layer_two.get('isForeigner')) # پیدا کردن شهر (همان منطق قبلی) city = City.objects.filter(name__icontains=city_name, trash=False).first() if not city: normalized_city = _normalize_fa_ar(city_name) city = City.objects.filter(name__icontains=normalized_city, trash=False).first() if not city: alt_city = str(city_name or '') alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي') city = City.objects.filter(name__icontains=alt_city, trash=False).first() if not city: try: target = _normalize_fa_ar(city_name or '') best_id = None best_ratio = 0.0 for c in all_cities_cache: cand = _normalize_fa_ar(c.get('name', '') or '') ratio = difflib.SequenceMatcher(None, target, cand).ratio() if ratio > best_ratio: best_ratio = ratio best_id = c['id'] if best_id is not None and best_ratio >= 0.72: city = City.objects.filter(id=best_id, trash=False).first() except Exception: city = None # به‌روزرسانی اطلاعات کاربر و فلگ استعلام صنف (بدون دست‌زدن به سایر فیلدهای صنف) try: user_profile = guild.user if user_profile: # اگر شماره موبایل در استعلام صنفی وجود دارد و با موبایل فعلی فرق می‌کند if mobile_from_guild and mobile_from_guild != user_profile.mobile: first_mobile_number = user_profile.mobile second_mobile_number = mobile_from_guild # شماره جدید قبلا برای شخص دیگری ثبت نشده باشد if SystemUserProfile.objects.filter(mobile=second_mobile_number) \ .exclude(id=user_profile.id).exists(): failed_records.append( { "guild_id": guild.id, "national_id": national_id, "reason": "این شماره در سامانه به نام شخص دیگری است", } ) continue data = { "first_mobile_number": first_mobile_number, "second_mobile_number": second_mobile_number, } req = requests.post( url=ARTA_URL_CHANGE_MOBILE_NUMBER, data=data, verify=False ) if req.status_code == 200: user = User.objects.get(id=user_profile.user.id) user.username = second_mobile_number user.save() user_profile.mobile = second_mobile_number else: failed_records.append( { "guild_id": guild.id, "national_id": national_id, "reason": "در تغییر شماره موبایل در آرتا مشکلی به‌وجود آمده است", } ) continue user_profile.national_id = national_id user_profile.national_code = identity_no user_profile.first_name = first_name user_profile.last_name = last_name user_profile.fullname = f"{first_name} {last_name}".strip() user_profile.father_name = father_name user_profile.gender = gender if birthday_str: user_profile.birthday = birthday_str user_profile.is_alive = is_alive if city: user_profile.city = city user_profile.province = city.province user_profile.save() guild.has_inquiry = True guild.save(update_fields=["has_inquiry"]) updated_ids.append(guild.id) except Exception as e: failed_records.append( {"guild_id": guild.id, "national_id": national_id, "reason": f"خطا در آپدیت صنف/کاربر: {str(e)}"} ) continue except Exception as e: failed_records.append( {"guild_id": guild.id, "national_id": national_id, "reason": f"خطای کلی: {str(e)}"} ) continue updated_guilds = Guilds.objects.filter(id__in=updated_ids) serializer = GuildsSerializer(updated_guilds, many=True) return Response( { "result": "پردازش کامل شد", "updated_count": len(updated_ids), "failed_count": len(failed_records), "failed_records": failed_records, "guilds": serializer.data, }, status=status.HTTP_200_OK, ) @api_view(["GET"]) @permission_classes([AllowAny]) def report_guilds_without_national_or_pos_transactions(request): """ برگرداندن لیست صنف‌هایی که: - کاربرشان کد ملی ندارد (national_id خالی/NULL است) - یا هیچ تراکنش فعالی در جدول PosMachineTransactions برای آن‌ها ثبت نشده است """ # ۱) ابتدا برای همه صنف‌ها has_inquiry را False می‌کنیم Guilds.objects.filter(trash=False).update(has_inquiry=False) # ۲) فقط صنف‌های فعال و غیرحذف‌شده را برای بررسی انتخاب می‌کنیم queryset = Guilds.objects.filter(trash=False, active=True) result_guilds = [] missing_national_id_count = 0 missing_pos_txn_count = 0 deactivated_count = 0 for guild in queryset: national_id = getattr(getattr(guild, "user", None), "national_id", None) has_national_id = bool(national_id) transactions = PosMachineTransactions.objects.filter( trash=False, pos__guild=guild, paid=True ).order_by('-date') has_pos_transactions = transactions.exists() # صنف‌هایی که یا کد ملی ندارند یا هیچ تراکنش فعالی ندارند if (not has_national_id) or (not has_pos_transactions): result_guilds.append(guild) if not has_national_id: missing_national_id_count += 1 if not has_pos_transactions: missing_pos_txn_count += 1 # صنف‌هایی که نه کد ملی دارند و نه تراکنش => غیرفعال می‌شوند if (not has_national_id) and (not has_pos_transactions) and guild.active: guild.active = False guild.save(update_fields=["active"]) deactivated_count += 1 total = len(result_guilds) serializer = GuildsSerializer(result_guilds, many=True) return Response( { "result": "ok", "total": total, "missing_national_id_count": missing_national_id_count, "missing_pos_transactions_count": missing_pos_txn_count, "deactivated_count": deactivated_count, "guilds": serializer.data, }, status=status.HTTP_200_OK, ) @api_view(["GET"]) @permission_classes([TokenHasReadWriteScope]) def get_guilds_for_update_or_create(request): national_code = request.GET['national_code'] role = request.GET.get('role') update_flag = request.GET.get('update', '').lower() == 'true' users = SystemUserProfile.objects.filter(trash=False, national_id=national_code, active=True).order_by('id') _guilds = Guilds.objects.filter( trash=False, user__national_id=national_code, active=True ).order_by('id') api_data = {"dbRegister": False} if (not users.exists() or not _guilds.exists()) or update_flag: try: person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person" ) person_data = person_response.json() person_info = person_data.get('data', {}) api_data['user'] = person_info except Exception as e: return Response({"result": f"خطا در دریافت اطلاعات شخصی: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) try: guild_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild" ) guild_data = guild_response.json() if (not guild_data.get('status') or not guild_data.get('data')) and role == 'AdminX': return Response(api_data, status=status.HTTP_200_OK) if (not guild_data.get('status') or not guild_data.get('data')) and role != 'AdminX': return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) guild_list = guild_data.get('data', []) if not guild_list or len(guild_list) == 0: return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) has_valid_guild = False for guild in guild_list: layer_two = guild.get('layerTwo', {}) if layer_two and layer_two.get('licenseIssueDate'): has_valid_guild = True break if not has_valid_guild: return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) guild_info = None active_guilds = [] inactive_guilds = [] for guild in guild_list: layer_two = guild.get('layerTwo', {}) license_status_value = layer_two.get('licenseStatus', '') if layer_two else '' if license_status_value and 'فعال' in license_status_value: active_guilds.append(guild) else: inactive_guilds.append(guild) if not active_guilds and inactive_guilds: def parse_persian_date(date_str): if not date_str: return None try: date_str = date_str.strip() parts = date_str.split('/') if len(parts) == 3: year = int(parts[0]) month = int(parts[1]) day = int(parts[2]) return jdatetime.date(year, month, day) except: pass return None latest_guild = None latest_date = None for guild in inactive_guilds: layer_two = guild.get('layerTwo', {}) license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else '' parsed_date = parse_persian_date(license_issue_date) if parsed_date: if latest_date is None or parsed_date > latest_date: latest_date = parsed_date latest_guild = guild if latest_guild: guild_info = latest_guild if not guild_info and guild_list: guild_info = guild_list[0] if active_guilds: api_data['guild'] = active_guilds elif guild_info: api_data['guild'] = guild_info except Exception as e: if 'active_guilds' in locals() and active_guilds: api_data['guild'] = active_guilds elif 'guild_info' in locals() and guild_info: api_data['guild'] = guild_info elif 'guild_list' in locals() and guild_list: api_data['guild'] = guild_list[0] if users.count() > 1: users_with_valid_guilds = [] for user in users: guilds = Guilds.objects.filter(trash=False, user=user, active=True) if guilds.exists(): has_steward_guild = guilds.filter(steward=True).exists() has_allocation = False if not has_steward_guild: for guild in guilds: latest_allocation = StewardAllocation.objects.filter( Q(to_steward=guild) | Q(to_guilds=guild), trash=False ).order_by('-date').first() if latest_allocation: has_allocation = True break if has_steward_guild or has_allocation: users_with_valid_guilds.append(user) if users_with_valid_guilds: if len(users_with_valid_guilds) > 1: valid_user_ids = [u.id for u in users_with_valid_guilds] latest_user = SystemUserProfile.objects.filter(id__in=valid_user_ids).order_by('-id').first() if latest_user: users_with_valid_guilds = [latest_user] else: users_with_valid_guilds = users_with_valid_guilds[:1] valid_user_ids = [u.id for u in users_with_valid_guilds] guilds = Guilds.objects.filter(trash=False, user__in=users, active=True).exclude( user__id__in=valid_user_ids).update(active=False) users.exclude(id__in=valid_user_ids).update(active=False, national_id=0) users = SystemUserProfile.objects.filter(id__in=valid_user_ids, trash=False, active=True) else: latest_user = users.order_by('-id').first() users.exclude(id=latest_user.id).update(active=False, national_id=0) users = SystemUserProfile.objects.filter(id=latest_user.id, trash=False, active=True) for user in users: guilds = Guilds.objects.filter(trash=False, user=user, active=True) if guilds.count() > 1: guilds_to_keep_active = set() steward_guilds = guilds.filter(steward=True) guilds_to_keep_active.update(steward_guilds.values_list('id', flat=True)) guilds_with_allocation_info = [] for guild in guilds: latest_allocation = StewardAllocation.objects.filter( Q(to_steward=guild) | Q(to_guilds=guild), trash=False ).order_by('-date').first() if latest_allocation: allocation_date = latest_allocation.date if latest_allocation.date else latest_allocation.created_at guilds_with_allocation_info.append({ 'guild_id': guild.id, 'allocation_date': allocation_date, 'allocation': latest_allocation }) if guilds_with_allocation_info: valid_allocation_info = [item for item in guilds_with_allocation_info if item['allocation_date']] if valid_allocation_info: max_date = max(item['allocation_date'] for item in valid_allocation_info) for item in valid_allocation_info: if item['allocation_date'] == max_date: guilds_to_keep_active.add(item['guild_id']) if not guilds_to_keep_active: latest_guild = guilds.order_by('-created_at', '-updated_at').first() if latest_guild: guilds_to_keep_active.add(latest_guild.id) guilds.exclude(id__in=guilds_to_keep_active).update(active=False) if api_data and any(key != 'dbRegister' for key in api_data.keys()): return Response(api_data, status=status.HTTP_200_OK) final_guilds = Guilds.objects.filter( trash=False, user__national_id=national_code, active=True ) serializer = GuildsSerializer(final_guilds.first()) return Response(serializer.data, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([TokenHasReadWriteScope]) def get_guilds_for_update_or_create_new(request): national_code = request.GET['national_code'] role = request.GET.get('role') update_flag = request.GET.get('update', '').lower() == 'true' users = SystemUserProfile.objects.filter(trash=False, national_id=national_code, active=True).order_by('id') _guilds = Guilds.objects.filter( trash=False, user__national_id=national_code, active=True ).order_by('id') api_data = {"dbRegister": False} if (not users.exists() or not _guilds.exists()) or update_flag: try: person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person" ) person_data = person_response.json() person_info = person_data.get('data', {}) api_data['user'] = person_info except Exception as e: return Response({"result": f"خطا در دریافت اطلاعات شخصی: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) try: guild_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild" ) guild_data = guild_response.json() if (not guild_data.get('status') or not guild_data.get('data')) and role == 'AdminX': return Response(api_data, status=status.HTTP_200_OK) if (not guild_data.get('status') or not guild_data.get('data')) and role != 'AdminX': return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) guild_list = guild_data.get('data', []) if not guild_list or len(guild_list) == 0: return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) has_valid_guild = False for guild in guild_list: layer_two = guild.get('layerTwo', {}) if layer_two and layer_two.get('licenseIssueDate'): has_valid_guild = True break if not has_valid_guild: return Response({"result": "اطلاعات صنفی یافت نشد با واحد پشتیبانی تماس بگیرید."}, status=status.HTTP_403_FORBIDDEN) guild_info = None active_guilds = [] inactive_guilds = [] for guild in guild_list: layer_two = guild.get('layerTwo', {}) license_status_value = layer_two.get('licenseStatus', '') if layer_two else '' if license_status_value and 'فعال' in license_status_value: active_guilds.append(guild) else: inactive_guilds.append(guild) if not active_guilds and inactive_guilds: def parse_persian_date(date_str): if not date_str: return None try: date_str = date_str.strip() parts = date_str.split('/') if len(parts) == 3: year = int(parts[0]) month = int(parts[1]) day = int(parts[2]) return jdatetime.date(year, month, day) except: pass return None latest_guild = None latest_date = None for guild in inactive_guilds: layer_two = guild.get('layerTwo', {}) license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else '' parsed_date = parse_persian_date(license_issue_date) if parsed_date: if latest_date is None or parsed_date > latest_date: latest_date = parsed_date latest_guild = guild if latest_guild: guild_info = latest_guild if not guild_info and guild_list: guild_info = guild_list[0] if active_guilds: api_data['guild'] = active_guilds elif guild_info: api_data['guild'] = guild_info except Exception as e: if 'active_guilds' in locals() and active_guilds: api_data['guild'] = active_guilds elif 'guild_info' in locals() and guild_info: api_data['guild'] = guild_info elif 'guild_list' in locals() and guild_list: api_data['guild'] = guild_list[0] if users.count() > 1: users_with_valid_guilds = [] for user in users: guilds = Guilds.objects.filter(trash=False, user=user, active=True) if guilds.exists(): has_steward_guild = guilds.filter(steward=True).exists() has_allocation = False if not has_steward_guild: for guild in guilds: latest_allocation = StewardAllocation.objects.filter( Q(to_steward=guild) | Q(to_guilds=guild), trash=False ).order_by('-date').first() if latest_allocation: has_allocation = True break if has_steward_guild or has_allocation: users_with_valid_guilds.append(user) if users_with_valid_guilds: if len(users_with_valid_guilds) > 1: valid_user_ids = [u.id for u in users_with_valid_guilds] latest_user = SystemUserProfile.objects.filter(id__in=valid_user_ids).order_by('-id').first() if latest_user: users_with_valid_guilds = [latest_user] else: users_with_valid_guilds = users_with_valid_guilds[:1] valid_user_ids = [u.id for u in users_with_valid_guilds] guilds = Guilds.objects.filter(trash=False, user__in=users, active=True).exclude( user__id__in=valid_user_ids).update(active=False) users.exclude(id__in=valid_user_ids).update(active=False, national_id=0) users = SystemUserProfile.objects.filter(id__in=valid_user_ids, trash=False, active=True) else: latest_user = users.order_by('-id').first() users.exclude(id=latest_user.id).update(active=False, national_id=0) users = SystemUserProfile.objects.filter(id=latest_user.id, trash=False, active=True) for user in users: guilds = Guilds.objects.filter(trash=False, user=user, active=True) if guilds.count() > 1: guilds_to_keep_active = set() steward_guilds = guilds.filter(steward=True) guilds_to_keep_active.update(steward_guilds.values_list('id', flat=True)) guilds_with_allocation_info = [] for guild in guilds: latest_allocation = StewardAllocation.objects.filter( Q(to_steward=guild) | Q(to_guilds=guild), trash=False ).order_by('-date').first() if latest_allocation: allocation_date = latest_allocation.date if latest_allocation.date else latest_allocation.created_at guilds_with_allocation_info.append({ 'guild_id': guild.id, 'allocation_date': allocation_date, 'allocation': latest_allocation }) if guilds_with_allocation_info: valid_allocation_info = [item for item in guilds_with_allocation_info if item['allocation_date']] if valid_allocation_info: max_date = max(item['allocation_date'] for item in valid_allocation_info) for item in valid_allocation_info: if item['allocation_date'] == max_date: guilds_to_keep_active.add(item['guild_id']) if not guilds_to_keep_active: latest_guild = guilds.order_by('-created_at', '-updated_at').first() if latest_guild: guilds_to_keep_active.add(latest_guild.id) guilds.exclude(id__in=guilds_to_keep_active).update(active=False) if api_data and any(key != 'dbRegister' for key in api_data.keys()): return Response(api_data, status=status.HTTP_200_OK) final_guilds = Guilds.objects.filter( trash=False, user__national_id=national_code, active=True ) serializer = GuildsSerializer(final_guilds.first()) return Response(serializer.data, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) def get_legal_person_unit_info(request): national_code = request.GET.get('national_code') if not national_code: return Response({"result": "کد ملی الزامی است"}, status=status.HTTP_400_BAD_REQUEST) existing_user = SystemUserProfile.objects.filter( trash=False, national_id=national_code, active=True ).first() if existing_user: return Response({ "result": "کاربر در سیستم وجود دارد!" }, status=status.HTTP_403_FORBIDDEN) try: unit_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=unit" ) unit_data = unit_response.json() if not unit_data.get('status') or not unit_data.get('data'): return Response({"result": "اطلاعات واحد صنفی یافت نشد"}, status=status.HTTP_403_FORBIDDEN) unit_info = unit_data.get('data', {}) unit_name = unit_info.get('name', '') unit_national_code = unit_info.get('nationalCode', '') unit_address = unit_info.get('address', '') city_name = None province_name = None if unit_address: address_parts = unit_address.split() if 'استان' in address_parts: province_idx = address_parts.index('استان') if province_idx + 1 < len(address_parts): province_parts = [] for i in range(province_idx + 1, len(address_parts)): if address_parts[i] in ['شهرستان', 'شهر', 'بخش']: break province_parts.append(address_parts[i]) if province_parts: province_name = ' '.join(province_parts) if 'شهرستان' in address_parts: city_idx = address_parts.index('شهرستان') if city_idx + 1 < len(address_parts): city_parts = [] for i in range(city_idx + 1, len(address_parts)): if address_parts[i] in ['بخش', 'شهر']: break city_parts.append(address_parts[i]) if city_parts: city_name = ' '.join(city_parts) if not city_name and 'شهر' in address_parts: city_idx = address_parts.index('شهر') if city_idx + 1 < len(address_parts): city_parts = [] for i in range(city_idx + 1, len(address_parts)): if address_parts[i] in ['بخش', 'کوچه', 'خیابان', 'پلاک']: break city_parts.append(address_parts[i]) if city_parts: city_name = ' '.join(city_parts) first_name = unit_name.split(' ')[0] last_name = unit_name.split(' ')[1] result_data = { "is_real_person": False, "first_name": first_name or "", "last_name": last_name or "", "national_id": unit_national_code, "province": province_name or "", "address": unit_address, "unit_name": unit_name, } return Response(result_data, status=status.HTTP_200_OK) except requests.RequestException as e: return Response({"result": f"خطا در ارتباط با API: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except Exception as e: import logging logger = logging.getLogger(__name__) logger.error(f"خطا در پردازش اطلاعات واحد صنفی: {str(e)}") return Response({"result": f"خطا در پردازش اطلاعات: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) @api_view(["GET"]) @permission_classes([AllowAny]) def update_all_active_guilds_from_api(request): """ دریافت تمام guild های فعال و آپدیت آن‌ها از API """ import logging logger = logging.getLogger(__name__) # دریافت تمام guild های فعال active_guilds = Guilds.objects.filter(trash=False, active=True) success_count = 0 failed_count = 0 skipped_count = 0 failed_records = [] def _normalize_fa_ar(text): """نرمالایز کردن متن فارسی/عربی""" if not text: return text mapping = { 'ك': 'ک', 'ي': 'ی', 'ى': 'ی', '\u0649': 'ی', '\u06CC': 'ی', '\u064A': 'ی', 'ۀ': 'ه', 'ة': 'ه', 'ؤ': 'و', 'أ': 'ا', 'إ': 'ا', 'ٱ': 'ا', '\u200c': ' ', } out = str(text) for src, dst in mapping.items(): out = out.replace(src, dst) return out.strip() def parse_yes_no(val): """تبدیل مقدار به boolean""" if isinstance(val, bool): return val if isinstance(val, str): return False if val == 'خیر' else True return bool(val) def persian_date_to_datetime(persian_date_str): """تبدیل تاریخ فارسی به datetime""" if not persian_date_str: return None try: persian_numbers = '۰۱۲۳۴۵۶۷۸۹' english_numbers = '0123456789' translation_table = str.maketrans(persian_numbers, english_numbers) english_date = persian_date_str.translate(translation_table) parts = english_date.split('/') if len(parts) != 3: return None year = int(parts[0]) month = int(parts[1]) day = int(parts[2]) return convert_to_miladi(year=year, month=month, day=day) except: return None all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name')) for guild in active_guilds: try: # دریافت کد ملی کاربر user = guild.user if not user or not user.national_id: skipped_count += 1 continue national_code = user.national_id # دریافت اطلاعات شخصی از API try: person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=person" ) person_data = person_response.json() if not person_data.get('status') or not person_data.get('data'): failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': 'اطلاعات شخصی یافت نشد' }) continue person_info = person_data.get('data', {}) except Exception as e: failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': f'خطا در دریافت اطلاعات شخصی: {str(e)}' }) continue # دریافت اطلاعات صنفی از API try: guild_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_code}&type=guild" ) guild_data = guild_response.json() if not guild_data.get('status') or not guild_data.get('data'): failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': 'اطلاعات صنفی یافت نشد' }) continue guild_list = guild_data.get('data', []) if not guild_list or len(guild_list) == 0: failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': 'لیست صنف‌ها خالی است' }) continue # انتخاب guild مناسب (فعال یا جدیدترین) guild_info = None active_guilds_list = [] inactive_guilds_list = [] for g in guild_list: layer_two = g.get('layerTwo', {}) license_status_value = layer_two.get('licenseStatus', '') if layer_two else '' if license_status_value and 'فعال' in license_status_value: active_guilds_list.append(g) else: inactive_guilds_list.append(g) if active_guilds_list: guild_info = active_guilds_list[0] elif inactive_guilds_list: def parse_persian_date(date_str): if not date_str: return None try: date_str = date_str.strip() parts = date_str.split('/') if len(parts) == 3: year = int(parts[0]) month = int(parts[1]) day = int(parts[2]) return jdatetime.date(year, month, day) except: pass return None latest_guild = None latest_date = None for g in inactive_guilds_list: layer_two = g.get('layerTwo', {}) license_issue_date = layer_two.get('licenseIssueDate', '') if layer_two else '' parsed_date = parse_persian_date(license_issue_date) if parsed_date: if latest_date is None or parsed_date > latest_date: latest_date = parsed_date latest_guild = g if latest_guild: guild_info = latest_guild if not guild_info: guild_info = guild_list[0] except Exception as e: failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': f'خطا در دریافت اطلاعات صنفی: {str(e)}' }) continue # استخراج اطلاعات از API layer_one = guild_info.get('layerOne', {}) layer_two = guild_info.get('layerTwo', {}) # اطلاعات شخصی first_name = person_info.get('firstName', '') last_name = person_info.get('lastName', '') father_name = person_info.get('fatherName', '') gender = person_info.get('gender', '') identity_no = person_info.get('identityNo', '') birth_date = person_info.get('birthDate', '') city_name = layer_two.get('city', '') address_text = layer_two.get('address', '') postal_code = layer_two.get('postalcode', '') mobile = person_info.get('mobile', '') or person_info.get('mobilenumber', '') # اطلاعات صنفی title = layer_one.get('title', '') or layer_two.get('title', '') or guild_info.get('title', '') license_number = guild_info.get('licenseNumber', '') license_type = guild_info.get('licenseType', '') license_status = guild_info.get('licenseStatus', '') license_issue_date = layer_two.get('licenseIssueDate', '') license_expire_date = guild_info.get('licenseExpireDate', '') type_activity_name = layer_one.get('isicname', '') or layer_two.get('isicname', '') company_name = layer_one.get('corporationName', '') or layer_two.get('corporationName', '') company_identifier = layer_one.get('nationalId', '') or layer_two.get('nationalId', '') union_name = layer_one.get('unionName', '') or layer_two.get('unionName', '') phone = layer_one.get('phonenumber', '') or layer_two.get('phonenumber', '') has_partner_val = layer_one.get('hasPartner', '') or layer_two.get('hasPartner', '') is_foreigner_val = layer_one.get('isForeigner', '') or layer_two.get('isForeigner', '') steward = guild.steward # حفظ مقدار فعلی # تبدیل تاریخ تولد birthday_str = None if birth_date: try: jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date() birthday_str = jalali_date.strftime("%Y-%m-%d") except: pass # تبدیل boolean ها has_partner = parse_yes_no(has_partner_val) is_foreign_national = parse_yes_no(is_foreigner_val) # پیدا کردن شهر city = City.objects.filter(name__icontains=city_name, trash=False).first() if not city: normalized_city = _normalize_fa_ar(city_name) city = City.objects.filter(name__icontains=normalized_city, trash=False).first() if not city: alt_city = str(city_name or '') alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي') city = City.objects.filter(name__icontains=alt_city, trash=False).first() if not city: try: target = _normalize_fa_ar(city_name or '') best_id = None best_ratio = 0.0 for c in all_cities_cache: cand = _normalize_fa_ar(c.get('name', '') or '') ratio = difflib.SequenceMatcher(None, target, cand).ratio() if ratio > best_ratio: best_ratio = ratio best_id = c['id'] if best_id is not None and best_ratio >= 0.72: city = City.objects.filter(id=best_id, trash=False).first() except Exception: city = None if not city: failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': national_code, 'error': f"شهر '{city_name}' یافت نشد" }) continue province = city.province # آپدیت اطلاعات کاربر if user: user.national_id = national_code user.national_code = identity_no user.father_name = father_name user.gender = gender user.birthday = birthday_str if city: user.city = city user.province = province if first_name: user.first_name = first_name if last_name: user.last_name = last_name user.fullname = f"{first_name} {last_name}".strip() if mobile and not user.mobile: user.mobile = mobile user.save() # ایجاد یا آپدیت آدرس if address_text: address = SystemAddress(city=city, province=province, address=address_text, postal_code=postal_code) address.save() else: address = guild.address if guild.address else None # پیدا کردن TypeActivity و AreaActivity from panel.models import TypeActivity, AreaActivity type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first() if not type_activity: type_activity = TypeActivity.objects.filter(trash=False).first() area_activity = AreaActivity.objects.filter(trash=False).first() # آپدیت guild guild.guilds_name = title guild.license_number = license_number guild.license_type = license_type guild.license_status = license_status guild.is_foreign_national = is_foreign_national guild.has_partner = has_partner guild.has_inquiry = True guild.company_name = company_name guild.company_identifier = company_identifier if address: guild.address = address guild.type_activity = type_activity.title if type_activity else type_activity_name guild.area_activity = area_activity.title if area_activity else '' guild.guild_type_activity = type_activity guild.guild_area_activity = area_activity guild.union_name = union_name guild.phone_number = phone guild.active = True if license_issue_date: converted_date = persian_date_to_datetime(license_issue_date) if converted_date: guild.license_issue_date = converted_date if license_expire_date: converted_date = persian_date_to_datetime(license_expire_date) if converted_date: guild.license_expire_date = converted_date guild.save() success_count += 1 except Exception as e: failed_count += 1 failed_records.append({ 'guild_id': guild.id, 'national_id': getattr(guild.user, 'national_id', '') if guild.user else '', 'error': f'خطای کلی: {str(e)}' }) logger.error(f"خطا در آپدیت guild {guild.id}: {str(e)}") continue return Response({ 'result': 'پردازش کامل شد', 'total_guilds': active_guilds.count(), 'success_count': success_count, 'failed_count': failed_count, 'skipped_count': skipped_count, 'failed_records': failed_records[:100] # فقط 100 مورد اول خطاها }, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def find_users_with_duplicate_national_id(request): users = SystemUserProfile.objects.filter( trash=False, national_id__isnull=False, role__name__in=['Guilds', 'Steward'] ).exclude(national_id__exact='').exclude(national_id__exact='0').distinct() national_id_dict = {} for user in users: nid = str(user.national_id).strip() if nid.isdigit() and len(nid) == 10: if nid not in national_id_dict: national_id_dict[nid] = [] national_id_dict[nid].append(user) result = [] for nid, user_list in national_id_dict.items(): if len(user_list) > 1: users_data = [] for user in user_list: users_data.append({ 'id': user.id, 'mobile': user.mobile, 'first_name': user.first_name, 'last_name': user.last_name, 'fullname': user.fullname, 'national_id': user.national_id }) result.append({ 'national_id': nid, 'count': len(user_list), 'users': users_data }) result.sort(key=lambda x: x['count'], reverse=True) total_duplicate = len(result) total_users = 0 for item in result: total_users += item['count'] return Response({ 'result': 'ok', 'total_duplicate_national_ids': total_duplicate, 'total_users_with_duplicate': total_users, 'duplicate_national_ids': result }, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def fix_duplicate_national_id_users(request): users = SystemUserProfile.objects.filter( trash=False, national_id__isnull=False, role__name__in=['Guilds', 'Steward'] ).exclude(national_id__exact='').exclude(national_id__exact='0') national_id_dict = {} for user in users: nid = str(user.national_id).strip() if nid.isdigit() and len(nid) == 10: if nid not in national_id_dict: national_id_dict[nid] = [] national_id_dict[nid].append(user) duplicate_national_ids = {} for nid, user_list in national_id_dict.items(): if len(user_list) > 1: duplicate_national_ids[nid] = user_list all_cities_cache = list(City.objects.filter(trash=False).values('id', 'name')) def _normalize_fa_ar(text): if not text: return text mapping = { 'ك': 'ک', 'ي': 'ی', 'ى': 'ی', '\u0649': 'ی', '\u06CC': 'ی', '\u064A': 'ی', 'ۀ': 'ه', 'ة': 'ه', 'ؤ': 'و', 'أ': 'ا', 'إ': 'ا', 'ٱ': 'ا', '\u200c': ' ', } out = str(text) for src, dst in mapping.items(): out = out.replace(src, dst) return out.strip() def parse_yes_no(val): if isinstance(val, bool): return val if isinstance(val, str): x = False if val.strip() == 'خیر' else True return x return bool(val) def find_city(city_name): if not city_name: return None city = City.objects.filter(name__icontains=city_name, trash=False).first() if not city: normalized_city = _normalize_fa_ar(city_name) city = City.objects.filter(name__icontains=normalized_city, trash=False).first() if not city: alt_city = str(city_name or '') alt_city = alt_city.replace('ک', 'ك').replace('ی', 'ي') city = City.objects.filter(name__icontains=alt_city, trash=False).first() if not city: try: target = _normalize_fa_ar(city_name or '') best_id = None best_ratio = 0.0 for c in all_cities_cache: cand = _normalize_fa_ar(c.get('name', '') or '') ratio = difflib.SequenceMatcher(None, target, cand).ratio() if ratio > best_ratio: best_ratio = ratio best_id = c['id'] if best_id is not None and best_ratio >= 0.72: city = City.objects.filter(id=best_id, trash=False).first() except Exception: city = None return city def generate_random_mobile(): while True: random_num = ''.join([str(random.randint(0, 9)) for _ in range(9)]) mobile = '08' + random_num if not SystemUserProfile.objects.filter(mobile=mobile).exists(): try: check_response = requests.get( f"{ARTA_URL_CHECK_USER_EXISTS}?username={mobile}", verify=False ) if check_response.status_code == 200: return mobile except Exception: continue processed = [] failed = [] for national_id, user_list in duplicate_national_ids.items(): try: guild_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_id}&type=guild" ) guild_data = guild_response.json() if not guild_data.get('status') or not guild_data.get('data'): failed.append({ 'national_id': national_id, 'reason': 'اطلاعات صنفی یافت نشد' }) continue guild_list = guild_data.get('data', []) guild_info = None for g in guild_list: license_status_value = g.get('licenseStatus', '') if license_status_value and 'فعال' in license_status_value: guild_info = g break if not guild_info and guild_list: guild_info = guild_list[0] if not guild_info: failed.append({ 'national_id': national_id, 'reason': 'اطلاعات صنفی یافت نشد' }) continue guild_layer_two = guild_info.get('layerTwo', {}) mobile_from_api = guild_layer_two.get('mobilenumber') steward_from_api = guild_layer_two.get('steward', False) if isinstance(steward_from_api, str): steward_value = steward_from_api.strip().lower() in ('true', 'بله', '1', 'yes') else: steward_value = bool(steward_from_api) if not mobile_from_api: failed.append({ 'national_id': national_id, 'reason': 'شماره موبایل در API یافت نشد' }) continue existing_user = SystemUserProfile.objects.filter( trash=False, mobile=mobile_from_api ).first() if existing_user: has_killhouse = existing_user.role.filter(name='KillHouse').exists() if not has_killhouse: person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person" ) person_data = person_response.json() if not person_data.get('status'): failed.append({ 'national_id': national_id, 'reason': 'اطلاعات شخص یافت نشد' }) continue person_info = person_data.get('data', {}) first_name = person_info.get('firstName') last_name = person_info.get('lastName') father_name = person_info.get('fatherName') gender = person_info.get('gender') identity_no = person_info.get('identityNo') is_alive = person_info.get('isLive', True) birth_date = person_info.get('birthDate') try: jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date() birthday_str = jalali_date.strftime("%Y-%m-%d") except Exception: birthday_str = None city_name = guild_info.get('city') city = find_city(city_name) existing_user.national_id = national_id existing_user.national_code = identity_no existing_user.first_name = first_name existing_user.last_name = last_name existing_user.fullname = f"{first_name} {last_name}".strip() existing_user.father_name = father_name existing_user.gender = gender if birthday_str: existing_user.birthday = birthday_str existing_user.is_alive = is_alive if city: existing_user.city = city existing_user.province = city.province existing_user.save() for user in user_list: has_killhouse = user.role.filter(name='KillHouse').exists() if user.id != existing_user.id: user_guilds = Guilds.objects.filter(trash=False, user=user) if user_guilds.exists(): user_guilds.update(active=False) has_killhouse = user.role.filter(name='KillHouse').exists() if not has_killhouse: random_mobile = generate_random_mobile() data = { "first_mobile_number": user.mobile, "second_mobile_number": random_mobile, } user.national_id = '0' req = requests.post( url=ARTA_URL_CHANGE_MOBILE_NUMBER, data=data, verify=False ) if req.status_code == 200: user.user.username = random_mobile user.user.save() user.mobile = random_mobile user.save() else: user_guilds = Guilds.objects.filter(trash=False, user=user) if user_guilds.exists(): user_guilds.update(active=False) user.national_id = '0' user.save() else: if has_killhouse: user_guilds = Guilds.objects.filter(trash=False, user=user) if user_guilds.exists(): user_guilds.update(active=False) user.national_id = '0' user.save() processed.append({ 'national_id': national_id, 'action': 'updated_existing_user', 'user_id': existing_user.id }) else: for user in user_list: has_killhouse = existing_user.role.filter(name='KillHouse').exists() if not has_killhouse: user.active = False user.save() user_guilds = Guilds.objects.filter(trash=False, user=user) user_guilds.update(active=False) person_response = requests.get( f"https://pay.rasadyar.net/national-documents?info={national_id}&type=person" ) person_data = person_response.json() if not person_data.get('status'): failed.append({ 'national_id': national_id, 'reason': 'اطلاعات شخص یافت نشد' }) continue person_info = person_data.get('data', {}) first_name = person_info.get('firstName') last_name = person_info.get('lastName') father_name = person_info.get('fatherName') gender = person_info.get('gender') identity_no = person_info.get('identityNo') is_alive = person_info.get('isLive', True) birth_date = person_info.get('birthDate') try: jalali_date = jdatetime.datetime.strptime(birth_date, "%Y/%m/%d").togregorian().date() birthday_str = jalali_date.strftime("%Y-%m-%d") except Exception: birthday_str = None city_name = guild_info.get('city') city = find_city(city_name) role_name = "Steward" if steward_value else "Guilds" password = '123456' register_payload = { "username": mobile_from_api, "first_name": first_name or "", "last_name": last_name or "", "password": password, "national_code": identity_no or '0', "role": role_name, "api_key": PROJECT_API_KEY } req = requests.post( url=ARTA_REGISTER, data=register_payload, verify=False ) if req.status_code == 200: hashed_password = hashlib.sha256(password.encode()).hexdigest() user = User.objects.filter(username=mobile_from_api).first() if not user: user = User( username=mobile_from_api, first_name=first_name or "", last_name=last_name or "", password=hashed_password ) user.save() base_id = SystemUserProfile.objects.all() if base_id.count() > 0: base_id = int(base_id.last().base_order) + 1 else: base_id = 1000 new_user = SystemUserProfile( mobile=mobile_from_api, first_name=first_name, last_name=last_name, fullname=f"{first_name} {last_name}".strip(), user=user, base_order=base_id, password=password, national_id=national_id, national_code=identity_no, father_name=father_name, gender=gender, birthday=birthday_str if birthday_str else str(datetime.datetime.now().date()), is_alive=is_alive, city=city, province=city.province if city else None ) new_user.save() if steward_value: group = Group.objects.get(name__exact="Steward") else: group = Group.objects.get(name__exact="Guilds") new_user.role.add(group) wallet = Wallet() wallet.save() address = SystemAddress( province=city.province if city else None, city=city, address=city_name or '' ) address.save() title = guild_info.get('title', f"{first_name} {last_name}".strip()) license_number = guild_info.get('licenseNumber', '') license_type = guild_info.get('licenseType', '') license_status = guild_info.get('licenseStatus', '') type_activity_name = guild_info.get('isicname', '') company_name = guild_info.get('corporationName', '') company_identifier = guild_info.get('nationalId', '') union_name = guild_info.get('unionName', '') phone = guild_layer_two.get('phonenumber', '') has_partner_val = guild_layer_two.get('hasPartner', False) is_foreigner_val = guild_layer_two.get('isForeigner', False) has_partner = parse_yes_no(has_partner_val) is_foreign_national = parse_yes_no(is_foreigner_val) from panel.models import TypeActivity, AreaActivity type_activity = TypeActivity.objects.filter(title__icontains=type_activity_name, trash=False).first() if not type_activity: type_activity = TypeActivity.objects.filter(trash=False).first() area_activity = AreaActivity.objects.filter(trash=False).first() new_guild = Guilds( user=new_user, guilds_name=title, license_number=license_number, license_type=license_type, license_status=license_status, is_foreign_national=is_foreign_national, has_partner=has_partner, has_inquiry=True, steward=steward_value, company_name=company_name, company_identifier=company_identifier, address=address, wallet=wallet, type_activity=type_activity.title if type_activity else type_activity_name, area_activity=area_activity.title if area_activity else '', guild_type_activity=type_activity, guild_area_activity=area_activity, union_name=union_name, phone_number=phone, active=True, province_accept_state='pending' ) new_guild.save() from panel.models import NewProduct, BroadcastPrice parent_product = NewProduct.objects.all().first() price = BroadcastPrice.objects.filter(trash=False).first() if parent_product and price: approved_price = price.steward_price if steward_value else price.guild_price approved_type = price.active if approved_price > 0 else False product = RolesProducts( parent_product=parent_product, guild=new_guild, name='مرغ گرم', approved_price_status=approved_type, approved_price=approved_price, ) product.save() processed.append({ 'national_id': national_id, 'action': 'created_new_user', 'user_id': new_user.id }) else: failed.append({ 'national_id': national_id, 'reason': 'خطا در ثبت کاربر در آرتا' }) except Exception as e: failed.append({ 'national_id': national_id, 'reason': f'خطا: {str(e)}' }) continue return Response({ 'result': 'ok', 'processed_count': len(processed), 'failed_count': len(failed), 'processed': processed, 'failed': failed }, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def fix_duplicate_guilds_steward_allocation(request): users_with_multiple_guilds = SystemUserProfile.objects.filter( trash=False, role__name__in=['Guilds', 'Steward'] ).annotate( guilds_count=Count('guilds_user', filter=Q(guilds_user__trash=False)) ).filter(guilds_count__gt=1) processed = [] failed = [] for user in users_with_multiple_guilds: try: user_guilds = Guilds.objects.filter( user=user, trash=False, ).order_by('-active', '-create_date') if user_guilds.count() <= 1: continue active_guild = user_guilds.filter(active=True).first() if not active_guild: continue inactive_guilds = user_guilds.exclude(id=active_guild.id).filter(active=False) if not inactive_guilds.exists(): continue allocations_to_move = StewardAllocation.objects.filter( trash=False ).filter( Q(guilds__in=inactive_guilds) | Q(to_guilds__in=inactive_guilds) | Q(to_steward__in=inactive_guilds) ) allocations_moved_count = 0 steward_updated = False for allocation in allocations_to_move: if allocation.guilds and allocation.guilds in inactive_guilds: allocation.guilds = active_guild if allocation.to_guilds and allocation.to_guilds in inactive_guilds: allocation.to_guilds = active_guild if allocation.to_steward and allocation.to_steward in inactive_guilds: allocation.to_steward = active_guild if not active_guild.steward: active_guild.steward = True active_guild.save() steward_updated = True allocation.save() allocations_moved_count += 1 if steward_updated: try: steward_group = Group.objects.get(name__exact="Steward") if not user.role.filter(id=steward_group.id).exists(): user.role.add(steward_group) except Group.DoesNotExist: pass pos_machines_to_move = POSMachine.objects.filter( trash=False, guild__in=inactive_guilds ) pos_machines_moved_count = 0 for pos_machine in pos_machines_to_move: pos_machine.guild = active_guild pos_machine.save() pos_machines_moved_count += 1 pos_segmentations_to_move = PosSegmentation.objects.filter( trash=False ).filter( Q(guild__in=inactive_guilds) | Q(to_guild__in=inactive_guilds) ) pos_segmentations_moved_count = 0 for pos_segmentation in pos_segmentations_to_move: if pos_segmentation.guild and pos_segmentation.guild in inactive_guilds: pos_segmentation.guild = active_guild if pos_segmentation.to_guild and pos_segmentation.to_guild in inactive_guilds: pos_segmentation.to_guild = active_guild pos_segmentation.save() pos_segmentations_moved_count += 1 roles_products_to_trash = RolesProducts.objects.filter( trash=False, guild__in=inactive_guilds ) roles_products_trashed_count = 0 for roles_product in roles_products_to_trash: roles_product.trash = True roles_product.save() roles_products_trashed_count += 1 for inactive_guild in inactive_guilds: inactive_guild.trash = True inactive_guild.save() active_guild_products = RolesProducts.objects.get( trash=False, guild=active_guild ) try: guild_steward_allocations_product_warehousing(active_guild_products) except Exception: pass processed.append({ 'user_id': user.id, 'user_mobile': user.mobile, 'user_national_id': user.national_id, 'active_guild_id': active_guild.id, 'active_guild_name': active_guild.guilds_name, 'inactive_guilds_count': inactive_guilds.count(), 'inactive_guild_ids': list(inactive_guilds.values_list('id', flat=True)), 'allocations_moved': allocations_moved_count, 'pos_machines_moved': pos_machines_moved_count, 'pos_segmentations_moved': pos_segmentations_moved_count, 'roles_products_trashed': roles_products_trashed_count }) except Exception as e: failed.append({ 'user_id': user.id, 'user_mobile': user.mobile, 'reason': f'خطا: {str(e)}' }) continue return Response({ 'result': 'ok', 'processed_count': len(processed), 'failed_count': len(failed), 'processed': processed, 'failed': failed }, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def fetch_evacuation_details_for_unknown_hatchings(request): hatchings = ( PoultryHatching.objects .filter( Q(unknown=True) | Q(state='pending', allow_hatching='pending', archive=False), trash=False, licence_number__isnull=False, ) ) licence_numbers = list(hatchings.values_list('licence_number', flat=True).distinct()) try: payload = {"codes": licence_numbers} external_response = requests.post( "http://rsibackend.rasadyaar.ir/app/get-evacuation-details-by-request-codes/", json=payload, ) external_response.raise_for_status() external_data = external_response.json() or {} except Exception as exc: return Response( {"result": f"خطا در ارتباط با سرویس تلفات: {str(exc)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) created_count = 0 updated_count = 0 skipped_no_data = 0 report_type_field_map = { 'تلفات ناشی از بیماری': 'total_disease_losses', 'معدوم سازی گله': 'total_flock_destruction', 'تلفات عادی گله': 'total_normal_flock_losses', 'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses', 'تلفات ناشی از آتش سوزی': 'total_fire_losses', } report_type_fields = list(set(report_type_field_map.values())) evacuation_detail_fields = [ 'PartIdCode', 'RequestId', 'MoReportId', 'ReportType', 'ReportTypeString', 'ReportDate', 'ReportDateShamsi', 'MoReason', 'MoDate', 'MoDateShamsi', 'MoStartDay', 'MoEndDay', 'MoReportSubId', 'ReportStatus', 'GoodCount', 'Message', 'ErrorCode', 'IsDeleted', 'RegDate', 'RegDateShamsi', 'RegDateShamsiWithTime', 'RegDateShamsiOnlyTime', 'ExternalId', 'StringId', 'IsPersisted', 'AllowInsert', 'AllowUpdate', 'ModalCss', 'GridContainerParametersModel', 'MenuUserAccess', 'MenuUserAccessId', 'LogTableName', 'LogTableAlias', 'PageTitle', ] def build_unique_key(detail_payload): external_id = detail_payload.get('ExternalId') if external_id: return f"external:{external_id}" string_id = detail_payload.get('StringId') if string_id: return f"string:{string_id}" return "fallback:" + "|".join( str(detail_payload.get(key) or '') for key in ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate') ) def normalize_good_count(value): if value in (None, ''): return None try: return int(value) except (TypeError, ValueError): try: return int(float(value)) except (TypeError, ValueError): return None def apply_evacuation_losses(instance): totals = {field: 0 for field in report_type_fields} detail_qs = instance.evacuation_details.filter(trash=False, IsDeleted=False) for detail in detail_qs: report_type = (detail.ReportTypeString or '').strip() field_name = report_type_field_map.get(report_type) if not field_name: continue totals[field_name] += detail.GoodCount or 0 for field, value in totals.items(): setattr(instance, field, value) hatching_map = {h.licence_number: h for h in hatchings} for code, details in external_data.items(): hatching = hatching_map.get(code) if not hatching: skipped_no_data += 1 continue if not isinstance(details, list) or not details: skipped_no_data += 1 continue seen_unique_keys = set() for detail in details: if not isinstance(detail, dict): continue detail_payload = {field: detail.get(field) for field in evacuation_detail_fields} detail_payload['GoodCount'] = normalize_good_count(detail_payload.get('GoodCount')) if not any(value not in (None, '') for value in detail_payload.values()): continue unique_key = build_unique_key(detail_payload) if unique_key in seen_unique_keys: continue seen_unique_keys.add(unique_key) external_id = detail_payload.get('ExternalId') string_id = detail_payload.get('StringId') lookup_kwargs = {'hatching': hatching} if external_id: lookup_kwargs['ExternalId'] = external_id elif string_id: lookup_kwargs['StringId'] = string_id else: lookup_key_fields = ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate') lookup_kwargs.update({field: detail_payload.get(field) for field in lookup_key_fields}) defaults = detail_payload.copy() defaults['hatching'] = hatching lookup_kwargs['trash'] = False obj, created = EvacuationHatchingDetail.objects.update_or_create( defaults=defaults, **lookup_kwargs, ) if created: created_count += 1 else: updated_count += 1 apply_evacuation_losses(hatching) hatching.save() return Response( { "result": "ثبت تلفات برای جوجه‌ریزی‌های unknown انجام شد.", "created_details": created_count, "updated_details": updated_count, "skipped_already_had_details": updated_count, "skipped_no_data": skipped_no_data, "processed_hatchings": len(licence_numbers), }, status=status.HTTP_200_OK, ) @api_view(["POST"]) @permission_classes([TokenHasReadWriteScope]) @csrf_exempt def upload_image_to_server_for_poultry_science(request): files = request.FILES.getlist('file') if not files: single_file = request.FILES.get('file') if single_file: files = [single_file] uploaded_urls = [] for idx, f in enumerate(files): now = datetime.datetime.now() name = now.strftime('%Y%m%d%H%M%S') name = f"{name}{idx}.jpg" url = send_image_to_server_for_poultry_science(f, name) uploaded_urls.append(url) return Response({ 'urls': uploaded_urls }, status=status.HTTP_200_OK) @api_view(["GET"]) @permission_classes([AllowAny]) @csrf_exempt def poultry_science_for_bazresi(request): query = PoultryScienceReport.objects.filter(trash=False).order_by('-id') value = request.GET.get('value') search = request.GET.get('search') if value and search == 'filter': if search != 'undefined' and search.strip(): query = query.filter( build_query(PoultryScienceReportFilterSet.Meta.fields, value) ) serializer = PoultryScienceReportSerializer(query, many=True) return Response(serializer.data, status=status.HTTP_200_OK) def archive_kill_house_remain_limitation_weight_manual(request): production_date = (datetime.datetime.now() - datetime.timedelta(days=3)).date() archive_date = (datetime.datetime.now() - datetime.timedelta(days=3)) kill_houses = KillHouse.objects.filter(trash=False, out_province=False) for kill_house in kill_houses: kill_house_requests = KillHouseRequest.objects.filter(input_warehouse=kill_house, province_request__poultry_request__free_sale_in_province=False, kill_request__recive_date__date=production_date, ware_house_confirmation=True, trash=False, calculate_status=True, warehouse=True) kill_house_allocations = StewardAllocation.objects.filter( kill_house=kill_house, trash=False, calculate_status=True, warehouse=True, system_registration_code=True, receiver_state__in=('pending', 'accepted'), production_date__date=production_date, quota='governmental') kill_house_free_sale_bars = KillHouseFreeSaleBarInformation.objects.filter(kill_house=kill_house, quota='governmental', production_date__date=production_date, trash=False, calculate_status=True, warehouse=True) segmentations = PosSegmentation.objects.filter(kill_house=kill_house, production_date__date=production_date, trash=False, warehouse=True, quota='governmental') kill_house_requests_weight = kill_house_requests.aggregate(total=Sum('ware_house_accepted_real_weight'))[ 'total'] or 0 kill_house_allocations_weight = \ kill_house_allocations.aggregate(total=Sum('real_weight_of_carcasses'))['total'] or 0 kill_house_free_sale_bars_weight = kill_house_free_sale_bars.aggregate(total=Sum('real_weight_of_carcasses'))[ 'total'] or 0 segmentation_weight = \ segmentations.aggregate(total=Sum('weight'))[ 'total'] or 0 archives = WarehouseArchive.objects.filter(kill_house=kill_house, date__date=production_date, quota='governmental', trash=False) archives_governmental_weight = \ archives.aggregate(total=Sum('weight'))[ 'total'] or 0 total_input = kill_house_requests_weight total_output = kill_house_allocations_weight + kill_house_free_sale_bars_weight + segmentation_weight + archives_governmental_weight total_remain = total_input - total_output if total_remain > 0: if kill_house.ware_house_remaining_weight_archive_percent > 0: percent_limitation_weight = total_input * (kill_house.ware_house_remaining_weight_archive_percent / 100) if percent_limitation_weight >= total_remain: archive = WarehouseArchive( kill_house=kill_house, date=archive_date, quota='governmental', weight=total_remain, registerer='سیستم', registerer_mobile='سیستم', registerer_role='سیستم', description='مانده کمتر از استاندارد تعیین شده', ) archive.save() kill_house_archive_warehousing(archive.kill_house) return HttpResponse('ok') def delete_steward_allocation_manual(request): current_time = datetime.datetime.now().date() # allow=AllowRegisterCodeForStewardAllocation.objects.filter(trash=False,active=True).first() # if allow: steward_allocation = StewardAllocation.objects.filter(trash=False, date__date=current_time, receiver_state='pending', active_expire_date_time=True, logged_registration_code__isnull=True, kill_house__isnull=False, return_trash=False).order_by('id') for allocation in steward_allocation: product = allocation.product seller_type = allocation.seller_type to_cold_house = allocation.to_cold_house other_cold_house = allocation.other_cold_house if allocation.other_cold_house else None allocation.trash = True allocation.save() if seller_type == 'KillHouse': kill_house_allocations_product_warehousing(product) if to_cold_house and to_cold_house.kill_house == product.kill_house: kill_house_cold_house_allocations(to_cold_house) elif seller_type == 'ColdHouse': cold_house_warehousing(to_cold_house) if other_cold_house: cold_house_warehousing(other_cold_house) else: guild_steward_allocations_product_warehousing(product) return HttpResponse('ok') def delete_sale_bar_manual(request): steward_sale_bar = StewardFreeSaleBarInformation.objects.filter(trash=False, logged_registration_code__isnull=True, system_registration_code=True, active_expire_date_time=True, registration_code__isnull=False) for free_sale_bar in steward_sale_bar: free_sale_bar.trash = True free_sale_bar.save() guild_steward_free_sale_product_warehousing(free_sale_bar.product) kill_house_sale_bar = KillHouseFreeSaleBarInformation.objects.filter(trash=False, logged_registration_code__isnull=True, system_registration_code=True, active_expire_date_time=True, registration_code__isnull=False) for free_sale_bar_kill_house in kill_house_sale_bar: product = free_sale_bar_kill_house.product free_sale_bar_kill_house.trash = True free_sale_bar_kill_house.save() kill_house_free_sale_product_warehousing(product) def send_credit_sahandsms_sms_manual(request): filters = {} if base_url_for_sms_report == 'ha': filters['username'] = 'hamedan' elif base_url_for_sms_report == 'ku': filters['username'] = 'kurdistan' elif base_url_for_sms_report == 'ma': filters['username__in'] = ['markazi', 'senfmarkazi'] managements = ManagementSendSms.objects.filter(**filters) \ .values('username') \ .annotate(min_id=Min('id')) \ .values_list('min_id', flat=True) managements = ManagementSendSms.objects.filter(id__in=managements) for management in managements: r = requests.get( f"http://webservice.sahandsms.com/newsmswebservice.asmx/GetUserCredit?username={management.username}" f"&password={management.password}") url = f'https://eitaayar.ir/api/{token}/sendMessage' date = datetime.datetime.now().date() if base_url_for_sms_report == 'ma': province = 'مرکزی' elif base_url_for_sms_report == 'ha': province = 'همدان' elif base_url_for_sms_report == 'ku': province = 'کردستان' elif base_url_for_sms_report == 'bu': province = 'بوشهر' else: province = 'تست' date_shamsi = shamsi_date(date).replace('-', '_') base_message = '🗓📢❗ سامانه رصدیار، زنجیره تامین،تولید و توزیع مرغ گوشتی📢❗\n' base_message += f' #گزارش_مانده_حساب_پنل_پیامکی #{date_shamsi}\n' base_message += f' #استان_{province}\n\n' base_message += f'➖➖➖➖➖➖➖➖➖➖\n' messages = [] current_message = base_message root = ET.fromstring(r.content) credit_amount = int(root.text) amount = "{:,}".format(credit_amount) new_message_part = "🔸 نام کاربری پنل : {0} \n".format(management.username) new_message_part += "🔸 مانده حساب پنل : {0} ریال \n".format(amount) # new_message_part = "🔸 نام کاربری پنل {0}: {1} ریال \n".format(management.username, amount) if credit_amount < 1000000: new_message_part += "‼توجه: لطفا برای شارژ پنل پیامکی خود اقدام فرمایید‼" new_message_part += '\n➖➖➖➖➖➖➖➖➖➖\n' if len(current_message) + len(new_message_part) > 4000: messages.append(current_message) current_message = base_message current_message += new_message_part if current_message and current_message != base_message: messages.append(current_message) for message in messages: data = { 'chat_id': chat_id_mali, 'text': message, } response = requests.post(url, data=data, verify=False) return HttpResponse('ok')