9339 lines
434 KiB
Python
9339 lines
434 KiB
Python
import datetime
|
||
import hashlib
|
||
import random
|
||
import re
|
||
import difflib
|
||
from collections import defaultdict, Counter
|
||
from datetime import timedelta
|
||
from io import BytesIO
|
||
import xml.etree.ElementTree as ET
|
||
|
||
import jdatetime
|
||
import openpyxl
|
||
import requests
|
||
from bs4 import BeautifulSoup
|
||
from dateutil.relativedelta import relativedelta
|
||
from django.contrib.auth.models import User, Group
|
||
from django.db.models import Q, F, Sum, Avg, Count, Min
|
||
from django.http import HttpResponse
|
||
from django.http import QueryDict, JsonResponse
|
||
from django.views.decorators.csrf import csrf_exempt
|
||
from oauth2_provider.contrib.rest_framework.permissions import TokenHasReadWriteScope
|
||
from oauth2_provider.models import AccessToken
|
||
from openpyxl import Workbook
|
||
from openpyxl.styles import Alignment
|
||
from requests.adapters import HTTPAdapter
|
||
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
|
||
from rest_framework import status
|
||
from rest_framework import viewsets
|
||
from rest_framework.decorators import api_view, permission_classes
|
||
from rest_framework.pagination import PageNumberPagination
|
||
from rest_framework.permissions import AllowAny
|
||
from rest_framework.response import Response
|
||
from url_filter.integrations.drf import DjangoFilterBackend
|
||
from LiveStock.helpers import build_query
|
||
from panel.ProvinceOperator.serializers import PoultryScienceReportSerializer
|
||
from panel.filterset import PoultryScienceReportFilterSet
|
||
from authentication.filterset import (
|
||
SystemUserProfileFilteSet
|
||
)
|
||
from authentication.models import SystemUserProfile, Province, SystemAddress, City
|
||
from authentication.register import ARTA_REGISTER
|
||
from authentication.sahandsms.sms import USERNAME_SMS_FINANCIAL, PASSWORD_SMS_FINANCIAL, kill_house_price
|
||
from authentication.serializer.serializer import SystemUserProfileSerializer
|
||
from authentication.sms_management import send_sms_for_kill_house_not_add_to_inventory, send_sms_for_guild, \
|
||
send_sms_for_guild_for_register, steward_allocation_sms, guild_register_password, guild_register_username, \
|
||
send_sms_for_sale_bar_for_steward, send_sms_for_sale_bar, send_sms_request
|
||
from authentication.views import ARTA_URL_CHANGE_MOBILE_NUMBER
|
||
|
||
ARTA_URL_CHECK_USER_EXISTS = "https://userbackend.rasadyar.com/api/check_user_exists/"
|
||
from general_urls import base_url_for_sms_report
|
||
from helper_eata import chat_id_mali, token
|
||
from panel.ProvinceOperator.serializers import \
|
||
NewProvinceAutoAllocationSerializer, GuildsSerializer
|
||
from panel.ProvinceOperator.helpers import guild_steward_allocations_product_warehousing
|
||
from panel.KillHouse.helpers import kill_house_allocations_product_warehousing, kill_house_archive_warehousing
|
||
from panel.ReportingPanel.filterset import (
|
||
PoultryRequestFilterSet,
|
||
KillHouseRequestFilterSet,
|
||
CityOperatorCheckFilterSet,
|
||
ProvinceOperatorCheckFilterSet,
|
||
VetOperatorCheckFilterSet,
|
||
PoultryHatchingFilterSet, PoultryFilterSet, UserProfileFilterSet
|
||
)
|
||
from panel.ReportingPanel.models import SearchFields
|
||
from panel.models import (
|
||
PoultryRequest,
|
||
KillHouseRequest,
|
||
CityOperatorCheckRequest,
|
||
ProvinceCheckOperatorRequest,
|
||
VetCheckRequest,
|
||
Poultry,
|
||
PoultryHatching, ProvinceKillRequest, ProvinceFactorToKillHouse, KillHouseAssignmentInformation,
|
||
KillHouseFactorToProvince, PovinceInspector, CityOperator, ProvinceOperator, VetFarm, KillHouseVet,
|
||
ProvinceAutoAllocation, KillHouse, IranProvinces, IranCities, AgeNotificationPoultry, CookieSamasat, LastUpdate,
|
||
Wallet, KillHouseFreeSaleBarInformation, KillRequest, KillHouseFreeBarInformation, ChickenCommissionPrices,
|
||
RolesProducts, ColdHouse, StewardAllocation, ProductsTransactions, PosMachineTransactions, POSMachine, Guilds,
|
||
PosSegmentation,
|
||
PoultryRequestQuarantineCode, ChainAllocation, ManagementSendSms, StewardFreeSaleBarInformation, POSTransactions,
|
||
SmsRecipient, EvacuationHatchingDetail, HatchingLossManagement, ChickenAgeRange, PoultryScience,
|
||
PoultryScienceReport, WarehouseArchive
|
||
)
|
||
from ticket.helper import send_image_to_server_for_poultry_science
|
||
from panel.poultry.serializers import (
|
||
PoultryRequestSerializer,
|
||
PoultrySerializer,
|
||
PoultryHatchingSerializer, PoultryRequestForGeneralCasestatusSerializer,
|
||
ChickenCommissionPricesForDashboardSerializer
|
||
)
|
||
from ticket.models import MessageSupport, TicketSupport
|
||
from .helper import (
|
||
poultry_request_fields,
|
||
user_fields,
|
||
city_operator_fields,
|
||
province_operator_fields,
|
||
kill_house_operator_fields,
|
||
vet_operator_fields,
|
||
poultry_hatching_fields, poultry_filterset_fields, poultry_hatching_filterset_fields
|
||
)
|
||
from .serializer import SearchFieldsSerializer, DetailsGeneraWageSerializer, GenaeralWageSerailizer, \
|
||
DashboardDetailsGeneraWageSerializer, NewDetailsGeneraWageSerializer, IranProvinceSerializer, IranCitiesSerializer, \
|
||
AgeNotificationPoultrySerilizer, CookieSamasatSerilizer, HatchingLossManagementSerializer
|
||
from ..KillHouse.helpers import kill_house_allocations_product_warehousing, market_poultry_request_remain_quantity, \
|
||
kill_house_cold_house_allocations, cold_house_warehousing, kill_house_free_buying_product_warehousing, \
|
||
kill_house_free_sale_product_warehousing
|
||
from ..ProvinceOperator.helpers import guild_steward_allocations_product_warehousing, \
|
||
guild_steward_free_sale_product_warehousing
|
||
from ..admin import PROJECT_API_KEY
|
||
from ..convert_date import convert_to_miladi
|
||
from ..helper_excel import percent_of_losses, create_value, create_header, create_header_freez, shamsi_date, \
|
||
excel_description, to_locale_str, convert_str_to_date
|
||
from ..helper import check_mobile_number
|
||
from ..validate_headers import PosDeviceValidator
|
||
|
||
|
||
def check_quarantine_code(code):
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
data = {'gid': str(code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
try:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
if date_match:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
return True
|
||
except:
|
||
return False
|
||
|
||
|
||
class CustomPagination(PageNumberPagination):
|
||
page_size = 10
|
||
|
||
|
||
class ReportingAllPoultryRequests(viewsets.ModelViewSet):
|
||
queryset = PoultryRequest.objects.all()
|
||
city_queryset = CityOperatorCheckRequest.objects.all()
|
||
province_queryset = ProvinceCheckOperatorRequest.objects.all()
|
||
kill_house_queryset = KillHouseRequest.objects.all()
|
||
vet_queryset = VetCheckRequest.objects.all()
|
||
poultry_hatching_queryset = PoultryHatching.objects.all()
|
||
serializer_class = PoultryRequestSerializer
|
||
permission_classes = [AllowAny]
|
||
filter_backends = [DjangoFilterBackend]
|
||
filterset_class = PoultryRequestFilterSet
|
||
kill_house_filter_class = KillHouseRequestFilterSet
|
||
city_operator_filter_class = CityOperatorCheckFilterSet
|
||
province_operator_filter_class = ProvinceOperatorCheckFilterSet
|
||
vet_operator_filter_class = VetOperatorCheckFilterSet
|
||
poultry_hatching_filter_class = PoultryHatchingFilterSet
|
||
filterset_fields = poultry_request_fields
|
||
user_filterset_fields = user_fields
|
||
city_operator_filter_fields = city_operator_fields
|
||
province_operator_filter_fields = province_operator_fields
|
||
kill_house_operator_filter_fields = kill_house_operator_fields
|
||
vet_operator_filter_fields = vet_operator_fields
|
||
poultry_hatching_filter_fields = poultry_hatching_fields
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
# refresh(request.user.id)
|
||
|
||
query_val = []
|
||
city_operator_query_val = []
|
||
province_operator_query_val = []
|
||
kill_house_operator_query_val = []
|
||
vet_operator_query_val = []
|
||
poultry_hatching_query_val = []
|
||
user_val = []
|
||
poultry_query_li = []
|
||
hatching_poultry_li = []
|
||
limited_query = []
|
||
city_limited_query = []
|
||
province_limited_query = []
|
||
kill_house_limited_query = []
|
||
vet_limited_query = []
|
||
poultry_hatching_limited_query = []
|
||
limited_dict = {}
|
||
province_limited_dict = {}
|
||
city_limited_dict = {}
|
||
kill_house_limited_dict = {}
|
||
vet_limited_dict = {}
|
||
poultry_hatching_limited_dict = {}
|
||
user_query = []
|
||
user_dict = {}
|
||
values_item = []
|
||
total_tons = []
|
||
if 'type' in request.GET:
|
||
if request.GET['value'] != "":
|
||
if request.GET['type'] == 'filter':
|
||
if 'value' in request.GET:
|
||
values = request.GET['value'].split(',')
|
||
for item in values:
|
||
if item != "":
|
||
values_item.append(item)
|
||
for val in values_item:
|
||
if not query_val:
|
||
for item in self.filterset_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.filterset_class(data=query, queryset=self.queryset)).filter():
|
||
ps = self.filterset_class(data=query, queryset=self.queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
limited_query.append(query)
|
||
|
||
if not city_operator_query_val:
|
||
for item in self.city_operator_filter_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (
|
||
self.city_operator_filter_class(data=query,
|
||
queryset=self.city_queryset)).filter():
|
||
ps = self.city_operator_filter_class(data=query, queryset=self.city_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
city_limited_query.append(query)
|
||
|
||
if not province_operator_query_val:
|
||
for item in self.province_operator_filter_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.city_operator_filter_class(data=query,
|
||
queryset=self.province_queryset)).filter():
|
||
ps = self.city_operator_filter_class(data=query,
|
||
queryset=self.province_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
province_limited_query.append(query)
|
||
|
||
if not kill_house_operator_query_val:
|
||
for item in self.kill_house_operator_filter_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.kill_house_filter_class(data=query,
|
||
queryset=self.kill_house_queryset)).filter():
|
||
ps = self.kill_house_filter_class(data=query, queryset=self.kill_house_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
kill_house_limited_query.append(query)
|
||
|
||
if not vet_operator_query_val:
|
||
for item in self.vet_operator_filter_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (
|
||
self.vet_operator_filter_class(data=query,
|
||
queryset=self.vet_queryset)).filter():
|
||
ps = self.vet_operator_filter_class(data=query, queryset=self.vet_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
vet_limited_query.append(query)
|
||
|
||
if not poultry_hatching_query_val:
|
||
for item in self.poultry_hatching_filter_fields:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.poultry_hatching_filter_class(data=query,
|
||
queryset=self.poultry_hatching_queryset)).filter():
|
||
ps = self.poultry_hatching_filter_class(data=query,
|
||
queryset=self.poultry_hatching_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
poultry_hatching_limited_query.append(query)
|
||
|
||
if not user_val:
|
||
for user_item in self.user_filterset_fields:
|
||
query = QueryDict('{0}__exact={1}'.format(user_item, val))
|
||
if (SystemUserProfileFilteSet(
|
||
data=query,
|
||
queryset=SystemUserProfile.objects.all())
|
||
).filter():
|
||
ps = SystemUserProfileFilteSet(
|
||
data=query,
|
||
queryset=SystemUserProfile.objects.all()
|
||
)
|
||
filtered_poultry_user = ps.filter()
|
||
if filtered_poultry_user:
|
||
user_query.append(query)
|
||
|
||
for i in limited_query:
|
||
for key, value in i.items():
|
||
limited_dict[key] = value
|
||
if len(values_item) != len(limited_dict):
|
||
pass
|
||
else:
|
||
for i in PoultryRequest.objects.filter(**limited_dict):
|
||
query_val.append(i)
|
||
|
||
for i in city_limited_query:
|
||
for key, value in i.items():
|
||
city_limited_dict[key] = value
|
||
if len(values_item) != len(city_limited_dict):
|
||
pass
|
||
else:
|
||
for i in self.city_queryset.filter(**city_limited_dict):
|
||
query_val.append(i.poultry_request)
|
||
|
||
for i in province_limited_query:
|
||
for key, value in i.items():
|
||
province_limited_dict[key] = value
|
||
if len(values_item) != len(province_limited_dict):
|
||
pass
|
||
else:
|
||
for i in self.province_queryset.filter(**province_limited_dict):
|
||
query_val.append(i.city_request_Poultry.poultry_request)
|
||
|
||
for i in kill_house_limited_query:
|
||
for key, value in i.items():
|
||
kill_house_limited_dict[key] = value
|
||
if len(values_item) != len(kill_house_limited_dict):
|
||
pass
|
||
else:
|
||
for i in self.kill_house_queryset.filter(**kill_house_limited_dict):
|
||
query_val.append(i.province_request.city_request_Poultry.poultry_request)
|
||
|
||
for i in vet_limited_query:
|
||
for key, value in i.items():
|
||
vet_limited_dict[key] = value
|
||
if len(values_item) != len(vet_limited_dict):
|
||
pass
|
||
else:
|
||
for i in self.vet_queryset.filter(**vet_limited_dict):
|
||
query_val.append(
|
||
i.kill_house_request.province_request.city_request_Poultry.poultry_request)
|
||
|
||
for i in poultry_hatching_limited_query:
|
||
for key, value in i.items():
|
||
poultry_hatching_limited_dict[key] = value
|
||
if len(values_item) != len(poultry_hatching_limited_dict):
|
||
pass
|
||
else:
|
||
for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict):
|
||
poultry_query_li.append(i.poultry)
|
||
hatching_poultry_li.append(i)
|
||
|
||
for i in user_query:
|
||
for key, value in i.items():
|
||
user_dict[key] = value
|
||
if len(values_item) != len(user_dict):
|
||
pass
|
||
else:
|
||
for i in SystemUserProfile.objects.filter(**user_dict):
|
||
user_val.append(i)
|
||
|
||
if 'hatching_date' in request.GET:
|
||
date_li = []
|
||
query_li = []
|
||
if request.GET['hatching_date'] != "":
|
||
date = request.GET['hatching_date'].split(',')
|
||
date_split_1 = date[0].split('-')
|
||
date_split_2 = date[1].split('-')
|
||
main_date_1 = datetime.datetime(
|
||
int(date_split_1[0]),
|
||
int(date_split_1[1]),
|
||
int(date_split_1[2])
|
||
)
|
||
main_date_2 = datetime.datetime(
|
||
int(date_split_2[0]),
|
||
int(date_split_2[1]),
|
||
int(date_split_2[2])
|
||
)
|
||
date_li.append(main_date_1)
|
||
date_li.append(main_date_2)
|
||
for i in PoultryHatching.objects.all():
|
||
if date_li[0] <= i.date <= date_li[1]:
|
||
if i.poultry not in poultry_query_li:
|
||
poultry_query_li.append(i.poultry)
|
||
|
||
if 'hatching_info' in request.GET:
|
||
serializer = PoultryHatchingSerializer(hatching_poultry_li, many=True)
|
||
data = {'hatching_info': serializer.data}
|
||
return Response(data, status=status.HTTP_200_OK)
|
||
|
||
if 'number_of_incubators' in request.GET:
|
||
if request.GET['number_of_incubators'] != "":
|
||
num = request.GET['number_of_incubators'].split(',')
|
||
for i in PoultryHatching.objects.all():
|
||
if int(num[0]) <= int(i.quantity) <= int(num[1]):
|
||
if i.poultry not in poultry_query_li:
|
||
poultry_query_li.append(i.poultry)
|
||
|
||
if 'number_of_requests' in request.GET:
|
||
if request.GET['number_of_requests'] != "":
|
||
num = request.GET['number_of_requests'].split(',')
|
||
for i in Poultry.objects.all():
|
||
if int(num[0]) <= int(i.number_of_requests) <= int(num[1]):
|
||
if i not in poultry_query_li:
|
||
poultry_query_li.append(i)
|
||
|
||
if 'total_capacity' in request.GET:
|
||
if request.GET['total_capacity'] != "":
|
||
num = request.GET['total_capacity'].split(',')
|
||
for i in Poultry.objects.all():
|
||
if int(num[0]) <= int(i.total_capacity) <= int(num[1]):
|
||
if i not in poultry_query_li:
|
||
poultry_query_li.append(i)
|
||
|
||
if 'tons_for_slaughter' in request.GET:
|
||
total = 0
|
||
total_li = []
|
||
if request.GET['tons_for_slaughter'] != "":
|
||
tons_date = request.GET['tons_for_slaughter']
|
||
date_split = tons_date.split('-')
|
||
main_date = (jdatetime.datetime(
|
||
int(date_split[0]), int(date_split[1]),
|
||
int(date_split[2])).togregorian())
|
||
for item in self.queryset:
|
||
if item.send_date.strftime("%Y-%m-%d") == main_date.strftime("%Y-%m-%d"):
|
||
total += item.quantity
|
||
total_li.append(item)
|
||
serializer = self.serializer_class(total_li, many=True)
|
||
return Response({'poultry_req': serializer.data, 'total_quantity': total})
|
||
|
||
if 'total_tons_in_date' in request.GET:
|
||
if request.GET['total_tons_in_date'] != "":
|
||
age_li = []
|
||
total_tons_split = request.GET['total_tons_in_date'].split(',')
|
||
total = 0
|
||
splited_date = total_tons_split[0].split('-')
|
||
date1 = jdatetime.date(
|
||
int(splited_date[0]),
|
||
int(splited_date[1]),
|
||
int(splited_date[2])
|
||
).togregorian()
|
||
for item in PoultryHatching.objects.all():
|
||
if item.date != None:
|
||
date2 = datetime.date(
|
||
int(item.date.year),
|
||
int(item.date.month),
|
||
int(item.date.day),
|
||
)
|
||
age = (date1 - date2)
|
||
if 48 >= age.days >= int(total_tons_split[1]):
|
||
total += item.quantity
|
||
total_tons.append(item.poultry)
|
||
age_li.append(age.days)
|
||
|
||
if 'show' in request.GET:
|
||
if request.GET['show'] == 'active':
|
||
poultry_req = self.queryset.filter(final_state="pending")
|
||
serializer = self.serializer_class(poultry_req, many=True)
|
||
return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)
|
||
if request.GET['show'] == "deactive":
|
||
poultry_req = self.queryset.filter(final_state="complete")
|
||
serializer = self.serializer_class(poultry_req, many=True)
|
||
return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)
|
||
if request.GET['show'] == "all":
|
||
poultry_req = self.queryset
|
||
serializer = self.serializer_class(poultry_req, many=True)
|
||
return Response({'poultry_req': serializer.data}, status=status.HTTP_200_OK)
|
||
|
||
serializer = self.serializer_class(query_val, many=True)
|
||
user_serializer = SystemUserProfileSerializer(user_val, many=True)
|
||
poultry_serializer = PoultrySerializer(poultry_query_li, many=True)
|
||
final_output_data = {
|
||
'poultry_req': serializer.data,
|
||
'poultry': poultry_serializer.data,
|
||
'user_detail': user_serializer.data,
|
||
}
|
||
return Response(final_output_data, status=status.HTTP_200_OK)
|
||
|
||
serializer = PoultryRequestSerializer(
|
||
self.queryset.filter(send_date=(datetime.datetime.now() - datetime.timedelta(days=1))),
|
||
many=True
|
||
)
|
||
data = {'poultry_req': serializer.data}
|
||
return Response(data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class SearchFieldsViewSet(viewsets.ModelViewSet):
|
||
queryset = SearchFields.objects.all()
|
||
serializer_class = SearchFieldsSerializer
|
||
permission_classes = [TokenHasReadWriteScope]
|
||
|
||
|
||
class NewReportingAllPoultryRequests(viewsets.ModelViewSet):
|
||
userprofile_queryset = SystemUserProfile.objects.all()
|
||
userprofile_serializer_class = SystemUserProfileSerializer
|
||
userprofile_filterset_class = UserProfileFilterSet
|
||
queryset = Poultry.objects.all()
|
||
serializer_class = PoultrySerializer
|
||
permission_classes = [TokenHasReadWriteScope]
|
||
filter_backends = [DjangoFilterBackend]
|
||
filterset_class = PoultryFilterSet
|
||
poultry_filterset_f = poultry_filterset_fields
|
||
poultry_hatching_queryset = PoultryHatching.objects.all()
|
||
poultry_hatching_filter_class = PoultryHatchingFilterSet
|
||
poultry_hatching_filterset_f = poultry_hatching_filterset_fields
|
||
poultry_hatching_serializer_class = PoultryHatchingSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
# refresh(request.user.id)
|
||
|
||
query_val = []
|
||
poultry_hatching_query_val = []
|
||
limited_dict = {}
|
||
values_item = []
|
||
limited_query = []
|
||
poultry_hatching_limited_query = []
|
||
poultry_hatching_limited_dict = {}
|
||
|
||
if request.GET['type'] == 'filter':
|
||
if 'value' in request.GET and request.GET['value'] != "":
|
||
values = request.GET['value'].split(',')
|
||
for item in values:
|
||
if item != "":
|
||
values_item.append(item)
|
||
for val in values_item:
|
||
if not query_val:
|
||
for item in self.poultry_filterset_f:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.filterset_class(data=query, queryset=self.queryset)).filter():
|
||
ps = self.filterset_class(data=query, queryset=self.queryset)
|
||
filtered_poultry = ps.filter()
|
||
if filtered_poultry:
|
||
limited_query.append(query)
|
||
|
||
if not poultry_hatching_query_val:
|
||
for item in self.poultry_hatching_filterset_f:
|
||
query = QueryDict('{0}={1}'.format(item, val))
|
||
if (self.poultry_hatching_filter_class(data=query,
|
||
queryset=self.poultry_hatching_queryset)).filter():
|
||
ps = self.poultry_hatching_filter_class(data=query,
|
||
queryset=self.poultry_hatching_queryset)
|
||
filtered_city_operator = ps.filter()
|
||
if filtered_city_operator:
|
||
poultry_hatching_limited_query.append(query)
|
||
for i in limited_query:
|
||
for key, value in i.items():
|
||
limited_dict[key] = value
|
||
#
|
||
# if len(values_item) != len(limited_dict):
|
||
# pass
|
||
# else:
|
||
|
||
if len(limited_dict) > 0:
|
||
for i in Poultry.objects.filter(**limited_dict):
|
||
query_val.append(i)
|
||
for i in poultry_hatching_limited_query:
|
||
for key, value in i.items():
|
||
poultry_hatching_limited_dict[key] = value
|
||
|
||
# if len(values_item) == len(poultry_hatching_limited_dict):
|
||
# pass
|
||
# else:
|
||
for i in self.poultry_hatching_queryset.filter(**poultry_hatching_limited_dict):
|
||
if i.poultry in query_val:
|
||
pass
|
||
else:
|
||
if len(limited_dict) > 0:
|
||
pass
|
||
else:
|
||
query_val.append(i.poultry)
|
||
values_item_count = len(values_item)
|
||
if values_item_count != len(limited_dict):
|
||
if len(poultry_hatching_limited_dict) == 0:
|
||
query_val = []
|
||
|
||
if 'double_hatching_date' in request.GET:
|
||
date_li = []
|
||
query_li = []
|
||
if request.GET['double_hatching_date'] != "":
|
||
date = request.GET['double_hatching_date'].split(',')
|
||
date_split_1 = date[0].split('-')
|
||
date_split_2 = date[1].split('-')
|
||
main_date_1 = datetime.datetime(
|
||
int(date_split_1[0]),
|
||
int(date_split_1[1]),
|
||
int(date_split_1[2])
|
||
)
|
||
main_date_2 = datetime.datetime(
|
||
int(date_split_2[0]),
|
||
int(date_split_2[1]),
|
||
int(date_split_2[2])
|
||
)
|
||
date_li.append(main_date_1)
|
||
date_li.append(main_date_2)
|
||
for i in PoultryHatching.objects.all():
|
||
if date_li[0].year <= i.date.year and date_li[0].month <= i.date.month and date_li[
|
||
0].day <= i.date.day and i.date.year <= date_li[1].year and i.date.month <= date_li[
|
||
1].month and i.date.day <= date_li[1].day:
|
||
if i.poultry not in query_val:
|
||
query_val.append(i.poultry)
|
||
if 'single_hatching_date' in request.GET:
|
||
date_li = []
|
||
query_li = []
|
||
if request.GET['single_hatching_date'] != "":
|
||
date = request.GET['single_hatching_date']
|
||
date_split = date.split('-')
|
||
main_date = datetime.datetime(
|
||
int(date_split[0]),
|
||
int(date_split[1]),
|
||
int(date_split[2])
|
||
)
|
||
date_li.append(main_date)
|
||
for i in PoultryHatching.objects.all():
|
||
if date_li[0].year == i.date.year and date_li[0].month == i.date.month and date_li[
|
||
0].day == i.date.day:
|
||
if i.poultry not in query_val:
|
||
query_val.append(i.poultry)
|
||
if 'double_age' in request.GET:
|
||
age = request.GET['double_age'].split(',')
|
||
age1 = int(age[0])
|
||
age2 = int(age[1])
|
||
hatching = PoultryHatching.objects.filter(state='pending')
|
||
if hatching.count() > 0:
|
||
for hatch in hatching:
|
||
chicken_age = (datetime.datetime.now() - hatch.date).days + 1
|
||
if age1 <= chicken_age and chicken_age <= age2:
|
||
if hatch.poultry in query_val:
|
||
pass
|
||
else:
|
||
query_val.append(hatch.poultry)
|
||
if 'single_age' in request.GET:
|
||
age = int(request.GET['single_age'])
|
||
hatching = PoultryHatching.objects.filter(state='pending')
|
||
if hatching.count() > 0:
|
||
for hatch in hatching:
|
||
chicken_age = (datetime.datetime.now() - hatch.date).days + 1
|
||
if age == chicken_age:
|
||
if hatch.poultry in query_val:
|
||
pass
|
||
else:
|
||
query_val.append(hatch.poultry)
|
||
|
||
serializer = self.serializer_class(query_val, many=True)
|
||
|
||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class ForcastViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryHatching.objects.all()
|
||
permission_classes = [TokenHasReadWriteScope]
|
||
serializer_class = PoultryHatchingSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
# refresh(request.user.id)
|
||
|
||
user = SystemUserProfile.objects.get(user=request.user)
|
||
from datetime import datetime, timedelta
|
||
date1 = datetime.strptime(request.GET['date1'], '%Y-%m-%d')
|
||
date2 = datetime.strptime(request.GET['date2'], '%Y-%m-%d')
|
||
d = request.GET['day']
|
||
days_interval = (date2 - date1).days
|
||
hatching_dict = {}
|
||
quantity = 0
|
||
poultry_list_id = []
|
||
poultry_list = []
|
||
interal_dict = {}
|
||
final_list = []
|
||
hatchs = PoultryHatching.objects.filter(poultry__address__province=user.province, state='pending')
|
||
if hatchs.count() > 0:
|
||
for i in range(days_interval + 1):
|
||
first_date = date1 + timedelta(days=i)
|
||
second_date = first_date - timedelta(days=int(d))
|
||
for hatch in hatchs:
|
||
if hatch.date.year == second_date.year and hatch.date.month == second_date.month and hatch.date.day == second_date.day:
|
||
quantity += hatch.quantity
|
||
if hatch.poultry in poultry_list:
|
||
pass
|
||
else:
|
||
poultry_list.append(hatch.poultry)
|
||
for p in poultry_list:
|
||
interal_dict = {
|
||
"name": p.user.fullname,
|
||
"mobile": p.user.mobile,
|
||
"unitname": p.unit_name,
|
||
"province": p.user.province.name,
|
||
"city": p.user.city.name,
|
||
}
|
||
poultry_list_id.append(interal_dict)
|
||
|
||
hatching_dict.update({"date": str(first_date), "quantity": quantity, "poultry": poultry_list_id})
|
||
quantity = 0
|
||
final_list.append(hatching_dict)
|
||
hatching_dict = {}
|
||
poultry_list_id = []
|
||
poultry_list = []
|
||
|
||
return Response(final_list, status=status.HTTP_200_OK)
|
||
|
||
|
||
class PoultryReporttViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryHatching.objects.all()
|
||
permission_classes = [TokenHasReadWriteScope]
|
||
serializer_class = PoultryHatchingSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
# refresh(request.user.id)
|
||
user = SystemUserProfile.objects.get(user=request.user)
|
||
poultry_request_list = []
|
||
dates = []
|
||
hatching_list = []
|
||
average_weight_chart_list = []
|
||
quantity = 0
|
||
losses = 0
|
||
poultry_requests = PoultryRequest.objects.filter(poultry__user=user, trash=False).order_by('send_date')
|
||
if poultry_requests.count() > 0:
|
||
for poultry_request in poultry_requests:
|
||
total_amount = 0
|
||
average_weight = 0
|
||
average_fee = 0
|
||
sales_price = 0
|
||
paid_state = None
|
||
if ProvinceKillRequest.objects.filter(
|
||
province_request__city_request_Poultry__poultry_request=poultry_request,
|
||
state='accepted').exists():
|
||
age = (poultry_request.send_date - poultry_request.hatching.date).days + 1
|
||
else:
|
||
age = (datetime.datetime.now() - poultry_request.hatching.date).days + 1
|
||
poultry_request_dict = {
|
||
"hatching_period": poultry_request.hatching.period,
|
||
"date": poultry_request.send_date.date(),
|
||
"hatching_date": poultry_request.hatching.date,
|
||
"hatching_chicken_breed": poultry_request.hatching.chicken_breed,
|
||
"quantity": poultry_request.quantity,
|
||
"age": age,
|
||
"weight_of_suffering": 2.5,
|
||
"request_id": poultry_request.id,
|
||
|
||
}
|
||
province_factors = ProvinceFactorToKillHouse.objects.filter(
|
||
province_check_req__poultry_request=poultry_request)
|
||
if province_factors.count() > 0:
|
||
factor_count = province_factors.count()
|
||
factor_counter = 0
|
||
paid_state = 'pending'
|
||
for factor in province_factors:
|
||
if factor.poultry_factor != None:
|
||
total_amount += factor.poultry_factor.shares['poultryShareWithProfit']
|
||
if factor.poultry_factor.paid_state == 'paid':
|
||
factor_counter += 1
|
||
else:
|
||
total_amount += factor.shares['poultryShareWithProfit']
|
||
if factor.paid_state == 'paid':
|
||
factor_counter += 1
|
||
average_weight += factor.total_weight
|
||
sales_price += factor.factor_fee
|
||
average_fee = factor.province_check_req.fee
|
||
if factor_count == factor_counter:
|
||
paid_state = 'paid'
|
||
sales_price = sales_price / factor_count
|
||
average_weight = average_weight / factor_count
|
||
average_weight_dict = {
|
||
"date": poultry_request.send_date.date(),
|
||
"weight": average_weight,
|
||
}
|
||
average_weight_chart_list.append(average_weight_dict)
|
||
|
||
poultry_request_dict.update({
|
||
"total_amount": total_amount,
|
||
"average_weight": average_weight,
|
||
"average_fee": average_fee,
|
||
"sales_price": sales_price,
|
||
"paid_state": paid_state,
|
||
|
||
})
|
||
poultry_request_list.append(poultry_request_dict)
|
||
|
||
poultry_hatchings = PoultryHatching.objects.filter(trash=False).order_by('date')
|
||
if poultry_hatchings.count() > 0:
|
||
for poultry_hatching in poultry_hatchings:
|
||
if poultry_hatching.date.date() in dates:
|
||
pass
|
||
else:
|
||
dates.append(poultry_hatching.date.date())
|
||
for date in dates:
|
||
hatching = PoultryHatching.objects.filter(date__year=date.year, date__month=date.month,
|
||
date__day=date.day)
|
||
for hatch in hatching:
|
||
quantity += hatch.quantity
|
||
losses += hatch.losses
|
||
internal_hatching_dict = {
|
||
"date": date,
|
||
"quantity": quantity,
|
||
"losses": losses,
|
||
}
|
||
hatching_list.append(internal_hatching_dict)
|
||
|
||
quantity = 0
|
||
losses = 0
|
||
|
||
final_dict = {
|
||
"table": poultry_request_list,
|
||
"hatching_chart": hatching_list,
|
||
"weight_chart": average_weight_chart_list,
|
||
}
|
||
|
||
return Response(final_dict, status=status.HTTP_200_OK)
|
||
|
||
|
||
# ویوست مربوط به نامه جهاد واستانداری
|
||
class PoultryRequestletterReportViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryRequest.objects.all()
|
||
permission_classes = [AllowAny]
|
||
serializer_class = PoultryRequestSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
province = Province.objects.get(id=2)
|
||
from datetime import datetime
|
||
# refresh(request.user.id)
|
||
if 'general_report' in request.GET:
|
||
date = datetime.strptime(request.GET['date'], '%Y-%m-%d')
|
||
poultry_requests_list = []
|
||
poultry_requests_dict = {}
|
||
poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province,
|
||
send_date__year=date.year, send_date__month=date.month,
|
||
send_date__day=date.day).order_by('send_date')
|
||
|
||
if poultry_requests.count() > 0:
|
||
for poultry_request in poultry_requests:
|
||
poultry_requests_dict.update({
|
||
'poultry_name': poultry_request.poultry.unit_name,
|
||
'quantity': poultry_request.previous_quantity,
|
||
'weight': poultry_request.Index_weight,
|
||
'age': (poultry_request.send_date.date() - poultry_request.hatching.date.date()).days + 1,
|
||
'confirmed_quantity': poultry_request.quantity,
|
||
'remain_quantity': poultry_request.hatching.left_over,
|
||
})
|
||
|
||
poultry_requests_list.append(poultry_requests_dict)
|
||
poultry_requests_dict = {}
|
||
return Response(poultry_requests_list, status=status.HTTP_200_OK)
|
||
|
||
elif 'daily_report' in request.GET:
|
||
now = datetime.now().date()
|
||
date_list = []
|
||
hatching_list = []
|
||
poultry_request_detail_list = []
|
||
poultry_requests = PoultryRequest.objects.filter(poultry__address__province=province).order_by('-send_date')
|
||
if poultry_requests.count() > 0:
|
||
for poultry_request in poultry_requests:
|
||
if poultry_request.send_date.date() in date_list:
|
||
pass
|
||
else:
|
||
date_list.append(poultry_request.send_date.date())
|
||
for date in date_list:
|
||
quantity = 0
|
||
remain_quantity = 0
|
||
province_quantity = 0
|
||
average_weight = 0
|
||
total_poultry_request_quantity = 0
|
||
accepted_request_quantity = 0
|
||
poultry_requests_list = PoultryRequest.objects.filter(poultry__address__province=province,
|
||
send_date__year=date.year,
|
||
send_date__month=date.month,
|
||
send_date__day=date.day)
|
||
for internal_poultry_reqs in poultry_requests_list:
|
||
if internal_poultry_reqs.hatching in hatching_list:
|
||
pass
|
||
else:
|
||
hatching_list.append(internal_poultry_reqs.hatching)
|
||
remain_quantity += internal_poultry_reqs.hatching.left_over
|
||
|
||
quantity += internal_poultry_reqs.previous_quantity
|
||
average_weight += internal_poultry_reqs.Index_weight
|
||
province_quantity += internal_poultry_reqs.quantity
|
||
total_poultry_request_quantity += internal_poultry_reqs.quantity
|
||
if internal_poultry_reqs.province_state == 'accepted':
|
||
accepted_request_quantity += internal_poultry_reqs.quantity
|
||
average_weight = round(average_weight / poultry_requests_list.count(), 2)
|
||
|
||
poultry_request_detail_list.append({
|
||
'today': now,
|
||
'date': date,
|
||
'province': province.name,
|
||
'previous_quantity': quantity,
|
||
'index_weight': average_weight,
|
||
'province_quantity': province_quantity,
|
||
'remain_quantity': remain_quantity,
|
||
'country_quantity': 0,
|
||
'total_poultry_request_quantity': total_poultry_request_quantity,
|
||
'accepted_request_quantity': accepted_request_quantity,
|
||
|
||
})
|
||
return Response(poultry_request_detail_list, status=status.HTTP_200_OK)
|
||
|
||
|
||
class CasestatusViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryRequest.objects.all()
|
||
permission_classes = [AllowAny]
|
||
serializer_class = PoultryRequestSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
poultry_request_list = []
|
||
user = SystemUserProfile.objects.get(user=request.user)
|
||
date = datetime.datetime.strptime(str(request.GET['date']), '%Y-%m-%d')
|
||
if request.GET['role'] == 'CityOperator':
|
||
city_operator = CityOperator.objects.get(user=user, trash=False)
|
||
poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
|
||
poultry__city_operator=city_operator.unit_name,
|
||
trash=False).order_by('id')
|
||
elif request.GET['role'] in ['VetFarm', 'CityCommerce', 'CityJahad', 'CityPoultry']:
|
||
|
||
poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
|
||
poultry__address__city=user.city,
|
||
trash=False).order_by('id')
|
||
else:
|
||
poultry_requests = PoultryRequest.objects.filter(send_date__date=date,
|
||
poultry__address__province=user.province,
|
||
trash=False).order_by('id')
|
||
if poultry_requests:
|
||
for poultry_request in poultry_requests:
|
||
vet_farm = VetFarm.objects.filter(poultry=poultry_request.poultry, trash=False)
|
||
if vet_farm.count() > 0:
|
||
vet_farm = vet_farm.last()
|
||
vet_farm_name = vet_farm.vet.user.fullname
|
||
vet_farm_mobile = vet_farm.vet.user.mobile
|
||
else:
|
||
vet_farm_name = None
|
||
vet_farm_mobile = None
|
||
|
||
poultry_request_dict = {}
|
||
poultry_request_dict.update({"poultry": {
|
||
"user_fullname": poultry_request.poultry.user.fullname,
|
||
"user_mobile": poultry_request.poultry.user.mobile,
|
||
"poultry_name": poultry_request.poultry.unit_name,
|
||
"poultry_city": poultry_request.poultry.address.city.name,
|
||
"poultry_province": poultry_request.poultry.address.province.name,
|
||
"poultry_request_quantity": poultry_request.quantity,
|
||
"poultry_request_remain_quantity": poultry_request.remain_quantity,
|
||
"freezing": poultry_request.freezing,
|
||
"chicken_breed": poultry_request.chicken_breed,
|
||
"send_date": poultry_request.send_date,
|
||
"index_weight": poultry_request.Index_weight,
|
||
"vet_farm_name": vet_farm_name,
|
||
"vet_farm_mobile": vet_farm_mobile,
|
||
|
||
}
|
||
|
||
})
|
||
city_operator = CityOperator.objects.filter(key=poultry_request.city_operator.key, trash=False)
|
||
if city_operator:
|
||
city_operator = city_operator.last()
|
||
city_operator_name = city_operator.user.fullname
|
||
city_operator_mobile = city_operator.user.mobile
|
||
city_operator_province = city_operator.address.province.name
|
||
city_operator_city = city_operator.address.city.name
|
||
else:
|
||
|
||
city_operator_name = None
|
||
city_operator_mobile = None
|
||
city_operator_province = None
|
||
city_operator_city = None
|
||
|
||
city = CityOperatorCheckRequest.objects.filter(poultry_request=poultry_request, trash=False)
|
||
if city:
|
||
city = city.last()
|
||
poultry_request_dict['city_state'] = {
|
||
"operator_name": city_operator_name,
|
||
"operator_mobile": city_operator_mobile,
|
||
"operator_province": city_operator_province,
|
||
"operator_city": city_operator_city,
|
||
"state": city.state,
|
||
}
|
||
else:
|
||
poultry_request_dict['city_state'] = {
|
||
"operator_name": city_operator_name,
|
||
"operator_mobile": city_operator_mobile,
|
||
"operator_province": city_operator_province,
|
||
"operator_city": city_operator_city,
|
||
"state": 'pending',
|
||
}
|
||
role = Group.objects.get(name='ProvinceOperator')
|
||
province_operator = ProvinceOperator.objects.filter(
|
||
address__province__name=poultry_request.poultry.address.province.name,
|
||
user__role=role, trash=False)
|
||
if province_operator:
|
||
province_operator = province_operator.last()
|
||
province_operator_name = province_operator.user.fullname
|
||
province_operator_mobile = province_operator.user.mobile
|
||
province_operator_provinc = province_operator.address.province.name
|
||
province_operator_city = province_operator.address.city.name
|
||
|
||
else:
|
||
province_operator_name = None
|
||
province_operator_mobile = None
|
||
province_operator_provinc = None
|
||
province_operator_city = None
|
||
|
||
province = ProvinceCheckOperatorRequest.objects.filter(poultry_request=poultry_request,
|
||
trash=False)
|
||
if province:
|
||
province = province.last()
|
||
poultry_request_dict['province_state'] = {
|
||
"province_operator_name": province_operator_name,
|
||
"province_operator_mobile": province_operator_mobile,
|
||
"province_operator_provinc": province_operator_provinc,
|
||
"province_operator_city": province_operator_city,
|
||
"state": province.state,
|
||
}
|
||
else:
|
||
|
||
poultry_request_dict.update({"province_state": {
|
||
"province_operator_name": province_operator_name,
|
||
"province_operator_mobile": province_operator_mobile,
|
||
"province_operator_provinc": province_operator_provinc,
|
||
"province_operator_city": province_operator_city,
|
||
"state": 'pending',
|
||
}})
|
||
|
||
province_kill_requests = ProvinceKillRequest.objects.filter(trash=False,
|
||
province_request__poultry_request=poultry_request)
|
||
if province_kill_requests:
|
||
province_kill_request_list = []
|
||
for province_kill_request in province_kill_requests:
|
||
province_kill_request_dict = {}
|
||
province_kill_request_dict = {
|
||
"state": province_kill_request.state,
|
||
"buyer_name": province_kill_request.kill_request.kill_house.name,
|
||
"buyer_mobile": province_kill_request.kill_request.kill_house.kill_house_operator.user.mobile,
|
||
"quantity": province_kill_request.main_quantity,
|
||
}
|
||
buyer_type = None
|
||
if province_kill_request.kill_request.kill_house.killer == False:
|
||
buyer_type = 'kill_house'
|
||
else:
|
||
buyer_type = 'killer'
|
||
province_kill_request_dict.update({
|
||
"buyer_type": buyer_type,
|
||
})
|
||
kill_house_requests = KillHouseRequest.objects.filter(trash=False,
|
||
province_kill_request=province_kill_request)
|
||
if kill_house_requests:
|
||
kill_house_request_list = []
|
||
for kill_house_request in kill_house_requests:
|
||
kill_house_vet = KillHouseVet.objects.filter(
|
||
kill_house=kill_house_request.kill_request.kill_house, trash=False)
|
||
if kill_house_vet.count() > 0:
|
||
kill_house_vet = kill_house_vet.last()
|
||
kill_house_vet_name = kill_house_vet.vet.user.fullname
|
||
kill_house_vet_mobile = kill_house_vet.vet.user.mobile
|
||
else:
|
||
kill_house_vet_name = None
|
||
kill_house_vet_mobile = None
|
||
|
||
kill_house_request_dict = {}
|
||
kill_house_request_dict = {
|
||
"vet_state": kill_house_request.vet_state,
|
||
"kill_house_vet_name": kill_house_vet_name,
|
||
"kill_house_vet_mobile": kill_house_vet_mobile,
|
||
"driver_name": kill_house_request.add_car.driver.driver_name,
|
||
"driver_mobile": kill_house_request.add_car.driver.driver_mobile,
|
||
"pelak": kill_house_request.add_car.driver.pelak,
|
||
"health_code": kill_house_request.add_car.driver.health_code,
|
||
"quantity": kill_house_request.quantity,
|
||
"traffic_code": kill_house_request.traffic_code,
|
||
"clearance_code": kill_house_request.clearance_code,
|
||
"bar_code": kill_house_request.bar_code,
|
||
}
|
||
bar = KillHouseAssignmentInformation.objects.filter(trash=False,
|
||
kill_house_request=kill_house_request)
|
||
if bar:
|
||
bar = bar.last()
|
||
kill_house_request_dict.update({
|
||
"bar": {
|
||
"car_weight_without_load": bar.car_weight_without_load,
|
||
"car_weight_without_load_image": bar.car_weight_without_load_image,
|
||
"car_weight_with_load": bar.car_weight_with_load,
|
||
"car_weight_with_load_image": bar.car_weight_with_load_image,
|
||
"net_weight": bar.net_weight,
|
||
"state": bar.state,
|
||
"real_quantity": bar.real_quantity,
|
||
"exploited_carcass": bar.exploited_carcass
|
||
}
|
||
})
|
||
else:
|
||
kill_house_request_dict.update({
|
||
"bar": None
|
||
})
|
||
province_factor = ProvinceFactorToKillHouse.objects.filter(
|
||
province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
|
||
trash=False)
|
||
if province_factor:
|
||
province_factor = province_factor.last()
|
||
kill_house_request_dict.update({"province_factor": {
|
||
"total_weight": province_factor.total_weight,
|
||
"factor_fee": province_factor.factor_fee,
|
||
"total_price": province_factor.total_price,
|
||
"paid_state": province_factor.paid_state,
|
||
}
|
||
|
||
})
|
||
else:
|
||
kill_house_request_dict.update({"province_factor": None})
|
||
|
||
kill_house_factor = KillHouseFactorToProvince.objects.filter(
|
||
province_factor__province_check_info__kill_house_assignment__kill_house_request=kill_house_request,
|
||
trash=False)
|
||
if kill_house_factor:
|
||
kill_house_factor = kill_house_factor.last()
|
||
kill_house_request_dict.update({"kill_house_factor": {
|
||
"payment_code": kill_house_factor.payment_code,
|
||
"state": kill_house_factor.state,
|
||
"factor_image": kill_house_factor.factor_image,
|
||
"message": kill_house_factor.message,
|
||
}
|
||
|
||
})
|
||
else:
|
||
kill_house_request_dict.update({"kill_house_factor": None})
|
||
kill_house_request_list.append(kill_house_request_dict)
|
||
province_kill_request_dict.update({"kill_house_requests": kill_house_request_list})
|
||
|
||
|
||
else:
|
||
province_kill_request_dict.update({"kill_house_requests": None})
|
||
|
||
province_kill_request_list.append(province_kill_request_dict)
|
||
poultry_request_dict.update({"province_kill_requests": province_kill_request_list})
|
||
|
||
else:
|
||
poultry_request_dict.update({"province_kill_requests": None})
|
||
|
||
province_inspector = PovinceInspector.objects.filter(poultry_request=poultry_request, trash=False)
|
||
if province_inspector:
|
||
province_inspector = province_inspector.last()
|
||
poultry_request_dict.update({"province_inspector": {
|
||
"state": province_inspector.state
|
||
|
||
}})
|
||
else:
|
||
poultry_request_dict.update({"province_inspector": None})
|
||
poultry_request_list.append(poultry_request_dict)
|
||
return Response(poultry_request_list, status=status.HTTP_200_OK)
|
||
|
||
|
||
class GeneralCasestatusViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryRequest.objects.all()
|
||
permission_classes = [AllowAny]
|
||
serializer_class = PoultryRequestSerializer
|
||
pagination_class = CustomPagination
|
||
filter_backends = [DjangoFilterBackend]
|
||
filterset_class = PoultryRequestFilterSet
|
||
filterset_fields = [
|
||
'poultry__unit_name',
|
||
'poultry__user__fullname',
|
||
'poultry__user__mobile',
|
||
'order_code',
|
||
]
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
poultry_reqs = []
|
||
poultry_requests = []
|
||
user = SystemUserProfile.objects.get(user=request.user)
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
|
||
if request.GET['role'] == 'CityOperator':
|
||
city_operator = CityOperator.objects.get(user=user)
|
||
poultry_reqs = PoultryRequest.objects.filter(
|
||
poultry__address__province=user.province,
|
||
poultry__city_operator=city_operator.unit_name,
|
||
send_date__date__gte=date1,
|
||
send_date__date__lte=date2,
|
||
trash=False
|
||
).order_by('id').select_related('poultry__user')
|
||
|
||
elif request.GET['role'] == 'CityCommerce' or request.GET['role'] == 'VetFarm':
|
||
poultry_reqs = PoultryRequest.objects.filter(
|
||
poultry__address__province=user.province,
|
||
poultry__address__city=user.city,
|
||
send_date__date__gte=date1,
|
||
send_date__date__lte=date2,
|
||
trash=False
|
||
).order_by('id').select_related('poultry__user')
|
||
|
||
else:
|
||
poultry_reqs = PoultryRequest.objects.filter(
|
||
poultry__address__province=user.province,
|
||
send_date__date__gte=date1,
|
||
send_date__date__lte=date2,
|
||
trash=False).order_by('id').select_related('poultry__user')
|
||
|
||
if 'search' in request.GET:
|
||
if request.GET['search'] == 'filter':
|
||
if request.GET['value'] != "":
|
||
for item in self.filterset_fields:
|
||
query = QueryDict('{0}__contains={1}'.format(item, request.GET['value']))
|
||
if (self.filterset_class(
|
||
data=query,
|
||
queryset=poultry_reqs
|
||
)
|
||
).filter():
|
||
ps = self.filterset_class(data=query, queryset=poultry_reqs)
|
||
poultry_requests = ps.filter()
|
||
poultry_reqs = [] if len(poultry_requests) == 0 else poultry_requests
|
||
|
||
page_size = request.query_params.get('page_size', None)
|
||
if page_size:
|
||
self.pagination_class.page_size = int(page_size)
|
||
|
||
page = self.paginate_queryset(poultry_reqs)
|
||
if page is not None:
|
||
serializer = PoultryRequestForGeneralCasestatusSerializer(page, many=True)
|
||
return self.get_paginated_response(serializer.data)
|
||
|
||
serializer = PoultryRequestForGeneralCasestatusSerializer(poultry_reqs, many=True)
|
||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class HatchingQueryViewSet(viewsets.ModelViewSet):
|
||
queryset = PoultryHatching
|
||
serializer_class = PoultryHatchingSerializer
|
||
permission_classes = [AllowAny]
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
|
||
hatchings = PoultryHatching.objects.filter(trash=False).order_by('-date')
|
||
if hatchings:
|
||
hatchings_list = []
|
||
quantity = 0
|
||
|
||
for hatching in hatchings:
|
||
poultry_requests = PoultryRequest.objects.filter(
|
||
hatching=hatching,
|
||
trash=False,
|
||
state_process__in=('pending', 'accepted'),
|
||
province_state__in=('pending', 'accepted')
|
||
)
|
||
|
||
quantity_req = sum(poultry_req.quantity for poultry_req in poultry_requests)
|
||
quantity += hatching.quantity
|
||
|
||
hatching_dict = {
|
||
"poultry_name": hatching.poultry.unit_name,
|
||
"quantity": hatching.quantity,
|
||
"breed": hatching.breed,
|
||
"left_over": hatching.left_over,
|
||
"date": hatching.date.date(),
|
||
"period": hatching.period,
|
||
"poultry_request": quantity_req
|
||
}
|
||
|
||
hatchings_list.append(hatching_dict)
|
||
|
||
return Response(hatchings_list)
|
||
|
||
|
||
class BuyerRemittance(viewsets.ModelViewSet):
|
||
queryset = ProvinceAutoAllocation.objects.all()
|
||
permission_classes = [AllowAny]
|
||
serializer_class = NewProvinceAutoAllocationSerializer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
|
||
if 'allocation_key' in request.GET:
|
||
serializer = NewProvinceAutoAllocationSerializer(
|
||
ProvinceAutoAllocation.objects.filter(key=request.GET['allocation_key'], trash=False, ).select_related(
|
||
'poultry_request'), many=True)
|
||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||
|
||
|
||
elif 'poultry_request_key' in request.GET:
|
||
|
||
poultry_request = PoultryRequest.objects.filter(key=request.GET['poultry_request_key']).prefetch_related(
|
||
'poultry_request_auto_quantity_province',
|
||
).last()
|
||
|
||
province_auto_allocations = poultry_request.poultry_request_auto_quantity_province.all().select_related(
|
||
'poultry_request',
|
||
'province_kill_request',
|
||
'daily_quota__kill_house__kill_house_operator__user',
|
||
'daily_quota__killer_kill_house__kill_house_operator__user')
|
||
poultry_requests_list = []
|
||
kill_house_list = []
|
||
killer_list = []
|
||
for a in province_auto_allocations:
|
||
if a.poultry_request not in poultry_requests_list:
|
||
poultry_requests_list.append(a.poultry_request)
|
||
num1 = 0
|
||
for b in province_auto_allocations:
|
||
if b.daily_quota == a.daily_quota:
|
||
num1 += b.quantity * b.poultry_request.Index_weight
|
||
dict1 = {
|
||
"buyer_name": a.daily_quota.kill_house.name,
|
||
"weight": num1
|
||
}
|
||
if dict1 not in killer_list:
|
||
killer_list.append(dict1)
|
||
if a.daily_quota.killer_kill_house == None:
|
||
for b in province_auto_allocations:
|
||
if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house:
|
||
num1 += b.quantity * b.poultry_request.Index_weight
|
||
dict2 = {
|
||
"kill_house_name": a.daily_quota.kill_house.name,
|
||
"weight": num1
|
||
}
|
||
if dict2 not in kill_house_list:
|
||
kill_house_list.append(dict2)
|
||
|
||
allocation_list = []
|
||
for allocation in province_auto_allocations:
|
||
if allocation.daily_quota.killer_kill_house:
|
||
kill_house = allocation.daily_quota.killer_kill_house
|
||
else:
|
||
kill_house = allocation.daily_quota.kill_house
|
||
|
||
allocation_dict = {
|
||
"buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
|
||
"buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
|
||
"quantity": allocation.quantity,
|
||
"kill_house": {
|
||
"kill_house_fullname": kill_house.kill_house_operator.user.fullname,
|
||
"kill_house_mobile": kill_house.kill_house_operator.user.mobile,
|
||
}
|
||
}
|
||
allocation_list.append(allocation_dict)
|
||
internal_poultry_req_dict = {
|
||
"poultry_fullname": poultry_request.poultry.user.fullname,
|
||
"base_order": poultry_request.poultry.user.base_order,
|
||
"poultry_mobile": poultry_request.poultry.user.mobile,
|
||
"poultry_quantity": poultry_request.quantity,
|
||
"index_weight": poultry_request.Index_weight,
|
||
"date": poultry_request.send_date,
|
||
"allocations": allocation_list,
|
||
}
|
||
final_dict = {
|
||
"poultry": internal_poultry_req_dict,
|
||
"buyer": killer_list,
|
||
"kill_house": kill_house_list
|
||
}
|
||
return Response(final_dict, status=status.HTTP_200_OK)
|
||
|
||
elif 'auto_allocation' in request.GET:
|
||
|
||
now = datetime.datetime.now().date()
|
||
date = datetime.datetime.strptime(str(request.GET['date']),
|
||
'%Y-%m-%d').date() if 'date' in request.GET else now
|
||
allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related(
|
||
'poultry_request',
|
||
'province_kill_request',
|
||
'daily_quota__kill_house__kill_house_operator__user',
|
||
'daily_quota__killer_kill_house__kill_house_operator__user'
|
||
)
|
||
|
||
poultry_requests_list = []
|
||
final_poultry_requests_list = []
|
||
kill_house_list = []
|
||
killer_list = []
|
||
|
||
for a in allocations:
|
||
if a.poultry_request not in poultry_requests_list:
|
||
poultry_requests_list.append(a.poultry_request)
|
||
num1 = 0
|
||
for b in allocations:
|
||
if b.daily_quota == a.daily_quota:
|
||
num1 += b.quantity * b.poultry_request.Index_weight
|
||
dict1 = {
|
||
"buyer_name": a.daily_quota.kill_house.name,
|
||
"weight": num1
|
||
}
|
||
if dict1 not in killer_list:
|
||
killer_list.append(dict1)
|
||
if a.daily_quota.killer_kill_house == None:
|
||
for b in allocations:
|
||
if b.daily_quota == a.daily_quota or b.daily_quota.killer_kill_house == a.daily_quota.kill_house:
|
||
num1 += b.quantity * b.poultry_request.Index_weight
|
||
dict2 = {
|
||
"kill_house_name": a.daily_quota.kill_house.name,
|
||
"weight": num1
|
||
}
|
||
if dict2 not in kill_house_list:
|
||
kill_house_list.append(dict2)
|
||
|
||
allocation_list = []
|
||
|
||
for poultry_request in poultry_requests_list:
|
||
for allocation in allocations:
|
||
if allocation.poultry_request != poultry_request:
|
||
continue
|
||
|
||
kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house
|
||
|
||
allocation_dict = {
|
||
"buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
|
||
"buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
|
||
"quantity": allocation.quantity,
|
||
"kill_house": {
|
||
"kill_house_fullname": kill_house.kill_house_operator.user.fullname,
|
||
"kill_house_mobile": kill_house.kill_house_operator.user.mobile,
|
||
}
|
||
}
|
||
allocation_list.append(allocation_dict)
|
||
|
||
internal_poultry_req_dict = {
|
||
"poultry_fullname": poultry_request.poultry.user.fullname,
|
||
"poultry_mobile": poultry_request.poultry.user.mobile,
|
||
"poultry_quantity": poultry_request.quantity,
|
||
"index_weight": poultry_request.Index_weight,
|
||
"date": poultry_request.send_date,
|
||
"allocations": allocation_list,
|
||
}
|
||
final_poultry_requests_list.append(internal_poultry_req_dict)
|
||
final_dict = {
|
||
"poultry": final_poultry_requests_list,
|
||
"buyer": killer_list,
|
||
"kill_house": kill_house_list,
|
||
}
|
||
|
||
return Response(final_dict, status=status.HTTP_200_OK)
|
||
|
||
elif 'poultry_remittance' in request.GET:
|
||
now = datetime.datetime.now().date()
|
||
date = datetime.datetime.strptime(str(request.GET['date']),
|
||
'%Y-%m-%d').date() if 'date' in request.GET else now
|
||
allocations = ProvinceAutoAllocation.objects.filter(trash=False, create_date__date=date).select_related(
|
||
'poultry_request',
|
||
'province_kill_request',
|
||
'daily_quota__kill_house__kill_house_operator__user',
|
||
'daily_quota__killer_kill_house__kill_house_operator__user'
|
||
)
|
||
|
||
poultry_requests_list = []
|
||
final_poultry_requests_list = []
|
||
allocation_list = []
|
||
for a in allocations:
|
||
if a.poultry_request not in poultry_requests_list:
|
||
poultry_requests_list.append(a.poultry_request)
|
||
for poultry_request in poultry_requests_list:
|
||
for allocation in allocations:
|
||
if allocation.poultry_request != poultry_request:
|
||
continue
|
||
|
||
kill_house = allocation.daily_quota.killer_kill_house if allocation.daily_quota.killer_kill_house else allocation.daily_quota.kill_house
|
||
|
||
allocation_dict = {
|
||
"buyer_fullname": allocation.daily_quota.kill_house.kill_house_operator.user.fullname,
|
||
"buyer_mobile": allocation.daily_quota.kill_house.kill_house_operator.user.mobile,
|
||
"quantity": allocation.quantity,
|
||
"kill_house": {
|
||
"kill_house_fullname": kill_house.kill_house_operator.user.fullname,
|
||
"kill_house_mobile": kill_house.kill_house_operator.user.mobile,
|
||
}
|
||
}
|
||
allocation_list.append(allocation_dict)
|
||
|
||
internal_poultry_req_dict = {
|
||
"poultry_fullname": poultry_request.poultry.user.fullname,
|
||
"poultry_mobile": poultry_request.poultry.user.mobile,
|
||
"poultry_quantity": poultry_request.quantity,
|
||
"date": poultry_request.send_date,
|
||
"allocations": allocation_list,
|
||
}
|
||
final_poultry_requests_list.append(internal_poultry_req_dict)
|
||
return Response(final_poultry_requests_list, status=status.HTTP_200_OK)
|
||
|
||
elif 'factor_to_province' in request.GET:
|
||
factor = ProvinceFactorToKillHouse.objects.get(
|
||
key=request.GET['factor_to_province'], paid_state='pending')
|
||
# serializer = ProvinceFactorToKillHousePdfSerializer(factor)
|
||
# return Response(serializer.data,status=status.HTTP_200_OK)
|
||
|
||
economic_code_kill_house = factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code if factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.user.national_code else None
|
||
economic_code_poultry = factor.province_check_req.poultry_request.poultry.user.national_code if factor.province_check_req.poultry_request.poultry.user.national_code else None
|
||
dict1 = {
|
||
"buyer_name": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.name,
|
||
# "economic_code_kill_house":economic_code_kill_house,
|
||
# "national_id_kill_house":None,
|
||
"serial_number_kill_house": factor.province_check_req.poultry_request.poultry.user.base_order,
|
||
"adders_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.address,
|
||
# "register_number_kill_house":None,
|
||
"postal_code_kill_house": factor.province_check_info.kill_house_assignment.kill_house_request.killhouse_user.kill_house_operator.address.postal_code,
|
||
"poultry_name": factor.province_check_req.poultry_request.poultry.unit_name + ' ' + factor.province_check_req.poultry_request.poultry.user.fullname,
|
||
# "economic_code_poultry":economic_code_poultry,
|
||
# "national_id_poultry":None,
|
||
"adders_poultry": factor.province_check_req.poultry_request.poultry.address.address,
|
||
# "register_number_poultry":None,
|
||
"postal_code_poultry": factor.province_check_req.poultry_request.poultry.address.postal_code,
|
||
"factor_bar_code": factor.factor_bar_code,
|
||
"amount": factor.total_weight,
|
||
"chicken_price": factor.factor_fee,
|
||
"total_price": factor.total_price,
|
||
|
||
}
|
||
return Response(dict1, status=status.HTTP_200_OK)
|
||
|
||
|
||
class DetailsGeneralWageViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
serializer_class = GenaeralWageSerailizer
|
||
queryset = ProvinceKillRequest.objects.filter(
|
||
state__in=('pending', 'accepted'), trash=False, archive_wage=False,
|
||
first_car_allocated_quantity=0,
|
||
return_to_province=False).exclude(union_share=0, company_share=0, guilds_share=0)
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
ser_general = self.serializer_class(self.queryset).data
|
||
return Response(ser_general['general'], status=status.HTTP_200_OK)
|
||
|
||
|
||
class DetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
serializer_class = DetailsGeneraWageSerializer
|
||
# serializer_class = NewDetailsGeneraWageSerializer
|
||
queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
|
||
'kill_house_operator__user__city').exclude(
|
||
out_province=True)
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class NewDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
serializer_class = NewDetailsGeneraWageSerializer
|
||
queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
|
||
'kill_house_operator__user__city').exclude(
|
||
out_province=True)
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
ser_data = self.serializer_class(self.queryset, many=True, context={'request': request}).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class DashboardDetailsGeneralKillHoseWageViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
serializer_class = DashboardDetailsGeneraWageSerializer
|
||
queryset = KillHouse.objects.filter(trash=False).select_related('kill_house_operator__user',
|
||
'kill_house_operator__user__city').exclude(
|
||
out_province=True)
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
ser_data = self.serializer_class(self.queryset, context={'request': request}).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
|
||
class DataReportPercentagesViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [TokenHasReadWriteScope]
|
||
serializer_class = DetailsGeneraWageSerializer
|
||
queryset = KillHouseRequest.objects.filter(trash=False).order_by('kill_request__recive_date')
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
user = request.user
|
||
if request.GET['role'] == 'CityOperator':
|
||
city_operator = CityOperator.objects.get(user__user=user, trash=False)
|
||
kill_requests = self.queryset.filter(
|
||
province_request__poultry_request__poultry__city_operator=city_operator.unit_name)
|
||
else:
|
||
kill_requests = self.queryset
|
||
all_list = {}
|
||
if request.GET['type'] == 'year':
|
||
has_code_list = []
|
||
quarantine_quantity_list = []
|
||
assignment_state_archive_list = []
|
||
accepted_assignment_real_weight_list = []
|
||
hasnt_code_list = []
|
||
difference_bar_list = []
|
||
ware_house_confirmation_list = []
|
||
ware_house_accepted_real_weight_list = []
|
||
weight_year_list = []
|
||
|
||
now = datetime.datetime.now().date()
|
||
start_date = now - relativedelta(years=1) # محاسبه تاریخ یک سال پیش
|
||
|
||
current_date = start_date
|
||
while current_date <= now:
|
||
kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
|
||
kill_request__recive_date__date__year=current_date.year)
|
||
has_code_year = len(kill_request.filter(clearance_code__isnull=False))
|
||
quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
|
||
assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
|
||
accepted_assignment_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
|
||
accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
|
||
'total_quantity') or 0
|
||
hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
|
||
difference_bar = len(kill_request.filter(
|
||
Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
|
||
ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
|
||
ware_house_accepted_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0
|
||
|
||
dict_has_code_year = {
|
||
'date': current_date,
|
||
'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_quarantine_quantity_year = {
|
||
'date': current_date,
|
||
'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_assignment_state_archive_year = {
|
||
'date': current_date,
|
||
'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_accepted_assignment_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_hasnt_code_year = {
|
||
'date': current_date,
|
||
'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_difference_bar_year = {
|
||
'date': current_date,
|
||
'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_confirmation_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_accepted_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
|
||
2) if accepted_assignment_real_weight > 0 else 0
|
||
}
|
||
|
||
has_code_list.append(dict_has_code_year)
|
||
quarantine_quantity_list.append(dict_quarantine_quantity_year)
|
||
assignment_state_archive_list.append(dict_assignment_state_archive_year)
|
||
accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
|
||
hasnt_code_list.append(dict_hasnt_code_year)
|
||
difference_bar_list.append(dict_difference_bar_year)
|
||
ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
|
||
ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
|
||
weight_year_list.append(dict_weight_year)
|
||
|
||
current_date += relativedelta(months=1)
|
||
|
||
all_list['hasCode'] = has_code_list
|
||
all_list['quarantineQuantity'] = quarantine_quantity_list
|
||
all_list['assignmentStateArchive'] = assignment_state_archive_list
|
||
all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
|
||
all_list['hasntCode'] = hasnt_code_list
|
||
all_list['differenceBar'] = difference_bar_list
|
||
all_list['wareHouseConfirmation'] = ware_house_confirmation_list
|
||
all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
|
||
all_list['weightYear'] = weight_year_list
|
||
elif request.GET['type'] == 'sixMonths':
|
||
has_code_list = []
|
||
quarantine_quantity_list = []
|
||
assignment_state_archive_list = []
|
||
accepted_assignment_real_weight_list = []
|
||
hasnt_code_list = []
|
||
difference_bar_list = []
|
||
ware_house_confirmation_list = []
|
||
ware_house_accepted_real_weight_list = []
|
||
weight_year_list = []
|
||
|
||
now = datetime.datetime.now().date()
|
||
start_date = now - relativedelta(months=5) # محاسبه تاریخ شش ماه پیش
|
||
|
||
current_date = start_date
|
||
while current_date <= now:
|
||
kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
|
||
kill_request__recive_date__date__year=current_date.year)
|
||
has_code_year = len(kill_request.filter(clearance_code__isnull=False))
|
||
quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
|
||
assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
|
||
accepted_assignment_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
|
||
accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
|
||
'total_quantity') or 0
|
||
hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
|
||
difference_bar = len(kill_request.filter(
|
||
Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
|
||
ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
|
||
ware_house_accepted_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0
|
||
|
||
dict_has_code_year = {
|
||
'date': current_date,
|
||
'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_quarantine_quantity_year = {
|
||
'date': current_date,
|
||
'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_assignment_state_archive_year = {
|
||
'date': current_date,
|
||
'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_accepted_assignment_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_hasnt_code_year = {
|
||
'date': current_date,
|
||
'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_difference_bar_year = {
|
||
'date': current_date,
|
||
'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_confirmation_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_accepted_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
|
||
2) if accepted_assignment_real_weight > 0 else 0
|
||
}
|
||
|
||
has_code_list.append(dict_has_code_year)
|
||
quarantine_quantity_list.append(dict_quarantine_quantity_year)
|
||
assignment_state_archive_list.append(dict_assignment_state_archive_year)
|
||
accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
|
||
hasnt_code_list.append(dict_hasnt_code_year)
|
||
difference_bar_list.append(dict_difference_bar_year)
|
||
ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
|
||
ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
|
||
weight_year_list.append(dict_weight_year)
|
||
|
||
current_date += relativedelta(months=1)
|
||
|
||
all_list['hasCode'] = has_code_list
|
||
all_list['quarantineQuantity'] = quarantine_quantity_list
|
||
all_list['assignmentStateArchive'] = assignment_state_archive_list
|
||
all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
|
||
all_list['hasntCode'] = hasnt_code_list
|
||
all_list['differenceBar'] = difference_bar_list
|
||
all_list['wareHouseConfirmation'] = ware_house_confirmation_list
|
||
all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
|
||
all_list['weightYear'] = weight_year_list
|
||
elif request.GET['type'] == 'threeMonths':
|
||
has_code_list = []
|
||
quarantine_quantity_list = []
|
||
assignment_state_archive_list = []
|
||
accepted_assignment_real_weight_list = []
|
||
hasnt_code_list = []
|
||
difference_bar_list = []
|
||
ware_house_confirmation_list = []
|
||
ware_house_accepted_real_weight_list = []
|
||
weight_year_list = []
|
||
|
||
now = datetime.datetime.now().date()
|
||
start_date = now - relativedelta(months=2) # محاسبه تاریخ سه ماه پیش
|
||
|
||
current_date = start_date
|
||
while current_date <= now:
|
||
kill_request = kill_requests.filter(kill_request__recive_date__date__month=current_date.month,
|
||
kill_request__recive_date__date__year=current_date.year)
|
||
has_code_year = len(kill_request.filter(clearance_code__isnull=False))
|
||
quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
|
||
assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
|
||
accepted_assignment_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
|
||
accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
|
||
'total_quantity') or 0
|
||
hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
|
||
difference_bar = len(kill_request.filter(
|
||
Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
|
||
ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
|
||
ware_house_accepted_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0
|
||
|
||
dict_has_code_year = {
|
||
'date': current_date,
|
||
'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_quarantine_quantity_year = {
|
||
'date': current_date,
|
||
'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_assignment_state_archive_year = {
|
||
'date': current_date,
|
||
'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_accepted_assignment_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_hasnt_code_year = {
|
||
'date': current_date,
|
||
'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_difference_bar_year = {
|
||
'date': current_date,
|
||
'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_confirmation_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_accepted_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
|
||
2) if accepted_assignment_real_weight > 0 else 0
|
||
}
|
||
|
||
has_code_list.append(dict_has_code_year)
|
||
quarantine_quantity_list.append(dict_quarantine_quantity_year)
|
||
assignment_state_archive_list.append(dict_assignment_state_archive_year)
|
||
accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
|
||
hasnt_code_list.append(dict_hasnt_code_year)
|
||
difference_bar_list.append(dict_difference_bar_year)
|
||
ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
|
||
ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
|
||
weight_year_list.append(dict_weight_year)
|
||
|
||
current_date += relativedelta(months=1)
|
||
|
||
all_list['hasCode'] = has_code_list
|
||
all_list['quarantineQuantity'] = quarantine_quantity_list
|
||
all_list['assignmentStateArchive'] = assignment_state_archive_list
|
||
all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
|
||
all_list['hasntCode'] = hasnt_code_list
|
||
all_list['differenceBar'] = difference_bar_list
|
||
all_list['wareHouseConfirmation'] = ware_house_confirmation_list
|
||
all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
|
||
all_list['weightYear'] = weight_year_list
|
||
else:
|
||
has_code_list = []
|
||
quarantine_quantity_list = []
|
||
assignment_state_archive_list = []
|
||
accepted_assignment_real_weight_list = []
|
||
hasnt_code_list = []
|
||
difference_bar_list = []
|
||
ware_house_confirmation_list = []
|
||
ware_house_accepted_real_weight_list = []
|
||
weight_year_list = []
|
||
|
||
now = datetime.datetime.now().date()
|
||
last_year = now - relativedelta(months=1) # محاسبه تاریخ یک ماه پیش
|
||
|
||
current_date = last_year
|
||
while current_date <= now:
|
||
kill_request = kill_requests.filter(kill_request__recive_date__date=current_date)
|
||
has_code_year = len(kill_request.filter(clearance_code__isnull=False))
|
||
quarantine_quantity_year = len(kill_request.filter(quarantine_quantity__isnull=False))
|
||
assignment_state_archive_year = len(kill_request.filter(assignment_state_archive='True'))
|
||
accepted_assignment_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('accepted_assignment_real_weight')).get('total_quantity') or 0
|
||
accepted_real_weight = kill_request.aggregate(total_quantity=Sum('accepted_real_weight')).get(
|
||
'total_quantity') or 0
|
||
hasnt_code_year = len(kill_request.filter(clearance_code__isnull=True))
|
||
difference_bar = len(kill_request.filter(
|
||
Q(quantity__gt=F('quarantine_quantity')) | Q(quantity__lt=F('quarantine_quantity'))))
|
||
ware_house_confirmation_year = len(kill_request.filter(ware_house_confirmation=True))
|
||
ware_house_accepted_real_weight = kill_request.aggregate(
|
||
total_quantity=Sum('ware_house_accepted_real_weight')).get('total_quantity') or 0
|
||
|
||
dict_has_code_year = {
|
||
'date': current_date,
|
||
'percent': round(has_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_quarantine_quantity_year = {
|
||
'date': current_date,
|
||
'percent': round(quarantine_quantity_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_assignment_state_archive_year = {
|
||
'date': current_date,
|
||
'percent': round(assignment_state_archive_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_accepted_assignment_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(accepted_assignment_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_hasnt_code_year = {
|
||
'date': current_date,
|
||
'percent': round(hasnt_code_year * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_difference_bar_year = {
|
||
'date': current_date,
|
||
'percent': round(difference_bar * 100 / len(kill_request), 2) if len(kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_confirmation_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_confirmation_year * 100 / len(kill_request), 2) if len(
|
||
kill_request) > 0 else 0
|
||
}
|
||
dict_ware_house_accepted_real_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_real_weight,
|
||
2) if accepted_real_weight > 0 else 0
|
||
}
|
||
dict_weight_year = {
|
||
'date': current_date,
|
||
'percent': round(ware_house_accepted_real_weight * 100 / accepted_assignment_real_weight,
|
||
2) if accepted_assignment_real_weight > 0 else 0
|
||
}
|
||
|
||
has_code_list.append(dict_has_code_year)
|
||
quarantine_quantity_list.append(dict_quarantine_quantity_year)
|
||
assignment_state_archive_list.append(dict_assignment_state_archive_year)
|
||
accepted_assignment_real_weight_list.append(dict_accepted_assignment_real_weight_year)
|
||
hasnt_code_list.append(dict_hasnt_code_year)
|
||
difference_bar_list.append(dict_difference_bar_year)
|
||
ware_house_confirmation_list.append(dict_ware_house_confirmation_year)
|
||
ware_house_accepted_real_weight_list.append(dict_ware_house_accepted_real_weight_year)
|
||
weight_year_list.append(dict_weight_year)
|
||
|
||
current_date += relativedelta(days=1) # به روز بعد بروید
|
||
|
||
all_list['hasCode'] = has_code_list
|
||
all_list['quarantineQuantity'] = quarantine_quantity_list
|
||
all_list['assignmentStateArchive'] = assignment_state_archive_list
|
||
all_list['acceptedAssignmentRealWeight'] = accepted_assignment_real_weight_list
|
||
all_list['hasntCode'] = hasnt_code_list
|
||
all_list['differenceBar'] = difference_bar_list
|
||
all_list['wareHouseConfirmation'] = ware_house_confirmation_list
|
||
all_list['wareHouseAcceptedRealWeight'] = ware_house_accepted_real_weight_list
|
||
all_list['weightYear'] = weight_year_list
|
||
return Response(all_list)
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def check_excel(request):
|
||
url = request.GET.get('url')
|
||
if not url:
|
||
return JsonResponse({'status': 'error', 'message': 'URL parameter is missing'}, status=400)
|
||
|
||
try:
|
||
r = requests.head(f'https://{base_url_for_sms_report}backend.rasadyar.com/{url}')
|
||
return JsonResponse({'status': r.status_code})
|
||
except requests.RequestException as e:
|
||
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
|
||
|
||
|
||
class SSLAdapter(HTTPAdapter):
|
||
def __init__(self, *args, **kwargs):
|
||
self.context = create_urllib3_context()
|
||
self.context.options |= 0x4 # OP_LEGACY_SERVER_CONNECT
|
||
super().__init__(*args, **kwargs)
|
||
|
||
def init_poolmanager(self, *args, **kwargs):
|
||
kwargs['ssl_context'] = self.context
|
||
return super().init_poolmanager(*args, **kwargs)
|
||
|
||
def build_response(self, req, resp):
|
||
resp = super().build_response(req, resp)
|
||
return resp
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def find_gid_code(request):
|
||
date = datetime.datetime.now().date() - datetime.timedelta(days=7)
|
||
kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False,
|
||
quarantine_quantity__isnull=True).only(
|
||
'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
|
||
).order_by('-id')
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
|
||
for kill in kill_house_request:
|
||
if kill.clearance_code is None:
|
||
kill.quarantine_code_state = 'noclearance'
|
||
else:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
kill.quarantine_code_state = 'notconfirmed'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_quantity = int(number)
|
||
if kill.quarantine_code_state is not None:
|
||
kill.quarantine_code_state = None
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
kill.save()
|
||
return HttpResponse('ok')
|
||
|
||
|
||
def get_gid(clearance_code):
|
||
kill = KillHouseRequest.objects.filter(clearance_code=clearance_code, trash=False).order_by('id')
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kill:
|
||
if len(kill) > 1:
|
||
for k in kill[1:]:
|
||
if k.quarantine_quantity is not None:
|
||
k.quarantine_quantity = None
|
||
k.quarantine_code_state = 'merge'
|
||
k.save()
|
||
kill = kill.first()
|
||
if kill.quarantine_code_state != 'merge':
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
kill.quarantine_code_state = 'notconfirmed'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
kill.inquiry_date = date.date()
|
||
send_date = kill.kill_request.recive_date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_quantity = int(number)
|
||
if kill.quarantine_code_state is not None:
|
||
kill.quarantine_code_state = None
|
||
for i in table[4:5]:
|
||
rows = i.find_all('tr')
|
||
|
||
pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
style='font-family:Tahoma').text.strip()
|
||
kill.inquiry_pelak = pelak_txt
|
||
td = rows[1].find_all('td')[1]
|
||
driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_driver = driver_txt
|
||
|
||
for r in rows:
|
||
tds = r.find_all('td', colspan="2")
|
||
if len(tds) >= 2:
|
||
origin_td = tds[0]
|
||
origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_origin = origin_text
|
||
|
||
destination_td = tds[1]
|
||
destination_text = destination_td.find('span',
|
||
class_='dynamictxt').text.strip()
|
||
kill.inquiry_destination = destination_text
|
||
else:
|
||
kill.quarantine_code_state = 'contradiction'
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
kill.save()
|
||
|
||
|
||
def cron_find_gid_code():
|
||
date = datetime.datetime.now().date() - datetime.timedelta(days=7)
|
||
kill_house_request = KillHouseRequest.objects.filter(kill_request__recive_date__date__gte=date, trash=False,
|
||
quarantine_quantity__isnull=True,
|
||
clearance_code__isnull=False).only(
|
||
'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
|
||
).order_by('-id')
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
|
||
for kill in kill_house_request:
|
||
if kill.quarantine_code_state != 'merge':
|
||
if kill.clearance_code is None:
|
||
kill.quarantine_code_state = 'noclearance'
|
||
else:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
kill.quarantine_code_state = 'notconfirmed'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
kill.inquiry_date = date.date()
|
||
send_date = kill.kill_request.recive_date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_quantity = int(number)
|
||
if kill.quarantine_code_state is not None:
|
||
kill.quarantine_code_state = None
|
||
for i in table[4:5]:
|
||
rows = i.find_all('tr')
|
||
|
||
pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
style='font-family:Tahoma').text.strip()
|
||
kill.inquiry_pelak = pelak_txt
|
||
td = rows[1].find_all('td')[1]
|
||
driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_driver = driver_txt
|
||
|
||
for r in rows:
|
||
tds = r.find_all('td', colspan="2")
|
||
if len(tds) >= 2:
|
||
origin_td = tds[0]
|
||
origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_origin = origin_text
|
||
|
||
destination_td = tds[1]
|
||
destination_text = destination_td.find('span',
|
||
class_='dynamictxt').text.strip()
|
||
kill.inquiry_destination = destination_text
|
||
else:
|
||
kill.quarantine_code_state = 'contradiction'
|
||
kill.quarantine_quantity = None
|
||
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
kill.save()
|
||
|
||
|
||
class IranProvinceViewSet(viewsets.ModelViewSet):
|
||
queryset = IranProvinces.objects.all().order_by('id')
|
||
serializer_class = IranProvinceSerializer
|
||
permission_classes = [AllowAny]
|
||
|
||
|
||
class IranCityViewSet(viewsets.ModelViewSet):
|
||
queryset = IranCities.objects.all().order_by('id')
|
||
serializer_class = IranCitiesSerializer
|
||
permission_classes = [AllowAny]
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
query = self.queryset.filter(province_id__name=request.GET.get('name'))
|
||
ser_data = self.serializer_class(query, many=True).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
|
||
def fix_image_voilation_hatching(request):
|
||
hatchings = PoultryHatching.objects.filter(violation_image__isnull=False)
|
||
for h in hatchings:
|
||
h.violation_image1 = [h.violation_image]
|
||
h.save()
|
||
return HttpResponse('ok')
|
||
|
||
|
||
def fix_image_voilation_hatching_return(request):
|
||
hatchings = PoultryHatching.objects.filter(violation_image1__isnull=False)
|
||
for h in hatchings:
|
||
h.violation_image = h.violation_image1
|
||
h.save()
|
||
return HttpResponse('ok')
|
||
|
||
|
||
class AgeNotificationPoultryViewSet(viewsets.ModelViewSet):
|
||
queryset = AgeNotificationPoultry.objects.all()
|
||
serializer_class = AgeNotificationPoultrySerilizer
|
||
permission_classes = [AllowAny]
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
query = self.queryset.filter(trash=False)
|
||
ser_data = self.serializer_class(query, many=True).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
query = self.queryset.get(key=request.data['notif_key'])
|
||
request.data.pop('notif_key')
|
||
ser_data = self.serializer_class(query)
|
||
ser_data.update(instance=query, validated_data=request.data)
|
||
return Response(ser_data.data, status=status.HTTP_200_OK)
|
||
|
||
def destroy(self, request, *args, **kwargs):
|
||
query = self.queryset.get(key=request.GET['notif_key'])
|
||
query.trash = True
|
||
query.save()
|
||
return Response({'result': 'با موفقیت حذف شد.'}, status=status.HTTP_200_OK)
|
||
|
||
|
||
def send_sms_for_poultry_from_age_notification():
|
||
notif_poultry = AgeNotificationPoultry.objects.filter(trash=False)
|
||
if notif_poultry:
|
||
for n in notif_poultry:
|
||
poultry_hatchings = PoultryHatching.objects.filter(
|
||
archive=False,
|
||
allow_hatching='pending',
|
||
trash=False,
|
||
left_over__gt=(F('quantity') * n.losses_percent) / 100,
|
||
chicken_age=n.poultry_age
|
||
).values_list('poultry__user__mobile', flat=True).distinct()
|
||
|
||
mobile_numbers = ','.join(poultry_hatchings)
|
||
if len(mobile_numbers) > 0:
|
||
req = send_sms_request(
|
||
f"http://webservice.sahandsms.com/newsmswebservice.asmx/SendPostUrl?username={USERNAME_SMS_FINANCIAL}&password={PASSWORD_SMS_FINANCIAL}&from=30002501&to={mobile_numbers}&message={n.message}")
|
||
|
||
|
||
def remove_access_token():
|
||
ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/"
|
||
requests.get(
|
||
url=ARTA_remove_access_token,
|
||
verify=False
|
||
)
|
||
now = datetime.datetime.now()
|
||
accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3))
|
||
for access in accesses:
|
||
access.expires = now - timedelta(days=2)
|
||
access.save()
|
||
|
||
|
||
def kill_house_not_add_to_inventory():
|
||
now = datetime.datetime.now().date() - timedelta(days=2)
|
||
kill_houses = KillHouse.objects.filter(trash=False, out_province=False).select_related('kill_house_operator__user')
|
||
for kill_house in kill_houses:
|
||
kill_request = len(KillHouseRequest.objects.filter(Q(killhouse_user=kill_house) | Q(killer=kill_house),
|
||
trash=False, ware_house_confirmation=False,
|
||
calculate_status=True,
|
||
kill_request__recive_date__date__lte=now))
|
||
if kill_request > 0:
|
||
send_sms_for_kill_house_not_add_to_inventory(kill_house.kill_house_operator.user.mobile, kill_request)
|
||
|
||
|
||
class CookieSamasatViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
queryset = CookieSamasat.objects.first()
|
||
serializer_class = CookieSamasatSerilizer
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
cookie = CookieSamasat.objects.all().first()
|
||
if not cookie:
|
||
cookie = CookieSamasat(
|
||
cookie='-',
|
||
table_name='-'
|
||
)
|
||
cookie.save()
|
||
ser_data = self.serializer_class(cookie).data
|
||
return Response(ser_data, status=status.HTTP_200_OK)
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
query = CookieSamasat.objects.first()
|
||
|
||
if base_url_for_sms_report == 'test':
|
||
province_list = ['bu', 'ma', 'ha']
|
||
for name in province_list:
|
||
requests.put(f"https://{name}backend.rasadyar.com/cookie-samasat/0/", data=request.data)
|
||
|
||
serializer = self.serializer_class(query, data=request.data, partial=True)
|
||
if serializer.is_valid():
|
||
serializer.save()
|
||
return Response({"result": "با موفقیت انجام شد."}, status=status.HTTP_200_OK)
|
||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||
|
||
|
||
# def create_poultry(phone_number,full_name,city,province):
|
||
# group = Group.objects.get(name__exact="Poultry")
|
||
# hashed_password=None
|
||
# password=None
|
||
# user = User(username=phone_number, first_name=first_name, last_name=last_name, password=hashed_password)
|
||
# user.save()
|
||
# base_id = SystemUserProfile.objects.all()
|
||
# if base_id.count() > 0:
|
||
# base_id = int(base_id.last().base_order) + 1
|
||
# else:
|
||
# base_id = 1000
|
||
# system_profile = SystemUserProfile(
|
||
# mobile=phone_number,
|
||
# first_name=first_name,
|
||
# last_name=last_name,
|
||
# fullname=first_name + '' + last_name,
|
||
# user=user,
|
||
# base_order=base_id,
|
||
# password=password,
|
||
# birthday=str(datetime.datetime.now().date()),
|
||
# city=city,
|
||
# province=province
|
||
# )
|
||
# system_profile.save()
|
||
# system_profile.role.add(group)
|
||
# wallet = Wallet()
|
||
# wallet.save()
|
||
|
||
# درست نیست
|
||
@api_view(["PUT"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def api_update_poultry_hatching(request):
|
||
not_find_list = []
|
||
|
||
for data in request.data['Data']:
|
||
breeding_uniq_id = data['PartIdCode']
|
||
licence_number = data['RequestCode']
|
||
hatching_quantity = data['BaseHatchingCount']
|
||
poultry_name = data['UnitName']
|
||
losses = data['EvacuationCount']
|
||
health_certificate = data['DesCertId']
|
||
evacuation_details = data.get('EvacuationDetail') or []
|
||
if isinstance(evacuation_details, dict):
|
||
evacuation_details = [evacuation_details]
|
||
report_type_field_map = {
|
||
'تلفات ناشی از بیماری': 'total_disease_losses',
|
||
'معدوم سازی گله': 'total_flock_destruction',
|
||
'تلفات عادی گله': 'total_normal_flock_losses',
|
||
'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses',
|
||
'تلفات ناشی از آتش سوزی': 'total_fire_losses',
|
||
}
|
||
evacuation_losses = {}
|
||
evacuation_fields = set()
|
||
for detail in evacuation_details:
|
||
if not isinstance(detail, dict):
|
||
continue
|
||
report_type = (detail.get('ReportTypeString') or '').strip()
|
||
field_name = report_type_field_map.get(report_type)
|
||
if not field_name:
|
||
continue
|
||
try:
|
||
good_count = int(detail.get('GoodCount') or 0)
|
||
except (TypeError, ValueError):
|
||
continue
|
||
evacuation_losses[field_name] = evacuation_losses.get(field_name, 0) + good_count
|
||
evacuation_fields.add(field_name)
|
||
|
||
def apply_evacuation_losses(instance):
|
||
for field in evacuation_fields:
|
||
setattr(instance, field, evacuation_losses.get(field, 0))
|
||
|
||
poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()
|
||
|
||
if not poultry:
|
||
not_find_list.append(breeding_uniq_id)
|
||
continue
|
||
poultry.unit_name = poultry_name
|
||
poultry.save()
|
||
hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
|
||
if hatch:
|
||
period = hatch.last().period + 1
|
||
else:
|
||
period = 1
|
||
|
||
hatching_date = data['HatchingDatePersian'].split('/')
|
||
date = convert_to_miladi(
|
||
year=int(hatching_date[0]),
|
||
month=int(hatching_date[1]),
|
||
day=int(hatching_date[2])
|
||
)
|
||
|
||
poultry_hatching = hatch.filter(trash=False, archive=False, state='pending',
|
||
allow_hatching='pending').order_by('id')
|
||
|
||
if not poultry_hatching.exists():
|
||
if not hatch.filter(archive=True, state='complete',
|
||
allow_hatching="True", licence_number=licence_number).exists():
|
||
hatching = PoultryHatching(
|
||
poultry=poultry,
|
||
date=date,
|
||
quantity=hatching_quantity,
|
||
breed=[
|
||
{"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
period=period,
|
||
chicken_breed='*ترکیبی',
|
||
hall=1,
|
||
left_over=hatching_quantity,
|
||
latest_hatching_change={
|
||
"role": "UnitWindow",
|
||
"date": str(datetime.datetime.now().date()),
|
||
"full_name": ""
|
||
},
|
||
licence_number=licence_number,
|
||
breeding_unique_id=breeding_uniq_id,
|
||
losses=losses,
|
||
health_certificate=health_certificate
|
||
|
||
)
|
||
apply_evacuation_losses(hatching)
|
||
hatching.save()
|
||
|
||
else:
|
||
previouse_hatching = poultry_hatching.last()
|
||
|
||
hatchings = poultry_hatching.filter(licence_number=licence_number)
|
||
if not hatchings:
|
||
if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses):
|
||
previouse_hatching.violation = True
|
||
previouse_hatching.save()
|
||
|
||
hatching = PoultryHatching(
|
||
poultry=poultry,
|
||
date=date,
|
||
quantity=hatching_quantity,
|
||
breed=[
|
||
{"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
period=period,
|
||
chicken_breed='*ترکیبی',
|
||
hall=1,
|
||
left_over=hatching_quantity,
|
||
latest_hatching_change={
|
||
"role": "UnitWindow",
|
||
"date": str(datetime.datetime.now().date()),
|
||
"full_name": ""
|
||
},
|
||
licence_number=licence_number,
|
||
breeding_unique_id=breeding_uniq_id,
|
||
losses=losses,
|
||
health_certificate=health_certificate
|
||
|
||
)
|
||
apply_evacuation_losses(hatching)
|
||
hatching.save()
|
||
else:
|
||
last_hatchings = hatchings.first()
|
||
if last_hatchings.health_certificate is None:
|
||
last_hatchings.health_certificate = health_certificate
|
||
last_hatchings.date = date
|
||
last_hatchings.quantity = hatching_quantity
|
||
last_hatchings.losses = losses
|
||
apply_evacuation_losses(last_hatchings)
|
||
last_hatchings.save()
|
||
|
||
update = LastUpdate.objects.first()
|
||
update.update_date = datetime.datetime.now()
|
||
update.save()
|
||
return Response(not_find_list, status=status.HTTP_201_CREATED)
|
||
|
||
|
||
@api_view(["PUT"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def api_update_chicken_breed(request):
|
||
for data in request.data['Data']:
|
||
breeding_uniq_id = data['PartIdCode']
|
||
breed = data['PedigreeName']
|
||
health_certificate = data['CertId']
|
||
poultry_hatching = PoultryHatching.objects.filter(Q(poultry__breeding_unique_id=breeding_uniq_id,
|
||
health_certificate__isnull=True) | Q(
|
||
poultry__breeding_unique_id=breeding_uniq_id, health_certificate__isnull=False,
|
||
health_certificate=health_certificate)
|
||
, violation=False, trash=False, allow_hatching='pending',
|
||
state='pending',
|
||
).order_by(
|
||
'id').last()
|
||
|
||
if poultry_hatching:
|
||
if poultry_hatching.chicken_breed == '*ترکیبی':
|
||
poultry_hatching.chicken_breed = breed
|
||
elif poultry_hatching.chicken_breed != breed and poultry_hatching.chicken_breed != '*ترکیبی':
|
||
poultry_hatching.chicken_breed = 'ترکیبی'
|
||
else:
|
||
continue
|
||
|
||
poultry_hatching.save()
|
||
|
||
return Response({"result": "انجام شد."}, status=status.HTTP_201_CREATED)
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def api_update_poultry_hatching_from_rsi(request):
|
||
not_find_list = []
|
||
r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')
|
||
|
||
for data in r.json():
|
||
breeding_uniq_id = data['PartIdCode']
|
||
licence_number = data['RequestCode']
|
||
hatching_quantity = data['ChickCountSum']
|
||
CertId = data['CertId']
|
||
poultry_name = data.get('UnitName', None)
|
||
losses = data.get('Evacuation', 0)
|
||
province = data['ProvinceName']
|
||
city = data['CityName']
|
||
PersonTypeName = data['PersonTypeName']
|
||
InteractTypeName = data['InteractTypeName']
|
||
UnionTypeName = data['UnionTypeName']
|
||
date = convert_str_to_date(str(data['Date']), with_datetime=True)
|
||
samasat_discharge_percentage = data['samasat_discharge_percentage']
|
||
evacuation_details = data.get('EvacuationDetail') or []
|
||
if isinstance(evacuation_details, dict):
|
||
evacuation_details = [evacuation_details]
|
||
report_type_field_map = {
|
||
'تلفات ناشی از بیماری': 'total_disease_losses',
|
||
'معدوم سازی گله': 'total_flock_destruction',
|
||
'تلفات عادی گله': 'total_normal_flock_losses',
|
||
'تلفات ناشی از عوامل قهری و طبیعی': 'total_force_majeure_losses',
|
||
'تلفات ناشی از آتش سوزی': 'total_fire_losses',
|
||
}
|
||
evacuation_detail_fields = [
|
||
'PartIdCode',
|
||
'RequestId',
|
||
'MoReportId',
|
||
'ReportType',
|
||
'ReportTypeString',
|
||
'ReportDate',
|
||
'ReportDateShamsi',
|
||
'MoReason',
|
||
'MoDate',
|
||
'MoDateShamsi',
|
||
'MoStartDay',
|
||
'MoEndDay',
|
||
'MoReportSubId',
|
||
'ReportStatus',
|
||
'GoodCount',
|
||
'Message',
|
||
'ErrorCode',
|
||
'IsDeleted',
|
||
'RegDate',
|
||
'RegDateShamsi',
|
||
'RegDateShamsiWithTime',
|
||
'RegDateShamsiOnlyTime',
|
||
'ExternalId',
|
||
'StringId',
|
||
'IsPersisted',
|
||
'AllowInsert',
|
||
'AllowUpdate',
|
||
'ModalCss',
|
||
'GridContainerParametersModel',
|
||
'MenuUserAccess',
|
||
'MenuUserAccessId',
|
||
'LogTableName',
|
||
'LogTableAlias',
|
||
'PageTitle',
|
||
]
|
||
report_type_fields = set(report_type_field_map.values())
|
||
report_type_field_list = list(report_type_fields)
|
||
|
||
def build_unique_key(detail_payload):
|
||
external_id = detail_payload.get('ExternalId')
|
||
if external_id:
|
||
return f"external:{external_id}"
|
||
string_id = detail_payload.get('StringId')
|
||
if string_id:
|
||
return f"string:{string_id}"
|
||
return "fallback:" + "|".join(
|
||
str(detail_payload.get(key) or '') for key in ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate'))
|
||
|
||
def sync_evacuation_detail_records(hatching_instance):
|
||
if not hatching_instance.pk:
|
||
return
|
||
|
||
def normalize_good_count(value):
|
||
if value in (None, ''):
|
||
return None
|
||
try:
|
||
return int(value)
|
||
except (TypeError, ValueError):
|
||
try:
|
||
return int(float(value))
|
||
except (TypeError, ValueError):
|
||
return None
|
||
|
||
retained_ids = set()
|
||
seen_unique_keys = set()
|
||
|
||
for detail in evacuation_details:
|
||
if not isinstance(detail, dict):
|
||
continue
|
||
detail_payload = {field: detail.get(field) for field in evacuation_detail_fields}
|
||
detail_payload['GoodCount'] = normalize_good_count(detail_payload.get('GoodCount'))
|
||
if not any(value not in (None, '') for value in detail_payload.values()):
|
||
continue
|
||
|
||
unique_key = build_unique_key(detail_payload)
|
||
if unique_key in seen_unique_keys:
|
||
continue
|
||
seen_unique_keys.add(unique_key)
|
||
|
||
external_id = detail_payload.get('ExternalId')
|
||
string_id = detail_payload.get('StringId')
|
||
lookup_kwargs = {'hatching': hatching_instance}
|
||
if external_id:
|
||
lookup_kwargs['ExternalId'] = external_id
|
||
elif string_id:
|
||
lookup_kwargs['StringId'] = string_id
|
||
else:
|
||
lookup_key_fields = ('PartIdCode', 'MoReportId', 'ReportType', 'ReportDate')
|
||
lookup_kwargs.update({field: detail_payload.get(field) for field in lookup_key_fields})
|
||
|
||
defaults = detail_payload.copy()
|
||
defaults['hatching'] = hatching_instance
|
||
|
||
try:
|
||
detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create(
|
||
defaults=defaults,
|
||
**lookup_kwargs
|
||
)
|
||
except EvacuationHatchingDetail.MultipleObjectsReturned:
|
||
EvacuationHatchingDetail.objects.filter(**lookup_kwargs).delete()
|
||
detail_instance, _ = EvacuationHatchingDetail.objects.update_or_create(
|
||
defaults=defaults,
|
||
**lookup_kwargs
|
||
)
|
||
|
||
retained_ids.add(detail_instance.pk)
|
||
|
||
if retained_ids:
|
||
hatching_instance.evacuation_details.exclude(pk__in=retained_ids).delete()
|
||
else:
|
||
hatching_instance.evacuation_details.all().delete()
|
||
|
||
def apply_evacuation_losses(instance):
|
||
totals = {field: 0 for field in report_type_fields}
|
||
detail_qs = instance.evacuation_details.filter(trash=False, IsDeleted=False)
|
||
for detail in detail_qs:
|
||
report_type = (detail.ReportTypeString or '').strip()
|
||
field_name = report_type_field_map.get(report_type)
|
||
if not field_name:
|
||
continue
|
||
totals[field_name] += detail.GoodCount or 0
|
||
for field, value in totals.items():
|
||
setattr(instance, field, value)
|
||
|
||
hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id')
|
||
|
||
try:
|
||
if not hatch:
|
||
poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()
|
||
if not poultry:
|
||
first_name = data['poultry']['FirstName']
|
||
last_name = data['poultry']['LastName']
|
||
mobile = data['poultry']['Mobile']
|
||
system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
|
||
province = Province.objects.filter(trash=False, name__exact=province).first()
|
||
city = City.objects.filter(trash=False, name__exact=city).first()
|
||
if not system_profile:
|
||
|
||
data = {
|
||
"username": mobile,
|
||
"first_name": first_name,
|
||
"last_name": last_name,
|
||
"password": '123456',
|
||
"national_code": '0',
|
||
"role": "Poultry",
|
||
"api_key": PROJECT_API_KEY
|
||
}
|
||
req = requests.post(
|
||
url=ARTA_REGISTER,
|
||
data=data,
|
||
verify=False
|
||
)
|
||
|
||
if req.status_code == 200:
|
||
hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
|
||
user = User.objects.filter(username=mobile).first()
|
||
if not user:
|
||
user = User(username=mobile, first_name=first_name, last_name=last_name,
|
||
password=hashed_password)
|
||
user.save()
|
||
base_id = SystemUserProfile.objects.all()
|
||
if base_id.count() > 0:
|
||
base_id = int(base_id.last().base_order) + 1
|
||
else:
|
||
base_id = 1000
|
||
system_profile = SystemUserProfile(
|
||
mobile=mobile,
|
||
first_name=str(first_name),
|
||
last_name=str(last_name),
|
||
fullname=str(first_name) + ' ' + str(last_name),
|
||
user=user,
|
||
base_order=base_id,
|
||
password='123456',
|
||
birthday=str(datetime.datetime.now().date()),
|
||
city=city,
|
||
province=province,
|
||
)
|
||
system_profile.save()
|
||
|
||
else:
|
||
not_find_list.append(breeding_uniq_id)
|
||
|
||
group = Group.objects.get(name__exact="Poultry")
|
||
if not system_profile.role.filter(name="Poultry"):
|
||
system_profile.role.add(group)
|
||
|
||
wallet = Wallet()
|
||
wallet.save()
|
||
poultry = Poultry(
|
||
user=system_profile,
|
||
unit_name=poultry_name,
|
||
system_code=data.get('poultry', {}).get('SystemCode', None),
|
||
epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None),
|
||
breeding_unique_id=breeding_uniq_id,
|
||
)
|
||
|
||
address = SystemAddress(
|
||
province=province,
|
||
city=city,
|
||
address=city
|
||
)
|
||
address.save()
|
||
poultry.address = address
|
||
poultry.user = system_profile
|
||
poultry.wallet = wallet
|
||
poultry.save()
|
||
|
||
poultry.unit_name = poultry_name
|
||
poultry.save()
|
||
|
||
hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
|
||
if hatch:
|
||
period = hatch.last().period + 1
|
||
else:
|
||
period = 1
|
||
hatching = PoultryHatching(
|
||
poultry=poultry,
|
||
date=date,
|
||
quantity=hatching_quantity,
|
||
breed=[
|
||
{"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
period=period,
|
||
chicken_breed=data["PedigreeName"],
|
||
hall=1,
|
||
left_over=hatching_quantity,
|
||
latest_hatching_change={
|
||
"role": "UnitWindow",
|
||
"date": str(datetime.datetime.now().date()),
|
||
"full_name": ""
|
||
},
|
||
licence_number=licence_number,
|
||
breeding_unique_id=breeding_uniq_id,
|
||
losses=losses,
|
||
PersonTypeName=PersonTypeName,
|
||
InteractTypeName=InteractTypeName,
|
||
UnionTypeName=UnionTypeName,
|
||
samasat_discharge_percentage=samasat_discharge_percentage,
|
||
CertId=CertId,
|
||
predicate_date=date + timedelta(
|
||
days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None,
|
||
|
||
)
|
||
hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1
|
||
hatching.save()
|
||
sync_evacuation_detail_records(hatching)
|
||
apply_evacuation_losses(hatching)
|
||
if report_type_field_list:
|
||
hatching.save(update_fields=report_type_field_list)
|
||
else:
|
||
hatching.save()
|
||
else:
|
||
last_hatchings = hatch.first()
|
||
last_hatchings.date = date
|
||
last_hatchings.quantity = hatching_quantity
|
||
last_hatchings.losses = losses
|
||
last_hatchings.PersonTypeName = PersonTypeName
|
||
last_hatchings.InteractTypeName = InteractTypeName
|
||
last_hatchings.UnionTypeName = UnionTypeName
|
||
last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1
|
||
last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage
|
||
last_hatchings.predicate_date = date + timedelta(
|
||
days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None
|
||
sync_evacuation_detail_records(last_hatchings)
|
||
apply_evacuation_losses(last_hatchings)
|
||
update_fields = [
|
||
'date',
|
||
'quantity',
|
||
'losses',
|
||
'PersonTypeName',
|
||
'InteractTypeName',
|
||
'UnionTypeName',
|
||
'chicken_age',
|
||
'samasat_discharge_percentage',
|
||
'predicate_date',
|
||
] + report_type_field_list
|
||
last_hatchings.save(update_fields=update_fields)
|
||
update = LastUpdate.objects.first()
|
||
update.update_date = datetime.datetime.now()
|
||
update.save()
|
||
except:
|
||
not_find_list.append(breeding_uniq_id)
|
||
|
||
if not_find_list:
|
||
token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde"
|
||
chat_id = '10046800'
|
||
url = f'https://eitaayar.ir/api/{token}/sendMessage'
|
||
base_message = f'{base_url_for_sms_report}' \
|
||
'\n'
|
||
messages = []
|
||
current_message = base_message
|
||
new_message_part = ','.join(not_find_list)
|
||
if len(current_message) + len(new_message_part) > 4000: # محدودیت تعداد کاراکترها
|
||
messages.append(current_message)
|
||
current_message = base_message # شروع یک پیام جدید
|
||
|
||
current_message += new_message_part
|
||
|
||
if current_message and current_message != base_message:
|
||
messages.append(current_message)
|
||
for message in messages:
|
||
data = {
|
||
'chat_id': chat_id,
|
||
'text': message,
|
||
}
|
||
r = requests.post(url, data=data, verify=False)
|
||
|
||
return Response(not_find_list, status=status.HTTP_201_CREATED)
|
||
|
||
|
||
class HatchingLossManagementViewSet(viewsets.ModelViewSet):
|
||
permission_classes = [AllowAny]
|
||
serializer_class = HatchingLossManagementSerializer
|
||
|
||
def get_queryset(self):
|
||
queryset = HatchingLossManagement.objects.filter(trash=False)
|
||
if not queryset.exists():
|
||
queryset = HatchingLossManagement.objects.filter(
|
||
pk=HatchingLossManagement.objects.create().pk
|
||
)
|
||
return queryset
|
||
|
||
def get_object(self):
|
||
return self.get_queryset().first()
|
||
|
||
def list(self, request, *args, **kwargs):
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance)
|
||
return Response(
|
||
serializer.data,
|
||
status=status.HTTP_200_OK,
|
||
)
|
||
|
||
def create(self, request, *args, **kwargs):
|
||
return self._update_instance(request, partial=False)
|
||
|
||
def update(self, request, *args, **kwargs):
|
||
return self._update_instance(request, partial=False)
|
||
|
||
def _update_instance(self, request, partial):
|
||
instance = self.get_object()
|
||
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||
serializer.is_valid(raise_exception=True)
|
||
instance = serializer.save()
|
||
self._recalculate_hatchings()
|
||
return Response(self.get_serializer(instance).data, status=status.HTTP_200_OK)
|
||
|
||
def _recalculate_hatchings(self):
|
||
count = 0
|
||
hatchings = PoultryHatching.objects.filter(trash=False, archive=False, allow_hatching='pending')
|
||
for hatching in hatchings.iterator():
|
||
hatching.save()
|
||
count += 1
|
||
return count
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def update_hatching(request):
|
||
r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')
|
||
for data in r.json():
|
||
print(data['PartIdCode'])
|
||
return Response(r.json())
|
||
|
||
|
||
def cron_update_poultry_hatching_from_rsi():
|
||
not_find_list = []
|
||
r = requests.get(f'https://rsibackend.rasadyar.com/app/update_hatching/?province={base_url_for_sms_report}')
|
||
|
||
for data in r.json():
|
||
breeding_uniq_id = data['PartIdCode']
|
||
licence_number = data['RequestCode']
|
||
hatching_quantity = data['ChickCountSum']
|
||
CertId = data['CertId']
|
||
poultry_name = data.get('UnitName', None)
|
||
losses = data.get('Evacuation', 0)
|
||
province = data['ProvinceName']
|
||
city = data['CityName']
|
||
PersonTypeName = data['PersonTypeName']
|
||
InteractTypeName = data['InteractTypeName']
|
||
UnionTypeName = data['UnionTypeName']
|
||
date = datetime.datetime.strptime(data['Date'], "%Y-%m-%dT%H:%M:%SZ")
|
||
samasat_discharge_percentage = data['samasat_discharge_percentage']
|
||
|
||
hatch = PoultryHatching.objects.filter(trash=False, licence_number=licence_number).order_by('id')
|
||
|
||
try:
|
||
if not hatch:
|
||
poultry = Poultry.objects.filter(trash=False, breeding_unique_id=breeding_uniq_id).first()
|
||
if not poultry:
|
||
first_name = data['poultry']['FirstName']
|
||
last_name = data['poultry']['LastName']
|
||
mobile = data['poultry']['Mobile']
|
||
system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
|
||
if not system_profile:
|
||
|
||
data = {
|
||
"username": mobile,
|
||
"first_name": first_name,
|
||
"last_name": last_name,
|
||
"password": '123456',
|
||
"national_code": '0',
|
||
"role": "Poultry",
|
||
"api_key": PROJECT_API_KEY
|
||
}
|
||
req = requests.post(
|
||
url=ARTA_REGISTER,
|
||
data=data,
|
||
verify=False
|
||
)
|
||
|
||
if req.status_code == 200:
|
||
hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
|
||
user = User.objects.filter(username=mobile).first()
|
||
if not user:
|
||
user = User(username=mobile, first_name=first_name, last_name=last_name,
|
||
password=hashed_password)
|
||
user.save()
|
||
base_id = SystemUserProfile.objects.all()
|
||
if base_id.count() > 0:
|
||
base_id = int(base_id.last().base_order) + 1
|
||
else:
|
||
base_id = 1000
|
||
system_profile = SystemUserProfile(
|
||
mobile=mobile,
|
||
first_name=str(first_name),
|
||
last_name=str(last_name),
|
||
fullname=str(first_name) + ' ' + str(last_name),
|
||
user=user,
|
||
base_order=base_id,
|
||
password='123456',
|
||
birthday=str(datetime.datetime.now().date()),
|
||
)
|
||
system_profile.save()
|
||
|
||
else:
|
||
not_find_list.append(breeding_uniq_id)
|
||
|
||
group = Group.objects.get(name__exact="Poultry")
|
||
if not system_profile.role.filter(name="Poultry"):
|
||
system_profile.role.add(group)
|
||
|
||
wallet = Wallet()
|
||
wallet.save()
|
||
poultry = Poultry(
|
||
user=system_profile,
|
||
unit_name=poultry_name,
|
||
system_code=data.get('poultry', {}).get('SystemCode', None),
|
||
epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode', None),
|
||
breeding_unique_id=breeding_uniq_id,
|
||
)
|
||
province = Province.objects.filter(trash=False, name__exact=province).first()
|
||
city = City.objects.filter(trash=False, name__exact=city).first()
|
||
address = SystemAddress(
|
||
province=province,
|
||
city=city,
|
||
address=city
|
||
)
|
||
address.save()
|
||
poultry.address = address
|
||
poultry.user = system_profile
|
||
poultry.wallet = wallet
|
||
poultry.save()
|
||
|
||
poultry.unit_name = poultry_name
|
||
poultry.save()
|
||
|
||
hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
|
||
if hatch:
|
||
period = hatch.last().period + 1
|
||
else:
|
||
period = 1
|
||
hatching = PoultryHatching(
|
||
poultry=poultry,
|
||
date=date,
|
||
quantity=hatching_quantity,
|
||
breed=[
|
||
{"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
period=period,
|
||
chicken_breed=data["PedigreeName"],
|
||
hall=1,
|
||
left_over=hatching_quantity,
|
||
latest_hatching_change={
|
||
"role": "UnitWindow",
|
||
"date": str(datetime.datetime.now().date()),
|
||
"full_name": ""
|
||
},
|
||
licence_number=licence_number,
|
||
breeding_unique_id=breeding_uniq_id,
|
||
losses=losses,
|
||
PersonTypeName=PersonTypeName,
|
||
InteractTypeName=InteractTypeName,
|
||
UnionTypeName=UnionTypeName,
|
||
samasat_discharge_percentage=samasat_discharge_percentage,
|
||
CertId=CertId,
|
||
predicate_date=date + timedelta(
|
||
days=poultry.killing_ave_age) if poultry.killing_ave_age > 1 else None,
|
||
|
||
)
|
||
hatching.chicken_age = (datetime.datetime.now().date() - hatching.date.date()).days + 1
|
||
hatching.save()
|
||
else:
|
||
last_hatchings = hatch.first()
|
||
last_hatchings.date = date
|
||
last_hatchings.quantity = hatching_quantity
|
||
last_hatchings.losses = losses
|
||
last_hatchings.PersonTypeName = PersonTypeName
|
||
last_hatchings.InteractTypeName = InteractTypeName
|
||
last_hatchings.UnionTypeName = UnionTypeName
|
||
last_hatchings.chicken_age = (datetime.datetime.now().date() - last_hatchings.date.date()).days + 1
|
||
last_hatchings.samasat_discharge_percentage = samasat_discharge_percentage
|
||
last_hatchings.predicate_date = date + timedelta(
|
||
days=last_hatchings.poultry.killing_ave_age) if last_hatchings.poultry.killing_ave_age > 1 else None
|
||
last_hatchings.save()
|
||
update = LastUpdate.objects.first()
|
||
update.update_date = datetime.datetime.now()
|
||
update.save()
|
||
except:
|
||
not_find_list.append(breeding_uniq_id)
|
||
|
||
# poultry = Poultry.objects.filter(breeding_unique_id=breeding_uniq_id).first()
|
||
# try:
|
||
# if not poultry:
|
||
# first_name = data['poultry']['FirstName']
|
||
# last_name = data['poultry']['LastName']
|
||
# mobile = data['poultry']['Mobile']
|
||
# system_profile = SystemUserProfile.objects.filter(mobile=mobile, trash=False).first()
|
||
# if not system_profile:
|
||
#
|
||
# data = {
|
||
# "username": mobile,
|
||
# "first_name": first_name,
|
||
# "last_name": last_name,
|
||
# "password": '123456',
|
||
# "national_code": '0',
|
||
# "role": "Poultry",
|
||
# "api_key": PROJECT_API_KEY
|
||
# }
|
||
# req = requests.post(
|
||
# url=ARTA_REGISTER,
|
||
# data=data,
|
||
# verify=False
|
||
# )
|
||
#
|
||
# if req.status_code == 200:
|
||
# hashed_password = hashlib.sha256(str('123456').encode()).hexdigest()
|
||
# user = User.objects.filter(username=mobile).first()
|
||
# if not user:
|
||
# user = User(username=mobile, first_name=first_name, last_name=last_name,
|
||
# password=hashed_password)
|
||
# user.save()
|
||
# base_id = SystemUserProfile.objects.all()
|
||
# if base_id.count() > 0:
|
||
# base_id = int(base_id.last().base_order) + 1
|
||
# else:
|
||
# base_id = 1000
|
||
# system_profile = SystemUserProfile(
|
||
# mobile=mobile,
|
||
# first_name=str(first_name),
|
||
# last_name=str(last_name),
|
||
# fullname=str(first_name) + ' ' + str(last_name),
|
||
# user=user,
|
||
# base_order=base_id,
|
||
# password='123456',
|
||
# birthday=str(datetime.datetime.now().date()),
|
||
# )
|
||
# system_profile.save()
|
||
#
|
||
# else:
|
||
# continue
|
||
#
|
||
# group = Group.objects.get(name__exact="Poultry")
|
||
# if not system_profile.role.filter(name="Poultry"):
|
||
# system_profile.role.add(group)
|
||
#
|
||
# wallet = Wallet()
|
||
# wallet.save()
|
||
# poultry = Poultry(
|
||
# user=system_profile,
|
||
# unit_name=poultry_name,
|
||
# system_code=data.get('poultry', {}).get('SystemCode',None),
|
||
# epidemiological_code=data.get('poultry', {}).get('EpidemiologicCode',None),
|
||
# breeding_unique_id=breeding_uniq_id,
|
||
# )
|
||
# province=Province.objects.filter(trash=False,name__exact=province).first()
|
||
# city=City.objects.filter(trash=False,name__exact=city).first()
|
||
# address = SystemAddress(
|
||
# province=province,
|
||
# city=city,
|
||
# address=city
|
||
# )
|
||
# address.save()
|
||
# poultry.address = address
|
||
# poultry.user = system_profile
|
||
# poultry.wallet = wallet
|
||
# poultry.save()
|
||
#
|
||
# poultry.unit_name = poultry_name
|
||
# poultry.save()
|
||
# hatch = PoultryHatching.objects.filter(trash=False, poultry=poultry).order_by('id')
|
||
# if hatch:
|
||
# period = hatch.last().period + 1
|
||
# else:
|
||
# period = 1
|
||
#
|
||
# # hatching_date = data['HatchingDatePersian'].split('/')
|
||
# date = data['Date']
|
||
#
|
||
# poultry_hatching = hatch.filter(trash=False,archive=False, state='pending',
|
||
# allow_hatching='pending').order_by('id')
|
||
#
|
||
# if not poultry_hatching.exists():
|
||
# if not hatch.filter(archive=True, state='complete',
|
||
# allow_hatching="True",licence_number=licence_number).exists():
|
||
# hatching = PoultryHatching(
|
||
# poultry=poultry,
|
||
# date=date,
|
||
# quantity=hatching_quantity,
|
||
# breed=[
|
||
# {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
# period=period,
|
||
# chicken_breed=data["PedigreeName"],
|
||
# hall=1,
|
||
# left_over=hatching_quantity,
|
||
# latest_hatching_change={
|
||
# "role": "UnitWindow",
|
||
# "date": str(datetime.datetime.now().date()),
|
||
# "full_name": ""
|
||
# },
|
||
# licence_number=licence_number,
|
||
# breeding_unique_id=breeding_uniq_id,
|
||
# losses=losses,
|
||
#
|
||
# )
|
||
# hatching.save()
|
||
#
|
||
# else:
|
||
# previouse_hatching = poultry_hatching.last()
|
||
#
|
||
# hatchings = poultry_hatching.filter(licence_number=licence_number)
|
||
# if not hatchings:
|
||
# if previouse_hatching.left_over > (previouse_hatching.quantity * percent_of_losses):
|
||
# previouse_hatching.violation = True
|
||
# previouse_hatching.save()
|
||
#
|
||
# hatching = PoultryHatching(
|
||
# poultry=poultry,
|
||
# date=date,
|
||
# quantity=hatching_quantity,
|
||
# breed=[
|
||
# {"breed": 'آرین', "main_quantity": hatching_quantity, "remain_quantity": hatching_quantity}],
|
||
# period=period,
|
||
# chicken_breed=data["PedigreeName"],
|
||
# hall=1,
|
||
# left_over=hatching_quantity,
|
||
# latest_hatching_change={
|
||
# "role": "UnitWindow",
|
||
# "date": str(datetime.datetime.now().date()),
|
||
# "full_name": ""
|
||
# },
|
||
# licence_number=licence_number,
|
||
# breeding_unique_id=breeding_uniq_id,
|
||
# losses=losses,
|
||
#
|
||
# )
|
||
# hatching.save()
|
||
# else:
|
||
# last_hatchings=hatchings.first()
|
||
# # if last_hatchings.health_certificate is None:
|
||
# # last_hatchings.health_certificate=health_certificate
|
||
# last_hatchings.date = date
|
||
# last_hatchings.quantity = hatching_quantity
|
||
# last_hatchings.losses = losses
|
||
# last_hatchings.save()
|
||
#
|
||
# update = LastUpdate.objects.first()
|
||
# update.update_date = datetime.datetime.now()
|
||
# update.save()
|
||
# except:
|
||
# not_find_list.append(breeding_uniq_id)
|
||
if not_find_list:
|
||
token = "bot291669:9298e675-8b3c-4b8f-a69d-5c89a3f0bdde"
|
||
chat_id = '10046800'
|
||
url = f'https://eitaayar.ir/api/{token}/sendMessage'
|
||
base_message = f'{base_url_for_sms_report}' \
|
||
'\n'
|
||
messages = []
|
||
current_message = base_message
|
||
new_message_part = ','.join(not_find_list)
|
||
if len(current_message) + len(new_message_part) > 4000: # محدودیت تعداد کاراکترها
|
||
messages.append(current_message)
|
||
current_message = base_message # شروع یک پیام جدید
|
||
|
||
current_message += new_message_part
|
||
|
||
if current_message and current_message != base_message:
|
||
messages.append(current_message)
|
||
for message in messages:
|
||
data = {
|
||
'chat_id': chat_id,
|
||
'text': message,
|
||
}
|
||
r = requests.post(url, data=data, verify=False)
|
||
|
||
|
||
def fix_bar_without_quarantine(request):
|
||
kill_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False,
|
||
quarantine_code_state__isnull=False).only('clearance_code')
|
||
print(len(kill_request))
|
||
for kill in kill_request:
|
||
get_gid(kill.clearance_code)
|
||
return HttpResponse('ok')
|
||
|
||
|
||
def get_gid_out_province(id):
|
||
kill = KillHouseFreeSaleBarInformation.objects.get(id=id, trash=False)
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kill:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
# kill.quarantine_code_state = 'notconfirmed'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_weight_of_carcasses = None
|
||
pass
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
send_date = kill.date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
# kill.inquiry_date = date.date()
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[0:1]:
|
||
|
||
quantity = r.find_all('td')[1]
|
||
match = re.search(r'\d+', quantity.text)
|
||
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_weight_of_carcasses = int(number)
|
||
# if kill.quarantine_code_state is not None:
|
||
# kill.quarantine_code_state=None
|
||
else:
|
||
kill.quarantine_weight_of_carcasses = 0
|
||
# for i in table[4:5]:
|
||
# rows = i.find_all('tr')
|
||
#
|
||
# pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
# style='font-family:Tahoma').text.strip()
|
||
# kill.inquiry_pelak=pelak_txt
|
||
# td=rows[1].find_all('td')[1]
|
||
# driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_driver=driver_txt
|
||
#
|
||
# for r in rows:
|
||
# tds = r.find_all('td', colspan="2")
|
||
# if len(tds) >= 2:
|
||
# origin_td = tds[0]
|
||
# origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_origin=origin_text
|
||
#
|
||
# destination_td = tds[1]
|
||
# destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_destination=destination_text
|
||
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
# kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_weight_of_carcasses > 0:
|
||
kill.quarantine_weight_of_carcasses = 0
|
||
kill.save()
|
||
|
||
|
||
def get_gid_out_province_cron_job():
|
||
kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0,
|
||
clearance_code__isnull=False, trash=False)
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kills:
|
||
for kill in kills:
|
||
try:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
# kill.quarantine_code_state = 'notconfirmed'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_weight_of_carcasses = None
|
||
pass
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
# kill.inquiry_date = date.date()
|
||
if kill.date:
|
||
send_date = kill.date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[0:1]:
|
||
|
||
quantity = r.find_all('td')[1]
|
||
match = re.search(r'\d+', quantity.text)
|
||
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_weight_of_carcasses = int(number)
|
||
# if kill.quarantine_code_state is not None:
|
||
# kill.quarantine_code_state=None
|
||
else:
|
||
kill.quarantine_weight_of_carcasses = 0
|
||
# for i in table[4:5]:
|
||
# rows = i.find_all('tr')
|
||
#
|
||
# pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
# style='font-family:Tahoma').text.strip()
|
||
# kill.inquiry_pelak=pelak_txt
|
||
# td=rows[1].find_all('td')[1]
|
||
# driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_driver=driver_txt
|
||
#
|
||
# for r in rows:
|
||
# tds = r.find_all('td', colspan="2")
|
||
# if len(tds) >= 2:
|
||
# origin_td = tds[0]
|
||
# origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_origin=origin_text
|
||
#
|
||
# destination_td = tds[1]
|
||
# destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_destination=destination_text
|
||
|
||
# else:
|
||
# for table in table:
|
||
# p_tags = table.find_all('p')
|
||
# for p in p_tags:
|
||
# p_text = p.get_text(strip=True)
|
||
# if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
# kill.quarantine_code_state = 'contradiction'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_quantity = None
|
||
kill.save()
|
||
except Exception:
|
||
continue
|
||
|
||
|
||
def get_gid_out_province_manual(request):
|
||
kills = KillHouseFreeSaleBarInformation.objects.filter(quarantine_weight_of_carcasses=0,
|
||
clearance_code__isnull=False, trash=False)
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kills:
|
||
for kill in kills:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
# kill.quarantine_code_state = 'notconfirmed'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_weight_of_carcasses = None
|
||
pass
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
# kill.inquiry_date = date.date()
|
||
send_date = kill.date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[0:1]:
|
||
|
||
quantity = r.find_all('td')[1]
|
||
match = re.search(r'\d+', quantity.text)
|
||
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_weight_of_carcasses = int(number)
|
||
# if kill.quarantine_code_state is not None:
|
||
# kill.quarantine_code_state=None
|
||
else:
|
||
kill.quarantine_weight_of_carcasses = 0
|
||
# for i in table[4:5]:
|
||
# rows = i.find_all('tr')
|
||
#
|
||
# pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
# style='font-family:Tahoma').text.strip()
|
||
# kill.inquiry_pelak=pelak_txt
|
||
# td=rows[1].find_all('td')[1]
|
||
# driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_driver=driver_txt
|
||
#
|
||
# for r in rows:
|
||
# tds = r.find_all('td', colspan="2")
|
||
# if len(tds) >= 2:
|
||
# origin_td = tds[0]
|
||
# origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_origin=origin_text
|
||
#
|
||
# destination_td = tds[1]
|
||
# destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_destination=destination_text
|
||
|
||
# else:
|
||
# for table in table:
|
||
# p_tags = table.find_all('p')
|
||
# for p in p_tags:
|
||
# p_text = p.get_text(strip=True)
|
||
# if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
# kill.quarantine_code_state = 'contradiction'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_quantity = None
|
||
kill.save()
|
||
return HttpResponse(f'تعداد بار :{len(kills)}')
|
||
|
||
|
||
def get_gid_poultry_request(poultry_id):
|
||
kill = PoultryRequest.objects.filter(id=poultry_id, trash=False).first()
|
||
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kill:
|
||
# if kill.quarantine_code_state!='merge':
|
||
data = {'gid': str(kill.quarantine_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
kill.quarantine_code_state = 'notconfirmed'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
# kill.inquiry_date = date.date()
|
||
send_date = kill.send_date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_quantity = int(number)
|
||
# if kill.quarantine_code_state is not None:
|
||
# kill.quarantine_code_state=None
|
||
# for i in table[4:5]:
|
||
# rows = i.find_all('tr')
|
||
#
|
||
# pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
# style='font-family:Tahoma').text.strip()
|
||
# kill.inquiry_pelak=pelak_txt
|
||
# td=rows[1].find_all('td')[1]
|
||
# driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_driver=driver_txt
|
||
#
|
||
# for r in rows:
|
||
# tds = r.find_all('td', colspan="2")
|
||
# if len(tds) >= 2:
|
||
# origin_td = tds[0]
|
||
# origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_origin=origin_text
|
||
#
|
||
# destination_td = tds[1]
|
||
# destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_destination=destination_text
|
||
else:
|
||
kill.quarantine_quantity = 0
|
||
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
# kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_quantity > 0:
|
||
kill.quarantine_quantity = 0
|
||
kill.save()
|
||
|
||
|
||
def get_gid_poultry_request_quarantine_code(poultry_id):
|
||
kill = PoultryRequestQuarantineCode.objects.filter(id=poultry_id, trash=False).first()
|
||
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
if kill:
|
||
# if kill.quarantine_code_state!='merge':
|
||
data = {'gid': str(kill.quarantine_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
# kill.quarantine_code_state = 'notconfirmed'
|
||
# if kill.quarantine_quantity is not None:
|
||
# kill.quarantine_quantity = None
|
||
if kill.system_quarantine_quantity > 0:
|
||
kill.system_quarantine_quantity = 0
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
# kill.inquiry_date = date.date()
|
||
send_date = kill.poultry_request.send_date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.system_quarantine_quantity = int(number)
|
||
# if kill.quarantine_code_state is not None:
|
||
# kill.quarantine_code_state=None
|
||
# for i in table[4:5]:
|
||
# rows = i.find_all('tr')
|
||
#
|
||
# pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
# style='font-family:Tahoma').text.strip()
|
||
# kill.inquiry_pelak=pelak_txt
|
||
# td=rows[1].find_all('td')[1]
|
||
# driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_driver=driver_txt
|
||
#
|
||
# for r in rows:
|
||
# tds = r.find_all('td', colspan="2")
|
||
# if len(tds) >= 2:
|
||
# origin_td = tds[0]
|
||
# origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_origin=origin_text
|
||
#
|
||
# destination_td = tds[1]
|
||
# destination_text = destination_td.find('span', class_='dynamictxt').text.strip()
|
||
# kill.inquiry_destination=destination_text
|
||
else:
|
||
kill.system_quarantine_quantity = 0
|
||
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
# kill.quarantine_code_state = 'contradiction'
|
||
if kill.system_quarantine_quantity > 0:
|
||
kill.system_quarantine_quantity = 0
|
||
kill.save()
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([TokenHasReadWriteScope])
|
||
@csrf_exempt
|
||
def dashboard_monitoring_view(request):
|
||
now = datetime.datetime.now().date()
|
||
yesterday = now - timedelta(days=1)
|
||
hatching = PoultryHatching.objects.filter(
|
||
state='pending',
|
||
archive=False,
|
||
allow_hatching='pending',
|
||
trash=False
|
||
).only(
|
||
'quantity',
|
||
'killed_quantity',
|
||
'left_over',
|
||
'chicken_age',
|
||
'poultry'
|
||
).select_related('poultry')
|
||
|
||
hatching_aggregates = hatching.aggregate(
|
||
total_quantity=Sum('quantity'),
|
||
total_killed_quantity=Sum('killed_quantity'),
|
||
total_left_over=Sum('left_over'),
|
||
total_left_over_between_40_75=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(40, 75))
|
||
),
|
||
|
||
#
|
||
total_left_over_lt_35=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__lt=35)
|
||
),
|
||
total_left_over_between_35_40=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(35, 39))
|
||
),
|
||
total_left_over_between_40_45=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(40, 44))
|
||
),
|
||
total_left_over_between_45_50=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(45, 49))
|
||
),
|
||
total_left_over_between_50_55=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(50, 54))
|
||
),
|
||
total_left_over_between_55_60=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(55, 59))
|
||
),
|
||
total_left_over_between_60_65=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(60, 64))
|
||
),
|
||
total_left_over_between_65_70=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__range=(65, 70))
|
||
),
|
||
total_left_over_gt_70=Sum(
|
||
'left_over',
|
||
filter=Q(chicken_age__gt=70)
|
||
),
|
||
#
|
||
total_killing_ave_age=Avg('poultry__killing_ave_age')
|
||
)
|
||
|
||
kill_house_free_bar = KillHouseFreeBarInformation.objects.filter(
|
||
trash=False,
|
||
archive_wage=False,
|
||
date__date__gte=yesterday
|
||
).only(
|
||
'quantity',
|
||
'live_weight',
|
||
'number_of_carcasses',
|
||
'weight_of_carcasses',
|
||
'send_date',
|
||
'type',
|
||
'out'
|
||
)
|
||
|
||
kill_house_free_bar_aggregates = kill_house_free_bar.aggregate(
|
||
total_quantity_yesterday_live=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')),
|
||
total_weight_yesterday_live=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')),
|
||
total_quantity_yesterday_carcass=Sum('number_of_carcasses',
|
||
filter=Q(date__date=yesterday, buy_type='carcass')),
|
||
total_weight_yesterday_carcass=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')),
|
||
|
||
total_quantity_live=Sum('quantity', filter=Q(create_date__date=now, buy_type='live')),
|
||
total_weight_live=Sum('live_weight', filter=Q(create_date__date=now, buy_type='live')),
|
||
total_quantity_carcass=Sum('number_of_carcasses',
|
||
filter=Q(date__date=now, buy_type='carcass')),
|
||
total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now, buy_type='carcass')),
|
||
warehouse_total_weight_carcass=Sum('weight_of_carcasses', filter=Q(date__date=now)),
|
||
# yesterday
|
||
total_quantity_live_yesterday=Sum('quantity', filter=Q(create_date__date=yesterday, buy_type='live')),
|
||
total_weight_live_yesterday=Sum('live_weight', filter=Q(create_date__date=yesterday, buy_type='live')),
|
||
total_quantity_carcass_yesterday=Sum('number_of_carcasses',
|
||
filter=Q(date__date=yesterday, buy_type='carcass')),
|
||
total_weight_carcass_yesterday=Sum('weight_of_carcasses', filter=Q(date__date=yesterday, buy_type='carcass')),
|
||
|
||
)
|
||
|
||
poultry_request = PoultryRequest.objects.filter(
|
||
trash=False,
|
||
state_process__in=('pending', 'accepted'),
|
||
province_state__in=('pending', 'accepted'),
|
||
out_province_request_cancel=False,
|
||
temporary_trash=False,
|
||
temporary_deleted=False,
|
||
send_date__date__gte=yesterday
|
||
).only(
|
||
'quantity',
|
||
'Index_weight',
|
||
'send_date'
|
||
)
|
||
|
||
poultry_request_aggregates = poultry_request.aggregate(
|
||
total_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=False, out=False)),
|
||
total_weight=Sum(F('quantity') * F('Index_weight'),
|
||
filter=Q(send_date__date=now, direct_buying=False, out=False)),
|
||
total_direct_buying_quantity=Sum('quantity', filter=Q(send_date__date=now, direct_buying=True)),
|
||
total_direct_buying_weight=Sum(F('quantity') * F('Index_weight'),
|
||
filter=Q(send_date__date=now, direct_buying=True)),
|
||
total_quantity_out_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)),
|
||
poultry_out_province_quantity=Sum('quantity', filter=Q(out=True, send_date__date=now)),
|
||
poultry_out_province_weight=Sum(F('quantity') * F('Index_weight'), filter=Q(out=True, send_date__date=now)),
|
||
total_killing_ave_weight=Avg('Index_weight', filter=Q(send_date__date=now)),
|
||
# yesterday
|
||
total_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=False, out=False)),
|
||
total_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
|
||
filter=Q(send_date__date=yesterday, direct_buying=False, out=False)),
|
||
total_direct_buying_quantity_yesterday=Sum('quantity', filter=Q(send_date__date=yesterday, direct_buying=True)),
|
||
total_direct_buying_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
|
||
filter=Q(send_date__date=yesterday, direct_buying=True)),
|
||
poultry_out_province_quantity_yesterday=Sum('quantity', filter=Q(out=True, send_date__date=yesterday)),
|
||
poultry_out_province_weight_yesterday=Sum(F('quantity') * F('Index_weight'),
|
||
filter=Q(out=True, send_date__date=yesterday)),
|
||
total_killing_ave_weight_yesterday=Avg('Index_weight', filter=Q(send_date__date=now))
|
||
)
|
||
|
||
province_kill_request = ProvinceKillRequest.objects.filter(
|
||
trash=False,
|
||
archive_wage=False,
|
||
return_to_province=False,
|
||
state__in=('pending', 'accepted'),
|
||
kill_request__recive_date__date__gte=yesterday
|
||
).only(
|
||
'total_killed_quantity',
|
||
'total_killed_weight',
|
||
'kill_request__recive_date'
|
||
)
|
||
|
||
province_kill_request_aggregates = province_kill_request.aggregate(
|
||
total_quantity_yesterday=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=yesterday)),
|
||
total_weight_yesterday=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=yesterday)),
|
||
total_quantity=Sum('total_killed_quantity', filter=Q(kill_request__recive_date__date=now)),
|
||
total_weight_carcass=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)) * 0.75,
|
||
province_kill_request_total_weight=Sum('total_killed_weight', filter=Q(kill_request__recive_date__date=now)),
|
||
province_kill_request_total_weight_yesterday=Sum('total_killed_weight',
|
||
filter=Q(kill_request__recive_date__date=yesterday))
|
||
)
|
||
|
||
kill_house_request = KillHouseRequest.objects.filter(
|
||
trash=False,
|
||
kill_request__recive_date__date__gte=yesterday,
|
||
temporary_trash=False,
|
||
temporary_deleted=False
|
||
).select_related('kill_request').only(
|
||
'ware_house_accepted_real_weight',
|
||
'weight_loss',
|
||
'ware_house_confirmation',
|
||
'kill_request__recive_date'
|
||
)
|
||
|
||
kill_house_request_aggregates = kill_house_request.aggregate(
|
||
total_real_weight=Sum(
|
||
'ware_house_accepted_real_weight',
|
||
filter=Q(
|
||
kill_request__recive_date__date=yesterday,
|
||
ware_house_confirmation=True
|
||
)
|
||
),
|
||
total_weight_loss=Avg(
|
||
'weight_loss',
|
||
filter=Q(kill_request__recive_date__date=yesterday)
|
||
),
|
||
total_quantity=Sum(
|
||
'accepted_real_quantity',
|
||
filter=Q(kill_request__recive_date__date=now)
|
||
),
|
||
total_quantity_yesterday=Sum(
|
||
'accepted_real_quantity',
|
||
filter=Q(kill_request__recive_date__date=yesterday)
|
||
),
|
||
total_weight_yesterday=Sum(
|
||
'accepted_real_weight',
|
||
filter=Q(kill_request__recive_date__date=yesterday)
|
||
),
|
||
total_weight=Sum(
|
||
'accepted_real_weight',
|
||
filter=Q(kill_request__recive_date__date=now)
|
||
),
|
||
total_real_weight_yesterday=Sum(
|
||
'ware_house_accepted_real_weight',
|
||
filter=Q(
|
||
kill_request__recive_date__date=yesterday,
|
||
ware_house_confirmation=True
|
||
)
|
||
)
|
||
)
|
||
|
||
kill_request = KillRequest.objects.filter(
|
||
recive_date__date=now,
|
||
trash=False,
|
||
poultry__isnull=True,
|
||
province_state='accepted'
|
||
).only(
|
||
'kill_capacity',
|
||
'recive_date',
|
||
'province_state'
|
||
)
|
||
|
||
kill_request_aggregates = kill_request.aggregate(
|
||
total_quantity=Sum('kill_capacity'),
|
||
)
|
||
|
||
if hatching_aggregates['total_left_over_between_40_75'] and poultry_request_aggregates['total_killing_ave_weight']:
|
||
weight_between_forty_seventy_five = int(hatching_aggregates['total_left_over_between_40_75'] *
|
||
poultry_request_aggregates['total_killing_ave_weight'])
|
||
else:
|
||
weight_between_forty_seventy_five = 0
|
||
|
||
enter_warehouse_weight = (kill_house_free_bar_aggregates['warehouse_total_weight_carcass'] or 0) + (
|
||
kill_house_request_aggregates['total_real_weight_yesterday'] or 0)
|
||
roles_product = RolesProducts.objects.filter(trash=False)
|
||
|
||
roles_product_aggregates = roles_product.aggregate(
|
||
total_remain_weight=Sum('total_remain_weight'),
|
||
total_out_province_allocated_weight=Sum('out_province_allocated_weight'),
|
||
)
|
||
|
||
cold_house = ColdHouse.objects.filter(trash=False).only(
|
||
'total_remain_weight'
|
||
)
|
||
|
||
cold_house_aggregates = cold_house.aggregate(
|
||
total_freezing_weight=Sum('total_remain_weight')
|
||
)
|
||
kill_house_free_sale_bar_aggregates = KillHouseFreeSaleBarInformation.objects.filter(
|
||
trash=False
|
||
).aggregate(
|
||
total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'),
|
||
total_real_weight_of_carcasses_now=Sum('real_weight_of_carcasses', filter=Q(date__date=now))
|
||
)
|
||
steward_allocation = StewardAllocation.objects.filter(
|
||
trash=False,
|
||
calculate_status=True,
|
||
temporary_trash=False,
|
||
temporary_deleted=False,
|
||
receiver_state__in=('accepted', 'pending')
|
||
).exclude(
|
||
seller_type='ColdHouse'
|
||
).only(
|
||
'real_weight_of_carcasses',
|
||
'date'
|
||
)
|
||
|
||
steward_allocation_aggregates = steward_allocation.aggregate(
|
||
total_real_weight_of_carcasses=Sum('real_weight_of_carcasses'),
|
||
total_real_weight_of_carcasses_now=Sum(
|
||
'real_weight_of_carcasses',
|
||
filter=Q(date__date=now)
|
||
),
|
||
)
|
||
|
||
chicken_price = ChickenCommissionPrices.objects.filter(trash=False, date__date__gte=now - timedelta(7)).order_by(
|
||
'date')
|
||
ser_data = ChickenCommissionPricesForDashboardSerializer(chicken_price, many=True)
|
||
province_kill_request_weight = province_kill_request_aggregates['province_kill_request_total_weight'] or 0
|
||
province_kill_request_total_weight_yesterday = province_kill_request_aggregates[
|
||
'province_kill_request_total_weight_yesterday'] or 0
|
||
province_kill_request_weight_yesterday = province_kill_request_aggregates['total_weight_yesterday'] or 0
|
||
bars_live_weight = kill_house_free_bar_aggregates['total_weight_live'] or 0
|
||
total_weight_live_yesterday = kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0
|
||
bars_carcasses_weight = kill_house_free_bar_aggregates['total_weight_carcass'] or 0
|
||
total_weight_carcass_yesterday = kill_house_free_bar_aggregates['total_weight_carcass_yesterday'] or 0
|
||
bars_yesterday_carcasses_weight = kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0
|
||
bars_yesterday_live_weight = kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0
|
||
total_loss_weight = int(((province_kill_request_weight + bars_live_weight) * 0.75) + bars_carcasses_weight)
|
||
total_loss_weight_yesterday = int(((province_kill_request_total_weight_yesterday +
|
||
total_weight_live_yesterday) * 0.75) + total_weight_carcass_yesterday)
|
||
total_yesterday_loss_weight = int(((province_kill_request_weight_yesterday + bars_yesterday_live_weight)
|
||
* 0.75) + bars_yesterday_carcasses_weight)
|
||
|
||
result = {
|
||
'hatching': {
|
||
'quantity': hatching_aggregates['total_quantity'] or 0,
|
||
'killedQuantity': hatching_aggregates['total_killed_quantity'] or 0,
|
||
'leftOver': hatching_aggregates['total_left_over'] or 0,
|
||
'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0,
|
||
'killingAveAge': int(hatching_aggregates['total_killing_ave_age'] or 0),
|
||
'total_left_over_lt_35': int(hatching_aggregates['total_left_over_lt_35'] or 0),
|
||
'total_left_over_between_35_40': int(hatching_aggregates['total_left_over_between_35_40'] or 0),
|
||
'total_left_over_between_40_45': int(hatching_aggregates['total_left_over_between_40_45'] or 0),
|
||
'total_left_over_between_45_50': int(hatching_aggregates['total_left_over_between_45_50'] or 0),
|
||
'total_left_over_between_50_55': int(hatching_aggregates['total_left_over_between_50_55'] or 0),
|
||
'total_left_over_between_55_60': int(hatching_aggregates['total_left_over_between_55_60'] or 0),
|
||
'total_left_over_between_60_65': int(hatching_aggregates['total_left_over_between_60_65'] or 0),
|
||
'total_left_over_between_65_70': int(hatching_aggregates['total_left_over_between_65_70'] or 0),
|
||
'total_left_over_gt_70': int(hatching_aggregates['total_left_over_gt_70'] or 0),
|
||
},
|
||
'yesterdayKilling': {
|
||
'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_yesterday_live'] or 0,
|
||
'weightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_yesterday_live'] or 0,
|
||
'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_yesterday_carcass'] or 0,
|
||
'weightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_yesterday_carcass'] or 0,
|
||
'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity_yesterday'] or 0,
|
||
'provinceKillRequestWeight': province_kill_request_aggregates['total_weight_yesterday'] or 0,
|
||
'outQuantity': poultry_request_aggregates['total_quantity_out_yesterday'] or 0,
|
||
# 'weightOfCarcass': kill_house_request_aggregates['total_real_weight'] or 0,
|
||
# 'losses': round((kill_house_request_aggregates['total_weight_loss'] or 0),1),
|
||
'weightOfCarcass': total_yesterday_loss_weight,
|
||
'losses': 25,
|
||
|
||
},
|
||
'killing': {
|
||
'quantity': poultry_request_aggregates['total_quantity'] or 0,
|
||
'total_weight': poultry_request_aggregates['total_weight'] or 0,
|
||
'killRequestQuantity': poultry_request_aggregates['total_direct_buying_quantity'] or 0,
|
||
'killRequestWeight': poultry_request_aggregates['total_direct_buying_weight'] or 0,
|
||
# 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0,
|
||
'poultry_out_province_quantity': poultry_request_aggregates['poultry_out_province_quantity'] or 0,
|
||
'poultry_out_province_weight': poultry_request_aggregates['poultry_out_province_weight'] or 0,
|
||
'quantityKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_quantity_live'] or 0,
|
||
'WeightKillHouseFreeBarLive': kill_house_free_bar_aggregates['total_weight_live'] or 0,
|
||
'quantityKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_quantity_carcass'] or 0,
|
||
'WeightKillHouseFreeBarCarcass': kill_house_free_bar_aggregates['total_weight_carcass'] or 0,
|
||
'provinceKillRequestQuantity': province_kill_request_aggregates['total_quantity'] or 0,
|
||
'provinceKillRequestWeightCarcass': int(
|
||
province_kill_request_aggregates['province_kill_request_total_weight'] or 0),
|
||
'KillHouseRequestQuantity': kill_house_request_aggregates['total_quantity'] or 0,
|
||
'KillHouseRequestWeight': kill_house_request_aggregates['total_weight'] or 0,
|
||
'total_loss_weight': int(total_loss_weight),
|
||
|
||
},
|
||
'killingYesterday': {
|
||
'quantityYesterday': poultry_request_aggregates['total_quantity_yesterday'] or 0,
|
||
'total_weightYesterday': poultry_request_aggregates['total_weight_yesterday'] or 0,
|
||
'killRequestQuantityYesterday': poultry_request_aggregates['total_direct_buying_quantity_yesterday'] or 0,
|
||
'killRequestWeightYesterday': poultry_request_aggregates['total_direct_buying_weight_yesterday'] or 0,
|
||
# 'killRequestQuantity': kill_request_aggregates['total_quantity'] or 0,
|
||
'poultry_out_province_quantityYesterday': poultry_request_aggregates[
|
||
'poultry_out_province_quantity_yesterday'] or 0,
|
||
'poultry_out_province_weightYesterday': poultry_request_aggregates[
|
||
'poultry_out_province_weight_yesterday'] or 0,
|
||
'quantityKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates[
|
||
'total_quantity_live_yesterday'] or 0,
|
||
'WeightKillHouseFreeBarLiveYesterday': kill_house_free_bar_aggregates['total_weight_live_yesterday'] or 0,
|
||
'quantityKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[
|
||
'total_quantity_carcass_yesterday'] or 0,
|
||
'WeightKillHouseFreeBarCarcassYesterday': kill_house_free_bar_aggregates[
|
||
'total_weight_carcass_yesterday'] or 0,
|
||
'provinceKillRequestQuantityYesterday': province_kill_request_aggregates['total_quantity_yesterday'] or 0,
|
||
'provinceKillRequestWeightCarcassYesterday': int(
|
||
province_kill_request_aggregates['province_kill_request_total_weight_yesterday'] or 0),
|
||
'KillHouseRequestQuantityYesterday': kill_house_request_aggregates['total_quantity_yesterday'] or 0,
|
||
'KillHouseRequestWeightYesterday': kill_house_request_aggregates['total_weight_yesterday'] or 0,
|
||
'total_loss_weightYesterday': int(total_loss_weight_yesterday),
|
||
|
||
},
|
||
'inventory': {
|
||
'leftOverBetweenFortySeventyFive': hatching_aggregates['total_left_over_between_40_75'] or 0,
|
||
'weightBetweenFortySeventyFive': weight_between_forty_seventy_five,
|
||
'aveWeight': round((poultry_request_aggregates['total_killing_ave_weight'] or 0), 1),
|
||
'carcassWeight': int(weight_between_forty_seventy_five * 0.75),
|
||
|
||
},
|
||
'warehouseKillHouse': {
|
||
'remainingChickenStock': roles_product_aggregates['total_remain_weight'] or 0,
|
||
'remainingFreezingWeight': cold_house_aggregates['total_freezing_weight'] or 0,
|
||
'outProvinceAllocatedWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses'] or 0,
|
||
'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses'] or 0,
|
||
|
||
},
|
||
'warehouseInformation': {
|
||
'enterWarehouseWeight': enter_warehouse_weight,
|
||
'outSellWeight': kill_house_free_sale_bar_aggregates['total_real_weight_of_carcasses_now'] or 0,
|
||
'allocationWeight': steward_allocation_aggregates['total_real_weight_of_carcasses_now'] or 0,
|
||
'leftOverWarehouseWeight': roles_product_aggregates['total_remain_weight'] or 0,
|
||
|
||
},
|
||
'chickenPrice': ser_data.data
|
||
}
|
||
return Response(result, status=status.HTTP_200_OK)
|
||
|
||
|
||
def remove_access_token_manual(request):
|
||
ARTA_remove_access_token = "https://userbackend.rasadyar.com/api/remove_access_token/"
|
||
requests.get(
|
||
url=ARTA_remove_access_token,
|
||
verify=False
|
||
)
|
||
now = datetime.datetime.now()
|
||
accesses = AccessToken.objects.filter(created__date__gte=now.date() - timedelta(days=3))
|
||
for access in accesses:
|
||
access.expires = now - timedelta(days=2)
|
||
access.save()
|
||
return HttpResponse('ok')
|
||
|
||
|
||
def find_gid_code_manual(request):
|
||
kill_house_request = KillHouseRequest.objects.filter(trash=False, clearance_code__isnull=False,
|
||
quarantine_quantity__isnull=True).only(
|
||
'quarantine_code_state', 'clearance_code', 'quarantine_quantity'
|
||
).order_by('-id')
|
||
session = requests.Session()
|
||
session.mount('https://', SSLAdapter())
|
||
|
||
for kill in kill_house_request:
|
||
if kill.quarantine_code_state != 'merge':
|
||
if kill.clearance_code is None:
|
||
kill.quarantine_code_state = 'noclearance'
|
||
else:
|
||
data = {'gid': str(kill.clearance_code)}
|
||
m = session.post('https://e.ivo.ir/Rahgiri/Gidprnt.aspx', data=data, verify=False,
|
||
headers={
|
||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'})
|
||
context = BeautifulSoup(m.text, 'html.parser')
|
||
text = context.body.get_text(strip=True)
|
||
if text == 'فرآورده هاي خام داميGo Backفهرستخروجتاییده راهداری دریافت نشد به بخش اعلام خاتمه صدور گواهی بهداشتی حمل درهمین سایت مراجعه کنید.':
|
||
kill.quarantine_code_state = 'notconfirmed'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
else:
|
||
table = context.find_all('table')
|
||
if table[5:6]:
|
||
row = context.find('div', align="right")
|
||
if row:
|
||
content = row.get_text(separator=" ", strip=True)
|
||
date_match = re.search(r'تاريخ:(\d{4}/\d{2}/\d{2})', content)
|
||
|
||
if date_match:
|
||
jalali_date = date_match.group(1)
|
||
year, month, day = map(int, jalali_date.split('/'))
|
||
date = convert_to_miladi(year=year, month=month, day=day)
|
||
kill.inquiry_date = date.date()
|
||
send_date = kill.kill_request.recive_date.date()
|
||
|
||
one_day = timedelta(days=1)
|
||
if abs(send_date - date.date()) <= one_day:
|
||
for i in table[5:6]:
|
||
row = i.find_all('tr')
|
||
for r in row[1:2]:
|
||
quantity = r.find('td')
|
||
match = re.search(r'\d+', quantity.text)
|
||
if match:
|
||
number = match.group()
|
||
kill.quarantine_quantity = int(number)
|
||
if kill.quarantine_code_state is not None:
|
||
kill.quarantine_code_state = None
|
||
for i in table[4:5]:
|
||
rows = i.find_all('tr')
|
||
|
||
pelak_txt = rows[1].find('span', class_='dynamictxt', dir='ltr',
|
||
style='font-family:Tahoma').text.strip()
|
||
kill.inquiry_pelak = pelak_txt
|
||
td = rows[1].find_all('td')[1]
|
||
driver_txt = td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_driver = driver_txt
|
||
|
||
for r in rows:
|
||
tds = r.find_all('td', colspan="2")
|
||
if len(tds) >= 2:
|
||
origin_td = tds[0]
|
||
origin_text = origin_td.find('span', class_='dynamictxt').text.strip()
|
||
kill.inquiry_origin = origin_text
|
||
|
||
destination_td = tds[1]
|
||
destination_text = destination_td.find('span',
|
||
class_='dynamictxt').text.strip()
|
||
kill.inquiry_destination = destination_text
|
||
else:
|
||
kill.quarantine_code_state = 'contradiction'
|
||
kill.quarantine_quantity = None
|
||
|
||
else:
|
||
for table in table:
|
||
p_tags = table.find_all('p')
|
||
for p in p_tags:
|
||
p_text = p.get_text(strip=True)
|
||
if p_text == 'شماره رهگيري وارد شده معتبر نيست.':
|
||
kill.quarantine_code_state = 'contradiction'
|
||
if kill.quarantine_quantity is not None:
|
||
kill.quarantine_quantity = None
|
||
kill.save()
|
||
return HttpResponse('ok')
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def get_all_pos_transaction(request):
|
||
filters = {}
|
||
date1 = request.GET.get('date1')
|
||
date2 = request.GET.get('date2')
|
||
price_type = request.GET.get('price_type')
|
||
paid = request.GET.get('paid')
|
||
validator = PosDeviceValidator(request)
|
||
validation_error = validator.validation_version()
|
||
if validation_error:
|
||
return validation_error
|
||
|
||
validation_device = validator.validation_device()
|
||
if not validation_device:
|
||
return Response({"result": "نشست شما منقضی شده لطفا مجدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED)
|
||
|
||
pos = POSMachine.objects.get(pos_id=validation_device)
|
||
filters['trash'] = False
|
||
filters['pos'] = pos
|
||
|
||
if date1 and date2:
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
|
||
|
||
filters['date__date__gte'] = date1
|
||
filters['date__date__lte'] = date2
|
||
|
||
if price_type:
|
||
filters['price_type__in'] = price_type.split(',')
|
||
|
||
if paid:
|
||
filters['paid'] = True if paid == 'true' else False
|
||
|
||
transactions = PosMachineTransactions.objects.filter(**filters).only('price', 'price_type').order_by('-date')
|
||
product_transactions = ProductsTransactions.objects.filter(trash=False, transaction__in=transactions).only \
|
||
('price', 'cur_weight', 'targetunit', 'image')
|
||
|
||
transactions_aggregate = transactions.aggregate(
|
||
total_price=Sum('price'),
|
||
total_price_cash=Sum('price', filter=Q(price_type='cash')),
|
||
total_price_credit=Sum('price', filter=Q(price_type='credit')),
|
||
total_price_card=Sum('price', filter=Q(price_type='card')),
|
||
)
|
||
|
||
product_groups = defaultdict(lambda: {'price': 0, 'weight': 0, 'targetunit': None, 'image': None})
|
||
|
||
for pt in product_transactions:
|
||
product_groups[pt.name]['price'] += pt.price
|
||
product_groups[pt.name]['weight'] += pt.cur_weight
|
||
if not product_groups[pt.name]['targetunit']:
|
||
product_groups[pt.name]['targetunit'] = pt.targetunit
|
||
if not product_groups[pt.name]['image']:
|
||
product_groups[pt.name]['image'] = pt.image
|
||
|
||
unique_products = [{
|
||
'name': name,
|
||
'price': data['price'],
|
||
'weight': data['weight'],
|
||
'targetunit': data['targetunit'],
|
||
'image': data['image']
|
||
} for name, data in product_groups.items()]
|
||
|
||
result_dict = {
|
||
'count': transactions.count(),
|
||
'total_price': transactions_aggregate['total_price'] or 0,
|
||
'total_price_cash': transactions_aggregate['total_price_cash'] or 0,
|
||
'total_price_credit': transactions_aggregate['total_price_credit'] or 0,
|
||
'total_price_card': transactions_aggregate['total_price_card'] or 0,
|
||
'products': unique_products
|
||
}
|
||
|
||
return Response(result_dict)
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def send_clearance_code_to_rsi(request):
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
kill_house_request = KillHouseRequest.objects.filter(
|
||
trash=False,
|
||
temporary_trash=False,
|
||
temporary_deleted=False,
|
||
clearance_code__isnull=False
|
||
).values_list('clearance_code', flat=True).distinct()
|
||
|
||
kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
|
||
.values_list('quarantine_code', flat=True).distinct()
|
||
|
||
result = list(kill_house_request) + list(kill_house_free_sale)
|
||
|
||
response = requests.post(
|
||
f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}'
|
||
f'&date1={date1}&date2={date2}',
|
||
json=result,
|
||
headers={'Content-Type': 'application/json'}
|
||
)
|
||
|
||
output = BytesIO()
|
||
workbook = Workbook()
|
||
worksheet = workbook.active
|
||
workbook.remove(worksheet)
|
||
sheet_list = [
|
||
'بار های داخل استان',
|
||
'بار های خارج استان'
|
||
]
|
||
|
||
for sheet_name in sheet_list:
|
||
|
||
worksheet = workbook.create_sheet(sheet_name)
|
||
if sheet_name == 'بار های داخل استان':
|
||
|
||
worksheet.sheet_view.rightToLeft = True
|
||
worksheet.insert_rows(1)
|
||
cell = worksheet.cell(row=1, column=1)
|
||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||
|
||
header_list = [
|
||
'تعداد مرغداران',
|
||
'تعداد کشتارگاه ها',
|
||
'حجم کشتار',
|
||
|
||
]
|
||
create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000')
|
||
|
||
value_header_list = [
|
||
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
|
||
excel_options = [
|
||
'ردیف',
|
||
'تاریخ کشتار',
|
||
'مرغدار',
|
||
'شناسه یکتا مرغدار',
|
||
'شماره مجوز جوجه ریزی',
|
||
'شماره موبایل مرغدار',
|
||
'شهر مرغدار',
|
||
'دامپزشک فارم',
|
||
'تلفن دامپزشک فارم',
|
||
'کد قرنطینه',
|
||
'کشتارگاه',
|
||
'شناسه یکتا کشتارگاه',
|
||
'استان',
|
||
'شهر',
|
||
'حجم کشتار',
|
||
'سن کشتار',
|
||
|
||
]
|
||
|
||
m = 1
|
||
|
||
create_header_freez(worksheet, excel_options, 1, 6, 7, 20)
|
||
|
||
l = 7
|
||
unique_poultry_out_false = set()
|
||
unique_slaughterhouses_out_false = set()
|
||
total_slaughter_out_false = 0
|
||
excel_description(worksheet, 'A1', f'بارهای داخل استان', color='red',
|
||
row2='B1')
|
||
|
||
if 'date1' in request.GET:
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']),
|
||
'%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']),
|
||
'%Y-%m-%d').date()
|
||
from_date1 = shamsi_date(date1)
|
||
from_date2 = shamsi_date(date2)
|
||
excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3')
|
||
for data in response.json():
|
||
if data['Out'] == False:
|
||
vet_farm_mobile = ''
|
||
vet_farm_name = ''
|
||
vet_farm = VetFarm.objects.filter(trash=False,
|
||
poultry__breeding_unique_id=data['hatching']['poultry'][
|
||
'PartIdCode']).first()
|
||
if vet_farm:
|
||
vet_farm_mobile = vet_farm.vet.user.mobile
|
||
vet_farm_name = vet_farm.vet.user.fullname
|
||
unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
|
||
unique_slaughterhouses_out_false.add(data['DesUnitName'])
|
||
total_slaughter_out_false += data['GoodAmount']
|
||
date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ
|
||
date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
|
||
list1 = [
|
||
m,
|
||
str(shamsi_date(date, in_value=True)),
|
||
data['hatching']['poultry']['UnitName'],
|
||
data['hatching']['poultry']['PartIdCode'],
|
||
data['hatching']['RequestCode'],
|
||
data['hatching']['poultry']['Mobile'],
|
||
data['hatching']['poultry']['City'],
|
||
vet_farm_name,
|
||
vet_farm_mobile,
|
||
data['TrackingCode'],
|
||
data['DesUnitName'],
|
||
data['DesPartIdCode'],
|
||
data['Province'],
|
||
data['City'],
|
||
data['GoodAmount'],
|
||
data['Age'],
|
||
|
||
]
|
||
create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35)
|
||
|
||
l += 1
|
||
m += 1
|
||
value_header_list = [
|
||
len(unique_poultry_out_false),
|
||
len(unique_slaughterhouses_out_false),
|
||
total_slaughter_out_false
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
quantity = sum(
|
||
data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0
|
||
list2 = [
|
||
'مجموع==>',
|
||
'',
|
||
'',
|
||
'',
|
||
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
quantity,
|
||
'',
|
||
|
||
]
|
||
|
||
create_value(worksheet, list2, l + 1, 1, color='green')
|
||
else:
|
||
unique_poultry_out_false = set()
|
||
unique_slaughterhouses_out_false = set()
|
||
total_slaughter_out_false = 0
|
||
worksheet.sheet_view.rightToLeft = True
|
||
worksheet.insert_rows(1)
|
||
cell = worksheet.cell(row=1, column=1)
|
||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||
|
||
header_list = [
|
||
'تعداد مرغداران',
|
||
'تعداد کشتارگاه ها',
|
||
'حجم کشتار',
|
||
|
||
]
|
||
create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000')
|
||
|
||
excel_options = [
|
||
'ردیف',
|
||
'تاریخ کشتار',
|
||
'مرغدار',
|
||
'شناسه یکتا مرغدار',
|
||
'شماره مجوز جوجه ریزی',
|
||
'شماره موبایل مرغدار',
|
||
'شهر مرغدار',
|
||
'دامپزشک فارم',
|
||
'تلفن دامپزشک فارم',
|
||
'کد قرنطینه',
|
||
'کشتارگاه',
|
||
'شناسه یکتا کشتارگاه',
|
||
'استان',
|
||
'شهر',
|
||
'حجم کشتار',
|
||
'سن کشتار',
|
||
|
||
]
|
||
|
||
m = 1
|
||
|
||
create_header_freez(worksheet, excel_options, 1, 6, 7, 20)
|
||
|
||
l = 7
|
||
unique_poultry = set()
|
||
unique_slaughterhouses = set()
|
||
total_slaughter = 0
|
||
excel_description(worksheet, 'A1', f'بارهای خارج استان', color='red',
|
||
row2='B1')
|
||
|
||
if 'date1' in request.GET:
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']),
|
||
'%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']),
|
||
'%Y-%m-%d').date()
|
||
from_date1 = shamsi_date(date1)
|
||
from_date2 = shamsi_date(date2)
|
||
excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3')
|
||
for data in response.json():
|
||
if data['Out'] == True:
|
||
vet_farm_mobile = ''
|
||
vet_farm_name = ''
|
||
vet_farm = VetFarm.objects.filter(trash=False,
|
||
poultry__breeding_unique_id=data['hatching']['poultry'][
|
||
'PartIdCode']).first()
|
||
if vet_farm:
|
||
vet_farm_mobile = vet_farm.vet.user.mobile
|
||
vet_farm_name = vet_farm.vet.user.fullname
|
||
|
||
unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
|
||
unique_slaughterhouses_out_false.add(data['DesUnitName'])
|
||
total_slaughter_out_false += data['GoodAmount']
|
||
date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ
|
||
date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
|
||
list1 = [
|
||
m,
|
||
str(shamsi_date(date, in_value=True)),
|
||
data['hatching']['poultry']['UnitName'],
|
||
data['hatching']['poultry']['PartIdCode'],
|
||
data['hatching']['RequestCode'],
|
||
data['hatching']['poultry']['Mobile'],
|
||
data['hatching']['poultry']['City'],
|
||
vet_farm_mobile,
|
||
vet_farm_name,
|
||
data['TrackingCode'],
|
||
data['DesUnitName'],
|
||
data['DesPartIdCode'],
|
||
data['Province'],
|
||
data['City'],
|
||
data['GoodAmount'],
|
||
data['Age'],
|
||
|
||
]
|
||
create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35)
|
||
|
||
l += 1
|
||
m += 1
|
||
value_header_list = [
|
||
len(unique_poultry_out_false),
|
||
len(unique_slaughterhouses_out_false),
|
||
total_slaughter_out_false
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
quantity = sum(
|
||
data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0
|
||
list2 = [
|
||
'مجموع==>',
|
||
'',
|
||
'',
|
||
'',
|
||
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
quantity,
|
||
'',
|
||
|
||
]
|
||
|
||
create_value(worksheet, list2, l + 1, 1, color='green')
|
||
workbook.save(output)
|
||
output.seek(0)
|
||
|
||
response = HttpResponse(
|
||
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||
response[
|
||
'Content-Disposition'] = f'attachment; filename="اختلاف قرنطینه.xlsx"'.encode(
|
||
'utf-8')
|
||
response.write(output.getvalue())
|
||
return response
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def api_send_clearance_code_to_rsi(request):
|
||
page = ''
|
||
search_filter = ''
|
||
province = f'province={base_url_for_sms_report}'
|
||
search = request.GET.get('search')
|
||
value = request.GET.get('value')
|
||
if search:
|
||
if search != 'undefined' and value.strip():
|
||
search_filter = f'&search={search}&value={value}'
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
kill_house_request = KillHouseRequest.objects.filter(
|
||
trash=False,
|
||
temporary_trash=False,
|
||
temporary_deleted=False,
|
||
clearance_code__isnull=False
|
||
).values_list('clearance_code', flat=True).distinct()
|
||
|
||
kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
|
||
.values_list('quarantine_code', flat=True).distinct()
|
||
|
||
result = list(kill_house_request) + list(kill_house_free_sale)
|
||
if 'page' in request.GET:
|
||
page = f'&page={request.GET["page"]}&page_size={request.GET["page_size"]}'
|
||
|
||
response = requests.get(
|
||
f'https://rsibackend.rasadyar.com/app/api_send_different_bar/?{province}{page}'
|
||
f'{search_filter}'
|
||
f'&date1={date1}&date2={date2}',
|
||
json=result,
|
||
headers={'Content-Type': 'application/json'}
|
||
)
|
||
|
||
return Response(response.json(), status=status.HTTP_200_OK)
|
||
|
||
|
||
@api_view(["POST"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def create_steward_allocation_from_excel(request):
|
||
file = request.FILES['file'].read()
|
||
read = openpyxl.load_workbook(BytesIO(file), data_only=True)
|
||
sheet = read.active
|
||
result_list = []
|
||
for i, row in enumerate(sheet.iter_rows(values_only=True)):
|
||
if i <= 1:
|
||
continue
|
||
|
||
mobile = row[3]
|
||
kill_house_name = row[4]
|
||
allocation_type = row[5]
|
||
date = row[6]
|
||
sell_type = row[7]
|
||
seller_type = 'KillHouse'
|
||
type = 'manual'
|
||
weight_of_carcasses = row[8]
|
||
amount = row[9]
|
||
|
||
buyer_type = 'Steward' if allocation_type == 'مباشر' else 'Guild'
|
||
try:
|
||
miladi_date = date.split('/')
|
||
new_date = convert_to_miladi(
|
||
year=int(miladi_date[0]),
|
||
month=int(miladi_date[1]),
|
||
day=int(miladi_date[2])
|
||
)
|
||
kill_house = KillHouse.objects.filter(name=kill_house_name, trash=False).first()
|
||
user = SystemUserProfile.objects.filter(trash=False, mobile=mobile).first()
|
||
if user:
|
||
to_steward = None
|
||
to_guild = None
|
||
if buyer_type == 'Steward':
|
||
to_steward = Guilds.objects.get(user=user, trash=False)
|
||
else:
|
||
to_guild = Guilds.objects.get(user=user, trash=False)
|
||
product = RolesProducts.objects.get(kill_house=kill_house)
|
||
steward_allocation = StewardAllocation(
|
||
date=new_date,
|
||
real_weight_of_carcasses=weight_of_carcasses,
|
||
weight_of_carcasses=weight_of_carcasses,
|
||
product=product,
|
||
kill_house=kill_house,
|
||
seller_type=seller_type,
|
||
allocation_type='killhouse_guild' if allocation_type == 'صنف' else 'killhouse_steward',
|
||
sell_type='exclusive' if sell_type == 'اختصاصی' else 'free',
|
||
type=type,
|
||
amount=amount,
|
||
total_amount=int(amount * weight_of_carcasses),
|
||
)
|
||
if buyer_type == 'Steward':
|
||
steward_allocation.to_steward = to_steward
|
||
else:
|
||
steward_allocation.to_guilds = to_guild
|
||
steward_allocation.save()
|
||
kill_house_allocations_product_warehousing(product)
|
||
except:
|
||
result_list.append(mobile)
|
||
return Response(result_list)
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def send_bar_info_from_ticket(request):
|
||
user = SystemUserProfile.objects.get(trash=False, key=request.GET['key'])
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date()
|
||
kill_houses = KillHouse.objects.filter(trash=False, out_province=False).order_by('id')
|
||
kill_house_request = KillHouseRequest.objects.filter(trash=False,
|
||
kill_request__recive_date__date__gte=date1,
|
||
kill_request__recive_date__date__lte=date2,
|
||
temporary_trash=False, temporary_deleted=False)
|
||
if kill_house_request:
|
||
message = 'با سلام و احترام' \
|
||
'***' \
|
||
'بدینوسیله گزارش اسناد بارهای کشتارگاه ها از مورخه {0} تا {1} به شرح زیر بحضور ایفاد میگردد:' \
|
||
'***' \
|
||
'***'.format(shamsi_date(date1), shamsi_date(date2))
|
||
else:
|
||
message = 'با سلام و احترام' \
|
||
'***' \
|
||
' از مورخه {0} تا {1} باری وجود ندارد.' \
|
||
'***' \
|
||
'***'.format(shamsi_date(date1), shamsi_date(date2))
|
||
m = 1
|
||
for kill_house in kill_houses:
|
||
kill_house_request1 = kill_house_request.filter(trash=False, killhouse_user=kill_house,
|
||
kill_request__recive_date__date__gte=date1,
|
||
kill_request__recive_date__date__lte=date2,
|
||
temporary_trash=False, temporary_deleted=False)
|
||
bar_count = kill_house_request1.count()
|
||
bar_assigment_pending_count = kill_house_request1.filter(assignment_state_archive='pending').count()
|
||
bar_assigment_true_count = kill_house_request1.filter(assignment_state_archive='True').count()
|
||
bar_document_status = kill_house_request1.filter(bar_document_status__isnull=False).count()
|
||
bar_document_status_titles = kill_house_request1.values_list('bar_document_status__title', flat=True)
|
||
bars_info = []
|
||
if (None not in bar_document_status_titles and bar_document_status_titles) or (bar_assigment_pending_count != 0) \
|
||
or (bar_assigment_true_count > 0):
|
||
message += '{0}) {1} :' \
|
||
'تعداد {2} بار ایجاد شده است.***'.format(m, kill_house.name, to_locale_str(bar_count))
|
||
if bar_assigment_pending_count > 0 or bar_assigment_true_count > 0:
|
||
message += '📑 {1} بار دارای سند(بارنامه) و تعداد {0} بار فاقد سند(بارنامه) میباشد.*** '. \
|
||
format(to_locale_str(bar_assigment_pending_count), to_locale_str(bar_assigment_true_count))
|
||
if bar_document_status > 0:
|
||
message += '🌐 از بارهای دارای سند تعداد {0} بار توسط ربات هوش مصنوعی سامانه مورد بررسی قرار گرفت که به شرح زیر میباشد: '. \
|
||
format(to_locale_str(bar_document_status))
|
||
status_counts = Counter(bar_document_status_titles)
|
||
for title, count in status_counts.items():
|
||
if title:
|
||
bars_info.append(
|
||
'***' \
|
||
'🚛 {0} بار شامل سند ({1})'.format(to_locale_str(count), title))
|
||
|
||
if bars_info:
|
||
message += '.'.join(bars_info)
|
||
|
||
message += '***' \
|
||
'-------------------------------------------------------' \
|
||
'***' \
|
||
'***'
|
||
m += 1
|
||
|
||
new_ticket = TicketSupport(
|
||
user=user,
|
||
title="استعلام اسناد بارها از مورخه {0} تا {1}".format(shamsi_date(date1), shamsi_date(date2)),
|
||
status='open',
|
||
read_only=True,
|
||
type_ticket='single',
|
||
parent=None,
|
||
last_message='Admin',
|
||
)
|
||
new_ticket.save()
|
||
new_ticket.to_user.add(user)
|
||
msg = MessageSupport(
|
||
ticket=new_ticket,
|
||
message=message,
|
||
created_by=user,
|
||
sender='Admin'
|
||
)
|
||
msg.save()
|
||
return Response({'result': 'با موفقیت انجام شد.'}, status=status.HTTP_200_OK)
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def all_clearance_code_to_rsi(request):
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
# kill_house_request = KillHouseRequest.objects.filter(
|
||
# trash=False,
|
||
# temporary_trash=False,
|
||
# temporary_deleted=False,
|
||
# clearance_code__isnull=False
|
||
# ).values_list('clearance_code', flat=True).distinct()
|
||
#
|
||
# kill_house_free_sale = PoultryRequest.objects.filter(trash=False, quarantine_code__isnull=False, out=True) \
|
||
# .values_list('quarantine_code', flat=True).distinct()
|
||
|
||
result = []
|
||
|
||
response = requests.post(
|
||
f'https://rsibackend.rasadyar.com/app/send_different_bar/?province={base_url_for_sms_report}'
|
||
f'&date1={date1}&date2={date2}',
|
||
json=result,
|
||
headers={'Content-Type': 'application/json'}
|
||
)
|
||
|
||
output = BytesIO()
|
||
workbook = Workbook()
|
||
worksheet = workbook.active
|
||
workbook.remove(worksheet)
|
||
sheet_list = [
|
||
'بار های داخل استان',
|
||
'بار های خارج استان'
|
||
]
|
||
|
||
for sheet_name in sheet_list:
|
||
|
||
worksheet = workbook.create_sheet(sheet_name)
|
||
if sheet_name == 'بار های داخل استان':
|
||
|
||
worksheet.sheet_view.rightToLeft = True
|
||
worksheet.insert_rows(1)
|
||
cell = worksheet.cell(row=1, column=1)
|
||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||
|
||
header_list = [
|
||
'تعداد مرغداران',
|
||
'تعداد کشتارگاه ها',
|
||
'حجم کشتار',
|
||
|
||
]
|
||
create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000')
|
||
|
||
value_header_list = [
|
||
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
|
||
excel_options = [
|
||
'ردیف',
|
||
'تاریخ کشتار',
|
||
'مرغدار',
|
||
'شناسه یکتا مرغدار',
|
||
'شماره مجوز جوجه ریزی',
|
||
'شماره موبایل مرغدار',
|
||
'شهر مرغدار',
|
||
'دامپزشک فارم',
|
||
'تلفن دامپزشک فارم',
|
||
'کد قرنطینه',
|
||
'وضعیت بار',
|
||
'کشتارگاه',
|
||
'شناسه یکتا کشتارگاه',
|
||
'استان',
|
||
'شهر',
|
||
'حجم کشتار',
|
||
'سن کشتار',
|
||
|
||
]
|
||
|
||
m = 1
|
||
|
||
create_header_freez(worksheet, excel_options, 1, 6, 7, 20)
|
||
|
||
l = 7
|
||
unique_poultry_out_false = set()
|
||
unique_slaughterhouses_out_false = set()
|
||
total_slaughter_out_false = 0
|
||
excel_description(worksheet, 'A1', f'بارهای داخل استان', color='red',
|
||
row2='B1')
|
||
|
||
if 'date1' in request.GET:
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']),
|
||
'%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']),
|
||
'%Y-%m-%d').date()
|
||
from_date1 = shamsi_date(date1)
|
||
from_date2 = shamsi_date(date2)
|
||
excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3')
|
||
for data in response.json():
|
||
if data['Out'] == False:
|
||
vet_farm_mobile = ''
|
||
vet_farm_name = ''
|
||
vet_farm = VetFarm.objects.filter(trash=False,
|
||
poultry__breeding_unique_id=data['hatching']['poultry'][
|
||
'PartIdCode']).first()
|
||
if vet_farm:
|
||
vet_farm_mobile = vet_farm.vet.user.mobile
|
||
vet_farm_name = vet_farm.vet.user.fullname
|
||
unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
|
||
unique_slaughterhouses_out_false.add(data['DesUnitName'])
|
||
total_slaughter_out_false += data['GoodAmount']
|
||
date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ
|
||
date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
|
||
list1 = [
|
||
m,
|
||
str(shamsi_date(date, in_value=True)),
|
||
data['hatching']['poultry']['UnitName'],
|
||
data['hatching']['poultry']['PartIdCode'],
|
||
data['hatching']['RequestCode'],
|
||
data['hatching']['poultry']['Mobile'],
|
||
data['hatching']['poultry']['City'],
|
||
vet_farm_name,
|
||
vet_farm_mobile,
|
||
data['TrackingCode'],
|
||
data['TrackingStatusDescription'],
|
||
data['DesUnitName'],
|
||
data['DesPartIdCode'],
|
||
data['Province'],
|
||
data['City'],
|
||
data['GoodAmount'],
|
||
data['Age'],
|
||
|
||
]
|
||
create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35)
|
||
|
||
l += 1
|
||
m += 1
|
||
value_header_list = [
|
||
len(unique_poultry_out_false),
|
||
len(unique_slaughterhouses_out_false),
|
||
total_slaughter_out_false
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
quantity = sum(
|
||
data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0
|
||
list2 = [
|
||
'مجموع==>',
|
||
'',
|
||
'',
|
||
'',
|
||
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
quantity,
|
||
'',
|
||
|
||
]
|
||
|
||
create_value(worksheet, list2, l + 1, 1, color='green')
|
||
else:
|
||
unique_poultry_out_false = set()
|
||
unique_slaughterhouses_out_false = set()
|
||
total_slaughter_out_false = 0
|
||
worksheet.sheet_view.rightToLeft = True
|
||
worksheet.insert_rows(1)
|
||
cell = worksheet.cell(row=1, column=1)
|
||
cell.alignment = Alignment(horizontal='center', vertical='center')
|
||
|
||
header_list = [
|
||
'تعداد مرغداران',
|
||
'تعداد کشتارگاه ها',
|
||
'حجم کشتار',
|
||
|
||
]
|
||
create_header(worksheet, header_list, 4, 2, height=25, width=25, border_style='thin', color='C00000')
|
||
|
||
excel_options = [
|
||
'ردیف',
|
||
'تاریخ کشتار',
|
||
'مرغدار',
|
||
'شناسه یکتا مرغدار',
|
||
'شماره مجوز جوجه ریزی',
|
||
'شماره موبایل مرغدار',
|
||
'شهر مرغدار',
|
||
'دامپزشک فارم',
|
||
'تلفن دامپزشک فارم',
|
||
'کد قرنطینه',
|
||
'وضعیت بار',
|
||
'کشتارگاه',
|
||
'شناسه یکتا کشتارگاه',
|
||
'استان',
|
||
'شهر',
|
||
'حجم کشتار',
|
||
'سن کشتار',
|
||
|
||
]
|
||
|
||
m = 1
|
||
|
||
create_header_freez(worksheet, excel_options, 1, 6, 7, 20)
|
||
|
||
l = 7
|
||
unique_poultry = set()
|
||
unique_slaughterhouses = set()
|
||
total_slaughter = 0
|
||
excel_description(worksheet, 'A1', f'بارهای خارج استان', color='red',
|
||
row2='B1')
|
||
|
||
if 'date1' in request.GET:
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']),
|
||
'%Y-%m-%d').date()
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']),
|
||
'%Y-%m-%d').date()
|
||
from_date1 = shamsi_date(date1)
|
||
from_date2 = shamsi_date(date2)
|
||
excel_description(worksheet, 'A3', f'از تاریخ {from_date1} تا {from_date2}', color='red', row2='C3')
|
||
for data in response.json():
|
||
if data['Out'] == True:
|
||
vet_farm_mobile = ''
|
||
vet_farm_name = ''
|
||
vet_farm = VetFarm.objects.filter(trash=False,
|
||
poultry__breeding_unique_id=data['hatching']['poultry'][
|
||
'PartIdCode']).first()
|
||
if vet_farm:
|
||
vet_farm_mobile = vet_farm.vet.user.mobile
|
||
vet_farm_name = vet_farm.vet.user.fullname
|
||
|
||
unique_poultry_out_false.add(data['hatching']['poultry']['UnitName'])
|
||
unique_slaughterhouses_out_false.add(data['DesUnitName'])
|
||
total_slaughter_out_false += data['GoodAmount']
|
||
date_str = str(data['Date']).split('T')[0] # جدا کردن بخش تاریخ
|
||
date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
|
||
list1 = [
|
||
m,
|
||
str(shamsi_date(date, in_value=True)),
|
||
data['hatching']['poultry']['UnitName'],
|
||
data['hatching']['poultry']['PartIdCode'],
|
||
data['hatching']['RequestCode'],
|
||
data['hatching']['poultry']['Mobile'],
|
||
data['hatching']['poultry']['City'],
|
||
vet_farm_mobile,
|
||
vet_farm_name,
|
||
data['TrackingCode'],
|
||
data['TrackingStatusDescription'],
|
||
data['DesUnitName'],
|
||
data['DesPartIdCode'],
|
||
data['Province'],
|
||
data['City'],
|
||
data['GoodAmount'],
|
||
data['Age'],
|
||
|
||
]
|
||
create_value(worksheet, list1, l, 1, m=m, border_style='thin', height=35)
|
||
|
||
l += 1
|
||
m += 1
|
||
value_header_list = [
|
||
len(unique_poultry_out_false),
|
||
len(unique_slaughterhouses_out_false),
|
||
total_slaughter_out_false
|
||
]
|
||
create_value(worksheet, value_header_list, 3, 4, border_style='thin')
|
||
quantity = sum(
|
||
data['GoodAmount'] for data in response.json() if data['Out'] == False) or 0
|
||
list2 = [
|
||
'مجموع==>',
|
||
'',
|
||
'',
|
||
'',
|
||
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
'',
|
||
quantity,
|
||
'',
|
||
|
||
]
|
||
|
||
create_value(worksheet, list2, l + 1, 1, color='green')
|
||
workbook.save(output)
|
||
output.seek(0)
|
||
|
||
response = HttpResponse(
|
||
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||
response[
|
||
'Content-Disposition'] = f'attachment; filename="گزارش کلی بار ها.xlsx"'.encode(
|
||
'utf-8')
|
||
response.write(output.getvalue())
|
||
return response
|
||
|
||
|
||
@api_view(["GET"])
|
||
@permission_classes([AllowAny])
|
||
@csrf_exempt
|
||
def ticket_different_clearance_code_from_rsi(request):
|
||
date1 = datetime.datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
date2 = datetime.datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() if 'date1' in request.GET else None
|
||
poultry_hatchings_licence_numbers = PoultryHatching.objects.filter(trash=False,
|
||
licence_number=request.GET.get('licence_number'))
|
||
|
||
for poultry_hatching in poultry_hatchings_licence_numbers:
|
||
poultry_hatching_licence_number = poultry_hatching.licence_number
|
||
response = requests.post(
|
||
f'https://rsibackend.rasadyar.com/app/send_different_bar_with_licence_number/?'
|
||
f'licence_number={poultry_hatching_licence_number}'
|
||
f'&date1={date1}&date2={date2}',
|
||
headers={'Content-Type': 'application/json'}
|
||
)
|
||
kill_house_request = KillHouseRequest.objects.filter(trash=False,
|
||
province_request__poultry_request__hatching__licence_number
|
||
=poultry_hatching_licence_number,
|
||
temporary_trash=False,
|
||
temporary_deleted=False).order_by(
|
||
'-kill_request__recive_date')
|
||
if date1:
|
||
kill_house_request.filter(kill_request__recive_date__date__gte=date1,
|
||
kill_request__recive_date__date__lte=date2)
|
||
vet_farm = VetFarm.objects.filter(trash=False, poultry=poultry_hatching.poultry).first()
|
||
code_rasadyar = []
|
||
|
||
all_quantity_in_rsi = 0
|
||
for i in response.json():
|
||
all_quantity_in_rsi += i['GoodAmount']
|
||
bars_info = []
|
||
for kill_req in kill_house_request:
|
||
if kill_req.clearance_code:
|
||
quarantine_code = kill_req.clearance_code
|
||
code_rasadyar.append(quarantine_code)
|
||
|
||
else:
|
||
quarantine_code = 'ندارد'
|
||
bars_info.append(
|
||
'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
|
||
quarantine_code,
|
||
to_locale_str(int(kill_req.accepted_real_quantity)),
|
||
kill_req.killhouse_user.name,
|
||
shamsi_date(kill_req.kill_request.recive_date)
|
||
))
|
||
poultry_requests = PoultryRequest.objects.filter(trash=False, out=True,
|
||
state_process__in=('pending', 'accepted'),
|
||
province_state__in=('pending', 'accepted'),
|
||
out_province_request_cancel=False,
|
||
hatching=poultry_hatching).order_by(
|
||
'-send_date'
|
||
)
|
||
# code_rsi=[data['TrackingCode'] for data in response.json()]
|
||
bars_info_rsi = []
|
||
rsi_quantity = 0
|
||
for poultry_request in poultry_requests:
|
||
if poultry_request.quarantine_code:
|
||
quarantine_code = poultry_request.quarantine_code
|
||
code_rasadyar.append(quarantine_code)
|
||
|
||
else:
|
||
quarantine_code = 'ندارد'
|
||
bars_info.append(
|
||
'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
|
||
quarantine_code,
|
||
to_locale_str(int(poultry_request.quantity)),
|
||
poultry_request.buyer_fullname,
|
||
shamsi_date(poultry_request.send_date),
|
||
))
|
||
chain_allocations = ChainAllocation.objects.filter(trash=False, poultry_hatching=poultry_hatching).order_by(
|
||
'-date')
|
||
for poultry_request in chain_allocations:
|
||
if poultry_request.quarantine_code:
|
||
quarantine_code = poultry_request.quarantine_code
|
||
code_rasadyar.append(quarantine_code)
|
||
else:
|
||
quarantine_code = 'ندارد'
|
||
bars_info.append(
|
||
'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3})'.format(
|
||
quarantine_code,
|
||
to_locale_str(int(poultry_request.quantity)),
|
||
poultry_request.buyer_name,
|
||
shamsi_date(poultry_request.date),
|
||
))
|
||
for bar in response.json():
|
||
rsi_quantity += bar['GoodAmount']
|
||
date_str = str(bar['Date']).split('T')[0]
|
||
date = datetime.datetime.strptime(date_str, '%Y-%m-%d').date()
|
||
state = '✅' if bar['TrackingCode'] in code_rasadyar else '❌'
|
||
bars_info_rsi.append(
|
||
'کد قرنطینه: {0} - حجم: {1} قطعه - مقصد بار: {2} - تاریخ بار: ({3}){4}'.format(
|
||
bar['TrackingCode'],
|
||
to_locale_str(int(bar['GoodAmount'])),
|
||
bar['DesUnitName'],
|
||
shamsi_date(date),
|
||
state
|
||
))
|
||
|
||
bars_details = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info)])
|
||
bars_details_rsi = "***".join([f"{i + 1}. {info}" for i, info in enumerate(bars_info_rsi)])
|
||
accepted_real_quantity = 0
|
||
accepted_real_quantity += kill_house_request.aggregate(
|
||
total_quantity=Sum('accepted_real_quantity')).get('total_quantity') or 0
|
||
accepted_real_quantity += chain_allocations.aggregate(
|
||
total_quantity=Sum('quantity')).get('total_quantity') or 0
|
||
accepted_real_quantity += poultry_requests.aggregate(
|
||
total_quantity=Sum('quantity')).get('total_quantity') or 0
|
||
if rsi_quantity - accepted_real_quantity > 0:
|
||
new_message = 'در مجموع شما {0} قطعه بدون مجوز کشتار در سامانه قرنطینه ثبت کرده اید.' \
|
||
'***' \
|
||
'در صورت تکرار و عدم رعایت موضوع و ضوابط اجرایی در استان،مراتب و گزارش تخلف به مراجع مسئول ارجاع میگردد.' \
|
||
'***' \
|
||
'***' \
|
||
.format(to_locale_str(int(rsi_quantity - accepted_real_quantity)))
|
||
new_message1 = 'خارج از سامانه مجوز حمل'
|
||
else:
|
||
new_message = ''
|
||
new_message1 = 'اطلاعات زیر'
|
||
message = " دامپزشک محترم فارم {0}({9})" \
|
||
"***" \
|
||
"با سلام" \
|
||
"***" \
|
||
"با توجه بررسی های انجام شده" \
|
||
" و استعلامات از پایش کشوری سامانه" \
|
||
" رصد یار برای فارم {1} با شناسه یکتا {10} و شماره مجوز جوجه ریزی {11} {12} صادر گردیده است." \
|
||
"***" \
|
||
"***" \
|
||
"اطلاعات مجوز صادر شده در قرنطینه:" \
|
||
"***" \
|
||
"{2}" \
|
||
"***" \
|
||
"جمعا {3} بار با مجموع {4} قطعه" \
|
||
"***" \
|
||
"***" \
|
||
"اطلاعات مجوز صادر شده در رصدیار : " \
|
||
"***" \
|
||
"{5}" \
|
||
"***" \
|
||
"جمعا {6} بار با مجموع {7} قطعه" \
|
||
"***" \
|
||
"***" \
|
||
"{8}" \
|
||
"ربات هوشمند سامانه رصدیار" \
|
||
"".format(vet_farm.vet.user.fullname, poultry_hatching.poultry.unit_name, bars_details_rsi,
|
||
len(response.json()),
|
||
to_locale_str(int(rsi_quantity)),
|
||
bars_details,
|
||
len(kill_house_request), to_locale_str(int(accepted_real_quantity)),
|
||
new_message, vet_farm.vet.user.mobile,
|
||
poultry_hatching.poultry.breeding_unique_id, poultry_hatching.licence_number, new_message1)
|
||
|
||
user = SystemUserProfile.objects.filter(trash=False, mobile=request.GET['mobile']).last()
|
||
new_ticket = TicketSupport(
|
||
user=user,
|
||
title="گزارش کشتار جوجه ریزی",
|
||
status='open',
|
||
read_only=True,
|
||
type_ticket='single',
|
||
parent=None,
|
||
last_message='Admin',
|
||
)
|
||
new_ticket.save()
|
||
new_ticket.to_user.add(user)
|
||
msg = MessageSupport(
|
||
ticket=new_ticket,
|
||
message=message,
|
||
created_by=user,
|
||
sender='Admin'
|
||
)
|
||
msg.save()
|
||
return Response('ok', status=status.HTTP_200_OK)
|
||
|
||
|
||
def delete_kill_req_cron():
|
||
current_time = datetime.datetime.now()
|
||
kill_requests = KillRequest.objects.filter(Q(market_final_accept=True, market_code_status=True,
|
||
input_market_code__isnull=True) | Q(market_final_accept=False),
|
||
trash=False,
|
||
market=True,
|
||
market_state='pending',
|
||
market_expire_date_time__lt=current_time
|
||
).select_related('poultry_request')
|
||
for kill_request in kill_requests:
|
||
kill_request.trash = True
|
||
kill_request.market_state_message = {
|
||
"fullname": "سیستمی",
|
||
"mobile": "سیستمی",
|
||
"date": str(datetime.datetime.now())
|
||
}
|
||
kill_request.market_state = 'deleted'
|
||
kill_request.save()
|
||
market_poultry_request_remain_quantity(kill_request.poultry_request)
|
||
|
||
|
||
def delete_steward_allocation_cron():
|
||
current_time = datetime.datetime.now().date()
|
||
# allow=AllowRegisterCodeForStewardAllocation.objects.filter(trash=False,active=True).first()
|
||
# if allow:
|
||
steward_allocation = StewardAllocation.objects.filter(trash=False,
|
||
date__date=current_time,
|
||
receiver_state='pending',
|
||
active_expire_date_time=True,
|
||
logged_registration_code__isnull=True,
|
||
kill_house__isnull=False,
|
||
return_trash=False,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) |