import datetime import io from urllib.parse import quote import requests from django.db.models import Sum, Count, Avg, Q from django.http import HttpResponse from django.template.loader import render_to_string from weasyprint import HTML, CSS from weasyprint.text.fonts import FontConfiguration from general_urls import base_url_for_sms_report from panel.KillHouse.helpers import get_finance_info, check_kill_house_remain_limitation_weight from django.db.models import F from panel.KillHouse.serializers import KillHouseRequestForHatchingDetailSerializer, \ KillHouseRequestForBarManagementSerializer, ReturnProvinceKillRequestSerializer, BarDifferenceRequestSerializer from panel.helper_excel import shamsi_date, to_locale_str from panel.models import KillRequest, ProvinceKillRequest, PoultryHatching, KillHouseRequest, \ KillHouseFreeBarInformation, KillHouse, StewardAllocation, KillHouseFreeSaleBarInformation, RolesProducts, \ DirectBuyingPayment, PoultryRequest, ChainAllocation, BarDifferenceRequest, HatchingIncreaseRequest, \ PoultryScienceReport, KillHousePurchaseRequest, InternalTransaction, PosSegmentation, WarehouseArchive, \ Guilds, StewardFreeBarInformation, StewardFreeSaleBarInformation from panel.poultry.serializers import PoultryHatchingForDetailsSerializer, PoultryRequestForHatchingDetailSerializer, \ ChainAllocationForHatchingDetailSerializer, HatchingIncreaseRequestSerializer, EvacuationHatchingDetailSerializer def kill_request_pdf(request): font_config = FontConfiguration() kill_request = KillRequest.objects.filter(trash=False, key=request.GET['key']).select_related( 'kill_house', 'poultry', 'poultry__address', 'poultry__user', 'kill_house__kill_house_operator' ).only( 'poultry__unit_name', 'poultry__user__fullname', 'poultry__user__mobile', 'poultry__user__national_code', 'poultry__breeding_unique_id', 'poultry__breeding_unique_id', 'poultry__address__address', 'poultry__user__city__name', 'kill_house__kill_house_operator__user__fullname', 'kill_house__kill_house_operator__user__national_code', 'kill_house__kill_house_operator__address__address', 'kill_house__kill_house_operator__user__city__name', 'kill_house__name', 'kill_capacity', 'amount', 'recive_date', 'Index_weight', 'input_direct_buying_code', 'direct_buying_state', 'poultry_hatching__chicken_age', 'poultry_hatching__licence_number', 'payment_deadline_date', 'payment_deadline_days', 'direct_buying_intermediary_mobile', ).first() recive_date = kill_request.recive_date if isinstance(recive_date, str): try: recive_date = datetime.datetime.strptime(recive_date, '%Y-%m-%dT%H:%M:%S.%f') except ValueError: recive_date = datetime.datetime.strptime(recive_date, '%Y-%m-%dT%H:%M:%S') date = shamsi_date(recive_date.date(), in_value=True) date_in_value = shamsi_date(recive_date.date()) if kill_request.market_state == 'accepted' or kill_request.input_direct_buying_code or \ kill_request.direct_buying_state == 'accepted': input_direct_buying_code = True else: input_direct_buying_code = False if kill_request.market_final_accept or kill_request.final_accept: final_accept = True else: final_accept = False if kill_request.kill_house.kill_house_operator.address.address is not None: kill_house_address = kill_request.kill_house.kill_house_operator.address.address elif kill_request.kill_house.kill_house_operator.user.city.name: kill_house_address = kill_request.kill_house.kill_house_operator.user.city.name else: kill_house_address = '-' if kill_request.poultry.address.address: poultry_address = kill_request.poultry.address.address elif kill_request.poultry.user.city.name: poultry_address = kill_request.poultry.user.city.name else: poultry_address = '-' kill_house_request = KillHouseRequest.objects.filter(trash=False, kill_request=kill_request, assignment_state_archive='True').aggregate( total_quantity=Sum('accepted_real_quantity'), total_weight=Sum('accepted_real_weight'), ) province_kill_req = ProvinceKillRequest.objects.filter(trash=False, kill_request=kill_request).only( 'province_request__poultry_request__order_code' ).first() payments = DirectBuyingPayment.objects.filter(province_kill_request=province_kill_req, trash=False) total_paid_amount = payments.aggregate(total=Sum('amount'))['total'] or 0 avg_killed_weight = round((kill_house_request['total_weight'] or 0) / (kill_house_request['total_quantity'] or 0) if (kill_house_request['total_quantity'] or 0) > 0 else 0, 1) html_content = render_to_string('Digital_agreement_for_buying_and_selling.html', { # noqa 'date': date, 'unit_name': kill_request.poultry.unit_name, 'fullname': kill_request.poultry.user.fullname, 'mobile': kill_request.poultry.user.mobile, 'national_code': kill_request.poultry.user.national_code if kill_request.poultry.user.national_code else '-', 'breeding_unique_id': kill_request.poultry.breeding_unique_id if kill_request.poultry.breeding_unique_id else '-', 'poultry_address': poultry_address, 'kill_house_fullname': kill_request.kill_house.kill_house_operator.user.fullname, 'kill_house_name': kill_request.kill_house.name, 'kill_house_national_code': kill_request.kill_house.kill_house_operator.user.national_code if kill_request.kill_house.kill_house_operator.user.national_code else '-', 'kill_house_mobile': kill_request.kill_house.kill_house_operator.user.mobile, 'kill_house_address': kill_house_address, 'kill_capacity': to_locale_str(kill_request.kill_capacity), 'date_in_value': date_in_value, 'amount': to_locale_str(int(kill_request.amount)), 'weight': to_locale_str(round(kill_request.Index_weight * kill_request.kill_capacity, 1)), 'input_direct_buying_code': input_direct_buying_code, 'direct_buying_state': final_accept, 'Index_weight': kill_request.Index_weight, 'chicken_age': kill_request.poultry_hatching.chicken_age, 'licence_number': kill_request.poultry_hatching.licence_number if kill_request.poultry_hatching.licence_number else '-', 'max_time': shamsi_date(kill_request.payment_deadline_date) if kill_request.payment_deadline_date else '-', 'payment_deadline_days': kill_request.payment_deadline_days, 'number': province_kill_req.province_request.poultry_request.order_code if province_kill_req else '-', 'total_killed_quantity': to_locale_str(kill_house_request['total_quantity'] or 0), 'total_killed_weight': to_locale_str(kill_house_request['total_weight'] or 0), 'avg_killed_weight': avg_killed_weight, 'direct_buying_intermediary_mobile': kill_request.direct_buying_intermediary_mobile, 'payment_deadline_state': province_kill_req.payment_deadline_state, 'total_paid_amount': to_locale_str(total_paid_amount), 'payment_deadline_checker_fullname': province_kill_req.payment_deadline_checker_fullname, 'payment_deadline_check_date': shamsi_date(province_kill_req.payment_deadline_check_date) \ if province_kill_req.payment_deadline_check_date else '-', 'payment_deadline_archive_message': province_kill_req.payment_deadline_archive_message, }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) # noqa css = CSS(string=''' ''', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = 'توافق‌نامه {0}.pdf'.format( province_kill_req.province_request.poultry_request.order_code if province_kill_req else "-") encoded_filename = quote(filename) # کدگذاری نام فایل برای URL response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response def management_all_poultry_and_warehouse_pdf(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, send_date__date__gte=date1, send_date__date__lte=date2) max_age_poultry = poultry_hatching_has_killed.order_by('-killing_age').first() min_age_poultry = poultry_hatching_has_killed.order_by('killing_age').first() 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), '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 = [] 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 }) 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, }) if base_url_for_sms_report == 'ha': province = 'همدان' elif base_url_for_sms_report == 'ku': province = 'کردستان' elif base_url_for_sms_report == 'ma': province = 'مرکزی' elif base_url_for_sms_report == 'bu': province = 'بوشهر' else: province = 'تست' font_config = FontConfiguration() 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 if different_bar < 0: color_different_bar = '#FF0000' else: color_different_bar = None html_content = render_to_string('management_all_poultry_and_warehouse.html', { # noqa 'number': 1234, 'province': province, "date": shamsi_date(datetime.datetime.now().date(), in_value=True), "date1": request.GET['date1'], "date2": request.GET['date2'], "from_date": shamsi_date(date1), "to_date": shamsi_date(date2), "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": to_locale_str(aggregate_hatching['total_quantity'] or 0), "poultry_hatching_losses_vet": to_locale_str(aggregate_hatching['total_losses_vet'] or 0), "poultry_hatching_losses_union": to_locale_str(aggregate_hatching['total_losses_union'] or 0), "poultry_hatching_total_losses": to_locale_str(aggregate_hatching['total_losses'] or 0), "poultry_hatching_killed_quantity": to_locale_str(aggregate_hatching['killed_quantity'] or 0), "poultry_hatching_total_killed_weight": to_locale_str(aggregate_hatching['total_killed_weight'] or 0), "poultry_hatching_left_over": to_locale_str(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": to_locale_str(aggregate_poultry_hatching_gt_60['total_quantity'] or 0), "poultry_hatching_gt_60_left_over": to_locale_str(aggregate_poultry_hatching_gt_60['left_over'] or 0), "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, "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_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': 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_weight_hasnt_warehouse": to_locale_str( aggregate_kill_house_request['total_weight_hasnt_warehouse'] 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), 'color_different_bar': color_different_bar, 'different_bar_percent': different_bar_percent, 'tomorrow_of_date1': shamsi_date(tomorrow_of_date1), 'tomorrow_of_date2': shamsi_date(tomorrow_of_date2), }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) # noqa css = CSS(string=''' ''', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = 'عملکرد کشتار زنجیره.pdf' encoded_filename = quote(filename) # کدگذاری نام فایل برای URL response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response def summary_report_pdf(request): if base_url_for_sms_report == 'ha': province = 'همدان' elif base_url_for_sms_report == 'ku': province = 'کردستان' elif base_url_for_sms_report == 'ma': province = 'مرکزی' elif base_url_for_sms_report == 'bu': province = 'بوشهر' else: province = 'تست' 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( id=Count('id'), accepted_real_quantity=Sum('accepted_real_quantity'), accepted_real_weight=Sum('accepted_real_weight'), ) 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 = "-" transaction_count_req = 0 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'] transaction_count_req = top_kill_house_req['transaction_count'] # max_kill_day_req = kill_house_request.values('kill_request__recive_date__date').annotate( # daily_quantity=Sum('quantity') # ).order_by('-daily_quantity').first() # persian_date_req = '-' # daily_quantity_req = '-' # if max_kill_day_req: # persian_date = shamsi_date(max_kill_day_req['date__date']) # daily_quantity = to_locale_str(max_kill_day_req['daily_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 = poultry_hatching.filter(total_killed_weight__gt=0) max_age_poultry = poultry_hatching_has_killed.order_by('-chicken_age').first() min_age_poultry = poultry_hatching_has_killed.order_by('chicken_age').first() 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).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']) 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 out_qty = out_province_data.get('quantity', 0) or 0 total_quantity = in_qty + out_qty 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), 'out_province_quantity': to_locale_str(out_qty or 0), 'total_quantity': to_locale_str(total_quantity or 0), }) 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') ) steward_allocations_stats = steward_allocations.values('kill_house__name').annotate( total_quantity=Sum('real_weight_of_carcasses'), ).order_by('-total_quantity') top_steward_allocations_stats = steward_allocations_stats.first() if steward_allocations_stats else None out_kill_house_top = "-" out_weight_top = 0 if top_steward_allocations_stats: out_kill_house_top = top_steward_allocations_stats['kill_house__name'] out_weight_top = to_locale_str(top_steward_allocations_stats['total_quantity'] or 0) 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') top_free_bars_stats = free_bars.first() if free_bars else None free_bars_kill_house_top = "-" free_bars_weight_top = 0 if top_free_bars_stats: free_bars_kill_house_top = top_free_bars_stats['kill_house__name'] free_bars_weight_top = to_locale_str(top_free_bars_stats['total_quantity'] or 0) 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} bar_assigment_true_count1 = kill_house_request.filter(assignment_state_archive='True') bar_document_status_rejected1 = bar_assigment_true_count1.exclude( bar_document_status__title__in=('تایید شده بدون کیفیت', 'تایید شد')).count() percent_bar_document_status_rejected_all = int((bar_document_status_rejected1 / bar_assigment_true_count1.count()) * 100) if \ bar_assigment_true_count1.count() > 0 else 0 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 }) 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, }) font_config = FontConfiguration() html_content = render_to_string('summary_report.html', { # noqa 'number': 1234, 'province': province, "date": shamsi_date(datetime.datetime.now().date(), in_value=True), "date1": request.GET['date1'], "date2": request.GET['date2'], "from_date": shamsi_date(date1), "to_date": shamsi_date(date2), "out_kill_house_top": out_kill_house_top, "out_weight_top": out_weight_top, "free_bars_weight_top": free_bars_weight_top, "free_bars_kill_house_top": free_bars_kill_house_top, "steward_sum_weight_sale": to_locale_str(sum(steward_dict.values())), "free_bar_sum_weight_sale": to_locale_str(sum(free_bar_dict.values())), "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": to_locale_str(aggregate_hatching['total_quantity'] or 0), "poultry_hatching_total_losses": to_locale_str(aggregate_hatching['total_losses'] or 0), "poultry_hatching_killed_quantity": to_locale_str(aggregate_hatching['killed_quantity'] or 0), "poultry_hatching_left_over": to_locale_str(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": to_locale_str(aggregate_poultry_hatching_gt_60['total_quantity'] or 0), "poultry_hatching_gt_60_left_over": round(((aggregate_poultry_hatching_gt_60['left_over'] or 0) / (aggregate_poultry_hatching_gt_60['total_quantity'] or 0) * 100, 1) if (aggregate_poultry_hatching_gt_60['total_quantity'] or 0) < 0 else 0), "max_age_poultry": to_locale_str(max_age_poultry.chicken_age or 0), "max_age_poultry_name": max_age_poultry.poultry.unit_name or '-', "max_age_poultry_city": max_age_poultry.poultry.user.city.name if max_age_poultry.poultry.user.city else '-', "min_age_poultry": to_locale_str(min_age_poultry.chicken_age or 0), "min_age_poultry_name": min_age_poultry.poultry.unit_name or '-', "min_age_poultry_city": min_age_poultry.poultry.user.city.name if min_age_poultry.poultry.user.city else '-', "kill_house_request_count": to_locale_str(aggregate_kill_house_request['id'] or 0), "kill_house_request_quantity": to_locale_str(aggregate_kill_house_request['accepted_real_quantity'] or 0), "kill_house_request_weight": to_locale_str(aggregate_kill_house_request['accepted_real_weight'] or 0), "kill_house_request_average_weight": round( aggregate_kill_house_request['accepted_real_weight'] / aggregate_kill_house_request[ 'accepted_real_quantity'], 1) if (aggregate_kill_house_request['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, "transaction_count_req": transaction_count_req, "daily_quantity": daily_quantity, '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': 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, 'percent_bar_document_status_rejected_all': percent_bar_document_status_rejected_all, }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) # noqa css = CSS(string=''' ''', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = 'عملکرد کشتار زنجیره.pdf' encoded_filename = quote(filename) # کدگذاری نام فایل برای URL response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response def hatching_detail_pdf(request): if base_url_for_sms_report == 'ha': province = 'همدان' elif base_url_for_sms_report == 'ku': province = 'کردستان' elif base_url_for_sms_report == 'ma': province = 'مرکزی' elif base_url_for_sms_report == 'bu': province = 'بوشهر' else: province = 'تست' hatching = PoultryHatching.objects.filter( trash=False, key=request.GET['key'] ).select_related('poultry').first() ser_data = PoultryHatchingForDetailsSerializer(hatching).data kill_requests = KillHouseRequest.objects.filter( trash=False, province_request__poultry_request__hatching=hatching, ware_house_confirmation=True ).select_related( 'killhouse_user', 'killer', 'province_request', 'province_request__poultry_request', 'kill_request' ).order_by('-create_date') ser_data_kill_request = KillHouseRequestForHatchingDetailSerializer(kill_requests, many=True).data poultry_requests = PoultryRequest.objects.filter(hatching=hatching, trash=False, state_process__in=('pending', 'accepted'), province_state__in=('pending', 'accepted'), out=True, out_province_request_cancel=False, temporary_trash=False, temporary_deleted=False) ser_data_poultry_request = PoultryRequestForHatchingDetailSerializer(poultry_requests, many=True).data chain_allocation = ChainAllocation.objects.filter(trash=False, state='accepted', poultry_hatching=hatching) ser_data_chain_allocation = ChainAllocationForHatchingDetailSerializer(chain_allocation, many=True).data evacuation_reports = [] if hatching: detail_qs = hatching.evacuation_details.filter(trash=False).order_by('-ReportDate', '-create_date') evacuation_reports = EvacuationHatchingDetailSerializer(detail_qs, many=True).data poultry_hatching_licence_number = 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={None}&date2={None}', headers={'Content-Type': 'application/json'} ) kill_requests_non_receipt = KillHouseRequest.objects.filter( trash=False, province_request__poultry_request__hatching=hatching, non_receipt=True, main_non_receipt=True ).select_related( 'killhouse_user', 'killer', 'province_request', 'province_request__poultry_request', 'kill_request' ).order_by('-create_date') ser_data_non_receipt_kill_request = KillHouseRequestForHatchingDetailSerializer(kill_requests_non_receipt, many=True).data bar_requests = BarDifferenceRequest.objects.filter(trash=False, state='accepted', hatching=hatching).order_by('id') bar_request_serilizer = BarDifferenceRequestSerializer(bar_requests, many=True).data hatching_increase = HatchingIncreaseRequest.objects.filter(trash=False, hatching=hatching).order_by('-date') hatching_increase_serilizer = HatchingIncreaseRequestSerializer(hatching_increase, many=True).data filters = { 'archive_wage': False, 'state__in': ('pending', 'accepted'), 'first_car_allocated_quantity': 0 } return_province_kill_requests = ProvinceKillRequest.objects.filter( Q(trash=False, return_to_province=True) | Q(trash=True, return_trash=True), **filters, province_request__poultry_request__hatching=hatching).order_by('id') return_province_kill_requests_serializer = ReturnProvinceKillRequestSerializer(return_province_kill_requests, many=True).data kill_house_requests_return = KillHouseRequest.objects.filter( Q(non_receipt=True, main_non_receipt=True, non_receipt_state='accepted') | Q(trash=True, return_trash=True), province_request__poultry_request__hatching=hatching) kill_house_requests_return_serializer = KillHouseRequestForBarManagementSerializer(kill_house_requests_return, many=True).data font_config = FontConfiguration() html_content = render_to_string('poultry_datail.html', { # noqa 'province': province, "shamsi_date": shamsi_date(datetime.datetime.now().date(), in_value=True), "hatching_date": shamsi_date(hatching.date, in_value=True), "create_date_hatching": shamsi_date(hatching.create_date, in_value=True), "predicate_date_hatching": shamsi_date(hatching.predicate_date, in_value=True) if hatching.predicate_date else '-', **ser_data, "bars": ser_data_kill_request[:20] if len(ser_data_kill_request) > 20 else ser_data_kill_request, "bars2": ser_data_kill_request[20:] if len(ser_data_kill_request) > 20 else None, 'outBars': ser_data_poultry_request[:20] if len(ser_data_poultry_request) > 20 else ser_data_poultry_request, 'outBars2': ser_data_poultry_request[20:] if len(ser_data_poultry_request) > 20 else None, 'chainAllocation': ser_data_chain_allocation[20:] if len( ser_data_chain_allocation) > 20 else ser_data_chain_allocation, 'chainAllocation2': ser_data_chain_allocation[20:] if len(ser_data_chain_allocation) > 20 else None, 'percent_rasadyar1': round( ((ser_data['killed_quantity'] + ser_data['total_losses']) * 100) / ser_data['quantity']) if ser_data['quantity'] > 0 else 0, 'active_kill1': 'دارد' if ser_data['active_kill']['active_kill'] else 'ندارد', "differentBars": response.json()[:20], "differentBars2": response.json()[20:], "nonReceipt": ser_data_non_receipt_kill_request, "returnProvinceRequest": return_province_kill_requests_serializer, "returnKillHouseRequest": kill_house_requests_return_serializer, "killingDifference": bar_request_serilizer, "hatchingIncrease": hatching_increase_serilizer, "evacuation_reports": evacuation_reports, }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) # noqa css = CSS(string=''' ''', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = 'عملکرد کشتار زنجیره.pdf' encoded_filename = quote(filename) # کدگذاری نام فایل برای URL response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response def poultry_science_report_pdf(request): """ تولید PDF گزارش بازرسی مرغداری ساختار JSON بر اساس کد React: - generalConditionHall, casualties, technicalOfficer - inputStatus, infrastructureEnergy, facilities, hr - inspectionNotes, inspectionStatus """ font_config = FontConfiguration() report = PoultryScienceReport.objects.filter( trash=False, key=request.GET['key'] ).select_related( 'hatching', 'hatching__poultry', 'hatching__poultry__user', 'hatching__poultry__user__city', 'hatching__poultry__address', 'poultry_science', 'poultry_science__user', 'user' ).first() if not report: return HttpResponse("گزارش یافت نشد", status=404) report_data = report.report_information or {} hatching = report.hatching poultry = hatching.poultry if hatching else None # استخراج بخش‌های مختلف JSON (با snake_case) general_condition = report_data.get('general_condition_hall', {}) or {} casualties = report_data.get('casualties', {}) or {} technical_officer = report_data.get('technical_officer', {}) or {} input_status_data = report_data.get('input_status', {}) or {} infrastructure_energy = report_data.get('infrastructure_energy', {}) or {} facilities = report_data.get('facilities', {}) or {} hr = report_data.get('hr', {}) or {} # تابع کمکی برای مقادیر def safe_get(data, key, default='---'): if not isinstance(data, dict): return default value = data.get(key) return value if value not in [None, '', 'null'] else default def format_number(value): if value is None: return '---' try: return f"{int(value):,}" except (ValueError, TypeError): return str(value) if value else '---' # اطلاعات سربرگ inspection_date = shamsi_date(report.date, in_value=True) if report.date else '---' report_id = report.report_id or '---' unit_name = poultry.unit_name if poultry else '---' breeding_unique_id = poultry.breeding_unique_id if poultry else '---' licence_number = hatching.licence_number if hatching else '---' city = poultry.user.city.name if poultry and poultry.user and poultry.user.city else '---' hatching_date = shamsi_date(hatching.date, in_value=True) if hatching and hatching.date else '---' initial_quantity = format_number(hatching.quantity) if hatching else '---' # وضعیت بازرسی status_map = {'pending': 'در انتظار', 'accepted': 'تایید شده', 'rejected': 'رد شده'} inspection_status = status_map.get(report.state, report.state or 'در انتظار') # === بخش اطلاعات (informationData) === health_permit = poultry.health_certificate_number if poultry and hasattr(poultry, 'health_certificate_number') else '---' epidemiological_code = poultry.epidemiological_code if poultry and hasattr(poultry, 'epidemiological_code') else '---' permit_validity = format_number(poultry.operating_licence_capacity) if poultry and hasattr(poultry, 'operating_licence_capacity') else '---' tenant_status = hatching.InteractTypeName if hatching and hatching.InteractTypeName else ( 'دارد' if (hatching and hasattr(hatching, 'has_tenant') and hatching.has_tenant) else 'ندارد') owner_name = poultry.user.fullname if poultry and poultry.user else '---' ownership_type = hatching.InteractTypeName if hatching else '---' owner_national_code = (poultry.user.national_id if hasattr(poultry.user, 'national_id') and poultry.user.national_id else (poultry.user.national_code if hasattr(poultry.user, 'national_code') else '---')) if poultry and poultry.user else '---' province = poultry.address.province.name if poultry and poultry.address and hasattr(poultry.address, 'province') and poultry.address.province else '---' coordinates = f"{report.lat}, {report.log}" if report.lat and report.log else ( f"{poultry.Lat}, {poultry.Long}" if poultry and hasattr(poultry, 'Lat') and poultry.Lat else '---') owner_mobile = poultry.user.mobile if poultry and poultry.user else '---' nominal_capacity = format_number(poultry.total_capacity) if poultry and hasattr(poultry, 'total_capacity') else '---' vet_quantity = format_number(hatching.quantity) if hatching else '---' self_declared_quantity = format_number(hatching.quantity) if hatching else '---' chick_source = safe_get(casualties, 'source_of_hatching') chicken_age = f"{hatching.chicken_age} روز" if hatching and hatching.chicken_age else '---' breed_type = hatching.chicken_breed if hatching else '---' # === بخش پایش سلامت (healthMonitoringData) === health_status = safe_get(general_condition, 'health_status') ventilation_status = safe_get(general_condition, 'ventilation_status') bedding_status = safe_get(general_condition, 'bed_condition') temperature_humidity = f"{general_condition.get('temperature')} درجه" if general_condition.get( 'temperature') else '---' water_quality = safe_get(general_condition, 'drinking_water_quality') water_source = safe_get(general_condition, 'drinking_water_source') normal_losses = format_number(casualties.get('normal_losses')) if casualties.get( 'normal_losses') is not None else '---' abnormal_losses = format_number(casualties.get('abnormal_losses')) if casualties.get( 'abnormal_losses') is not None else '---' abnormal_losses_reason = safe_get(casualties, 'cause_abnormal_losses') disease_type = safe_get(casualties, 'type_disease') sampling_done = 'بله' if casualties.get('sampling_done') else 'خیر' sample_type = safe_get(casualties, 'type_sampling') health_responsible = safe_get(technical_officer, 'technical_health_officer') engineering_responsible = safe_get(technical_officer, 'technical_engineering_officer') # === بخش زیرساخت (infrastructureData) === input_status = safe_get(input_status_data, 'input_status') feed_type = safe_get(input_status_data, 'type_of_grain') feed_quality = safe_get(input_status_data, 'grade_grain') inventory_until_visit = safe_get(input_status_data, 'inventory_until_visit') warehouse_inventory = safe_get(input_status_data, 'inventory_in_warehouse') tracking_code = safe_get(input_status_data, 'tracking_code') company_name = safe_get(input_status_data, 'company_name') generator_type = safe_get(infrastructure_energy, 'generator_type') generator_model = safe_get(infrastructure_energy, 'generator_model') generator_count = safe_get(infrastructure_energy, 'generator_count') fuel_type = safe_get(infrastructure_energy, 'fuel_type') generator_capacity = format_number(infrastructure_energy.get('generator_capacity')) emergency_fuel = format_number(infrastructure_energy.get('emergency_fuel_inventory')) power_cut_history = 'بله' if infrastructure_energy.get('has_power_cut_history') else 'خیر' power_cut_duration = f"{infrastructure_energy.get('power_cut_duration')} ساعت" if infrastructure_energy.get( 'power_cut_duration') else '---' power_cut_hour = safe_get(infrastructure_energy, 'power_cut_hour') generator_status = safe_get(infrastructure_energy, 'generator_performance') additional_notes = safe_get(infrastructure_energy, 'additional_notes') # نیروی انسانی employee_count = safe_get(hr, 'number_employed') local_employee_count = safe_get(hr, 'number_indigenous') non_local_employee_count = safe_get(hr, 'number_non_indigenous') worker_contract_status = safe_get(hr, 'contract_status') health_training = 'بله' if hr.get('trained') else 'خیر' # تسهیلات active_facilities = 'بله' if facilities.get('has_facilities') else 'خیر' facility_type = safe_get(facilities, 'type_of_facility') facility_amount = format_number(facilities.get('amount')) repayment_status = safe_get(facilities, 'repayment_status') new_request = safe_get(facilities, 'request_facilities') facility_date = shamsi_date(facilities.get('date')) if facilities.get('date') else '---' # مستندات hall_images = general_condition.get('images', []) or [] warehouse_images = input_status_data.get('images', []) or [] losses_images = casualties.get('images', []) or [] violation_images = hatching.violation_image if hatching and hasattr(hatching, 'violation_image') and hatching.violation_image else [] # توصیه‌ها recommendations = report_data.get('inspection_notes', '---') or '---' inspection_status_text = report_data.get('inspection_status', '---') or '---' # احراز مسئول سالن (از vet_farm جوجه‌ریزی) vet_farm = None if hatching: from panel.models import VetFarm vet_farm = VetFarm.objects.filter(poultry=poultry, trash=False).first() hall_responsible_present = 'بله' if (vet_farm and vet_farm.vet and vet_farm.vet.user) else 'خیر' hall_responsible_name = vet_farm.vet.user.fullname if vet_farm and vet_farm.vet and vet_farm.vet.user else '---' hall_responsible_phone = vet_farm.vet.user.mobile if vet_farm and vet_farm.vet and vet_farm.vet.user else '---' html_content = render_to_string('poultry_science_report.html', { # سربرگ 'inspection_date': inspection_date, 'report_id': report_id, 'unit_name': unit_name, 'breeding_unique_id': breeding_unique_id, 'licence_number': licence_number, 'city': city, 'hatching_date': hatching_date, 'initial_quantity': initial_quantity, 'inspection_status': inspection_status, # اطلاعات واحد 'health_permit': health_permit, 'hatching_licence': licence_number, 'epidemiological_code': epidemiological_code, 'permit_validity': permit_validity, 'tenant_status': tenant_status, 'owner_name': owner_name, 'ownership_type': ownership_type, 'owner_national_code': owner_national_code, 'province': province, 'coordinates': coordinates, 'owner_mobile': owner_mobile, 'nominal_capacity': nominal_capacity, 'vet_quantity': vet_quantity, 'self_declared_quantity': self_declared_quantity, 'chick_source': chick_source, 'chicken_age': chicken_age, 'breed_type': breed_type, # پایش سلامت 'health_status': health_status, 'ventilation_status': ventilation_status, 'bedding_status': bedding_status, 'temperature_humidity': temperature_humidity, 'water_quality': water_quality, 'water_source': water_source, 'normal_losses': normal_losses, 'abnormal_losses': abnormal_losses, 'abnormal_losses_reason': abnormal_losses_reason, 'disease_type': disease_type, 'sampling_done': sampling_done, 'sample_type': sample_type, 'health_responsible': health_responsible, 'engineering_responsible': engineering_responsible, # زیرساخت 'input_status': input_status, 'feed_type': feed_type, 'feed_quality': feed_quality, 'inventory_until_visit': inventory_until_visit, 'warehouse_inventory': warehouse_inventory, 'tracking_code': tracking_code, 'company_name': company_name, 'generator_type': generator_type, 'generator_model': generator_model, 'generator_count': generator_count, 'fuel_type': fuel_type, 'generator_capacity': generator_capacity, 'emergency_fuel': emergency_fuel, 'power_cut_history': power_cut_history, 'power_cut_duration': power_cut_duration, 'power_cut_hour': power_cut_hour, 'generator_status': generator_status, 'additional_notes': additional_notes, # نیروی انسانی 'employee_count': employee_count, 'local_employee_count': local_employee_count, 'non_local_employee_count': non_local_employee_count, 'worker_contract_status': worker_contract_status, 'health_training': health_training, 'active_facilities': active_facilities, 'facility_type': facility_type, 'facility_amount': facility_amount, 'repayment_status': repayment_status, 'new_request': new_request, 'facility_date': facility_date, # مستندات 'hall_images': hall_images, 'warehouse_images': warehouse_images, 'losses_images': losses_images, 'violation_images': violation_images, # توصیه‌ها و احراز 'recommendations': recommendations, 'inspection_status_text': inspection_status_text, 'hall_responsible_present': hall_responsible_present, 'hall_responsible_name': hall_responsible_name, 'hall_responsible_phone': hall_responsible_phone, }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) css = CSS(string='', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = f'گزارش بازرسی {report_id}.pdf' encoded_filename = quote(filename) response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response def kill_house_debt_report_pdf(request): font_config = FontConfiguration() kill_houses = KillHouse.objects.filter( trash=False, out_province=False ).select_related('kill_house_operator__user', 'system_address').order_by('name') kill_house_data = [] production_date = (datetime.datetime.now() - datetime.timedelta(days=3)).date() yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).date() for kill_house in kill_houses: ware_house_lock = False if kill_house.ware_house_remaining_weight_limitation_status: if kill_house.total_remain_warehouse_governmental_weight > kill_house.ware_house_remaining_weight_limitation: ware_house_lock = True if kill_house.ware_house_remaining_percent_limitation_status: if not check_kill_house_remain_limitation_weight(kill_house): ware_house_lock = True if not ware_house_lock: continue 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' ) archives = WarehouseArchive.objects.filter( kill_house=kill_house, date__date=production_date, quota='governmental', trash=False ) live_weight = kill_house_requests.aggregate(total=Sum('accepted_real_weight'))['total'] or 0 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_governmental_weight = archives.aggregate(total=Sum('weight'))['total'] or 0 total_output = kill_house_allocations_weight + kill_house_free_sale_bars_weight + segmentation_weight + archives_governmental_weight total_remain = kill_house_requests_weight - total_output nature = 'کشتارکن' if kill_house.killer else 'کشتارگاه' name_with_phone = f"{kill_house.name} ({kill_house.kill_house_operator.user.mobile or '-'})" city = kill_house.city_name or (kill_house.system_address.city if kill_house.system_address else '-') kill_house_data.append({ 'nature': nature, 'name_with_phone': name_with_phone, 'city': city, 'live_weight': to_locale_str(int(live_weight)), 'carcass_weight': to_locale_str(int(kill_house_requests_weight)), 'distribution_weight': to_locale_str(int(total_output)), 'remain_weight': to_locale_str(int(total_remain)), }) guild_ids = list(Guilds.objects.filter(trash=False, steward=True, active=True).values_list('id', flat=True)) if guild_ids: input_allocations_data = StewardAllocation.objects.filter( to_steward_id__in=guild_ids, date__date=yesterday, trash=False, receiver_state='accepted', warehouse=True, steward_warehouse=True, ).values('to_steward_id').annotate(total=Sum('real_weight_of_carcasses')) input_free_bars_data = StewardFreeBarInformation.objects.filter( steward_id__in=guild_ids, date__date=yesterday, trash=False, warehouse=True, ).values('steward_id').annotate(total=Sum('weight_of_carcasses')) output_allocations_data = StewardAllocation.objects.filter( steward_id__in=guild_ids, production_date__date=yesterday, trash=False, receiver_state__in=('pending', 'accepted'), warehouse=True, steward_warehouse=True, ).values('steward_id').annotate(total=Sum('real_weight_of_carcasses')) free_sale_bars_data = StewardFreeSaleBarInformation.objects.filter( steward_id__in=guild_ids, production_date__date=yesterday, trash=False, warehouse=True, ).values('steward_id').annotate(total=Sum('weight_of_carcasses')) input_weights = {item['to_steward_id']: item['total'] or 0 for item in input_allocations_data} input_free_bar_weights = {item['steward_id']: item['total'] or 0 for item in input_free_bars_data} output_allocations_weights = {item['steward_id']: item['total'] or 0 for item in output_allocations_data} free_sale_bars_weights = {item['steward_id']: item['total'] or 0 for item in free_sale_bars_data} guilds = Guilds.objects.filter(id__in=guild_ids).select_related('user') steward_data = [] for guild in guilds: guild_id = guild.id total_input = (input_weights.get(guild_id, 0) + input_free_bar_weights.get(guild_id, 0)) total_output = (output_allocations_weights.get(guild_id, 0) + free_sale_bars_weights.get(guild_id, 0)) remain_weight = total_input - total_output if total_output == 0 and total_input > 0: unit_name = guild.guilds_name or '-' user_fullname = guild.user.fullname if guild.user else '-' user_phone = guild.user.mobile if guild.user else (guild.phone or '-') name_with_phone = f"{user_fullname} ({user_phone})" steward_data.append({ 'unit_name': unit_name, 'name_with_phone': name_with_phone, 'input_weight': to_locale_str(int(total_input)), 'output_weight': to_locale_str(int(total_output)), 'remain_weight': to_locale_str(int(remain_weight)), }) else: steward_data = [] report_date = shamsi_date(datetime.datetime.now().date(), in_value=True) report_date_number = f"{report_date.year:04d}{report_date.month:02d}{report_date.day:02d}" yesterday_shamsi = shamsi_date(yesterday, in_value=True) production_date_shamsi = shamsi_date(production_date, in_value=True) # تقسیم مباشرین به صفحات 19 تایی steward_pages = [] page_size = 19 for i in range(0, len(steward_data), page_size): page_data = steward_data[i:i + page_size] # اضافه کردن شماره ردیف برای هر صفحه for idx, steward in enumerate(page_data): steward['row_number'] = i + idx + 1 steward_pages.append(page_data) # Debug: چاپ تعداد صفحات print(f"Total stewards: {len(steward_data)}, Total pages: {len(steward_pages)}") for idx, page in enumerate(steward_pages): print(f"Page {idx + 1}: {len(page)} stewards") html_content = render_to_string('kill_house_debt_report.html', { 'kill_houses': kill_house_data, 'steward_pages': steward_pages, 'report_date': report_date, "number": report_date_number, 'total_count': len(kill_house_data), 'steward_count': len(steward_data), 'yesterday': yesterday_shamsi, 'production_date': production_date_shamsi, }) html = HTML(string=html_content, base_url=request.build_absolute_uri()) css = CSS(string=''' @page { margin: 3mm; } table { width: 100%; border-collapse: collapse; margin-top: 25px; background: transparent; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } th, td { border: 1px solid #dc3545; padding: 4px 5px; text-align: center; font-size: 12px; background-color: transparent; } th { background-color: #dc3545; color: white; font-weight: normal; text-align: center; } .a4-container { page-break-inside: avoid; page-break-after: avoid; } div[style*="page-break-before"] { page-break-before: always !important; break-before: page !important; height: 0; margin: 0; padding: 0; } ''', font_config=font_config) pdf_file = io.BytesIO() html.write_pdf(pdf_file, stylesheets=[css], font_config=font_config) pdf_file.seek(0) response = HttpResponse(pdf_file, content_type='application/pdf') filename = f'گزارش کشتارگاه‌های قفل شده - {report_date}.pdf' encoded_filename = quote(filename) response['Content-Disposition'] = f'attachment; filename*=UTF-8\'\'{encoded_filename}' return response