Files
RasadDam_Backend/apps/product/services/excel/excel_processing.py
2025-08-02 13:51:28 +03:30

519 lines
19 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from datetime import datetime
from io import BytesIO
from django.db.models import Q
from django.http import HttpResponse
from openpyxl import Workbook
from rest_framework import viewsets, filters
from rest_framework.decorators import action
from apps.core.mixins.search_mixin import DynamicSearchMixin
from apps.product import models as product_models
from apps.product.web.api.v1.serializers import quota_distribution_serializers as distribution_serializers
from apps.product.web.api.v1.serializers.product_serializers import IncentivePlanSerializer
from apps.product.web.api.v1.serializers.quota_serializers import QuotaSerializer
from common.helper_excel import create_header, excel_description, create_header_freez, create_value, shamsi_date, \
convert_str_to_date
from common.helpers import get_organization_by_user
class ProductExcelViewSet(viewsets.ModelViewSet, DynamicSearchMixin):
queryset = product_models.QuotaDistribution.objects.all()
serializer_class = distribution_serializers.QuotaDistributionSerializer
filter_backends = [filters.SearchFilter]
# noqa # سهمیه و توزیع
@action(
methods=['get'],
detail=False,
url_path='my_distributions_excel',
url_name='my_distributions_excel',
name='my_distributions_excel'
)
def my_distributions_excel(self, request):
output = BytesIO()
workbook = Workbook()
worksheet = workbook.active
worksheet.sheet_view.rightToLeft = True
worksheet.insert_rows(1)
product = self.filter_query(self.queryset) # return by search param or all objects
organization = get_organization_by_user(request.user)
query = self.request.query_params
description_name = ''
if query.get('param') == 'assigned':
product = product.filter(
Q(assigned_organization=organization)
).order_by('-modify_date')
description_name = 'سهمیه' # noqa
elif query.get('param') == 'assigner':
product = product.filter(
Q(assigner_organization=organization)
).order_by('-modify_date')
description_name = 'توزیع' # noqa
elif query.get('param') == 'all':
product = product.filter(
Q(assigner_organization=organization) |
Q(assigned_organization=organization)
).order_by('-modify_date')
description_name = ''
ser_data = distribution_serializers.QuotaDistributionSerializer(product, many=True).data
excel_options = [
"ردیف",
"شناسه توزیع",
"شناسه سهمیه",
"تاریخ ثبت",
"توزیع کننده",
"دریافت کننده",
"وزن",
"وزن توزیع شده",
"وزن باقیمانده",
"وزن فروش رفته",
"مانده انبار",
"ورودی به انبار",
"توضیحات",
]
header_list = [
"وزن",
"وزن توزیع شده",
"وزن باقیمانده",
"وزن فروش رفته",
"مانده انبار",
"ورودی به انبار",
]
create_header(worksheet, header_list, 5, 2, height=25, border_style='thin')
excel_description(worksheet, 'B1', f'{description_name}', row2='C3')
create_header_freez(worksheet, excel_options, 1, 6, 7, height=25, width=20)
l = 6
m = 1
if ser_data:
for data in ser_data:
list1 = [
m,
data['distribution_id'] or '',
str(data['quota']['quota_id']) if data.get('quota') and data['quota'].get('quota_id') else '',
str(shamsi_date(convert_str_to_date(data['create_date']), in_value=True)) if data.get(
'create_date') else '',
(data[
'assigner_organization'] or {}).get('organization') or '-',
(data[
'assigned_organization'] or {}).get('organization') or '-',
data.get('weight') or 0,
data.get('distributed') or 0,
data.get('remaining_weight') or 0,
data.get('been_sold') or 0,
data.get('warehouse_balance') or 0,
data.get('warehouse_entry') or 0,
data.get('description') or '-'
]
create_value(worksheet, list1, l + 1, 1, height=24, m=m)
m += 1
l += 1
weight = sum((data['weight'] or 0) for data in ser_data)
distributed = sum((data['distributed'] or 0) for data in ser_data)
remaining_weight = sum((data['remaining_weight'] or 0) for data in ser_data)
been_sold = sum((data['been_sold'] or 0) for data in ser_data)
warehouse_balance = sum((data['warehouse_balance'] or 0) for data in ser_data)
warehouse_entry = sum((data['warehouse_entry'] or 0) for data in ser_data)
value_list = [
weight,
distributed,
remaining_weight,
been_sold,
warehouse_balance,
warehouse_entry,
]
create_value(worksheet, value_list, 3, 5, border_style='thin')
list2 = [
'مجموع==>',
'',
'',
'',
'',
'',
weight,
distributed,
remaining_weight,
been_sold,
warehouse_balance,
warehouse_entry,
'',
]
create_value(worksheet, list2, l + 3, 1, color='gray') # noqa
workbook.save(output)
output.seek(0)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') # noqa
response[
'Content-Disposition'] = f'attachment; filename="سهمیه.xlsx"'.encode( # noqa
'utf-8')
response.write(output.getvalue())
return response
# noqa # طرح های تشویقی
@action(
methods=['get'],
detail=False,
url_path='incentive_plan_excel',
url_name='incentive_plan_excel',
name='incentive_plan_excel'
)
def incentive_plan_excel(self, request):
output = BytesIO()
workbook = Workbook()
worksheet = workbook.active
worksheet.sheet_view.rightToLeft = True
worksheet.insert_rows(1)
today = datetime.now().date()
user_relations = product_models.UserRelations.objects.filter(user=request.user).first()
incentive_plans = user_relations.incentive_plans.filter(
Q(is_time_unlimited=False) |
Q(start_date_limit__lte=today, end_date_limit__gte=today)
)
ser_data = IncentivePlanSerializer(incentive_plans, many=True).data
excel_options = [
"ردیف",
"نام",
"توضیحات",
"نوع طرح",
"گروه",
"محدودیت زمانی",
"شروع محدودیت",
"پایان طرح",
]
excel_description(worksheet, 'B1', f'طرح های تشویقی', row2='C3')
create_header_freez(worksheet, excel_options, 1, 6, 7, height=25, width=20)
l = 6
m = 1
if ser_data:
for data in ser_data:
grop_name = 'شهری'
if data.get('group') == 'rural':
grop_name = 'روستایی'
elif data.get('group') == 'nomadic':
grop_name = 'عشایری'
is_time_unlimited = 'دارد' if data.get('is_time_unlimited') == True else 'ندارد'
list1 = [
m,
data['name'] or '-',
data['description'] or '-',
data['plan_type'] or '-',
grop_name,
is_time_unlimited,
str(shamsi_date(convert_str_to_date(data.get('start_date_limit')), in_value=True)),
str(shamsi_date(convert_str_to_date(data.get('end_date_limit')), in_value=True)),
]
create_value(worksheet, list1, l + 1, 1, height=24, m=m)
m += 1
l += 1
list2 = [
'',
'',
'',
'',
'',
'',
'',
'',
]
create_value(worksheet, list2, l + 3, 1, height=24, color='gray') # noqa
workbook.save(output)
output.seek(0)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response[
'Content-Disposition'] = f'attachment; filename="طرح های تشویقی.xlsx"'.encode( # noqa
'utf-8')
response.write(output.getvalue())
return response
# noqa # سهمیه های فعال و بایگانی
@action(
methods=['get'],
detail=False,
url_path='detail_quota_excel',
url_name='detail_quota_excel',
name='detail_quota_excel'
)
def detail_quota_excel(self, request):
queryset = product_models.Quota.objects.filter(id=request.GET['id'], trash=False)
serializer_class = QuotaSerializer
filter_backends = [filters.SearchFilter]
search_fields = [
"registerer_organization__name",
"quota_id",
"product__name",
"sale_type",
"sale_unit__unit",
"group",
]
output = BytesIO()
workbook = Workbook()
worksheet = workbook.active
worksheet.sheet_view.rightToLeft = True
worksheet.insert_rows(1)
active = request.GET.get('active')
queryset = self.filter_query(queryset) # return by search param or all objects
organization = get_organization_by_user(request.user)
queryset = queryset.filter(
Q(registerer_organization=organization)).first()
if active:
quta_type = 'فعال'
else:
quta_type = 'بایگانی'
data = serializer_class(queryset).data
excel_options = [
"ردیف",
"شناسه سهمیه",
"محصول",
"وزن محصول",
"وزن باقیمانده",
"تاریخ ثبت",
"واحد فروش",
"گروه",
"سهمیه ماه",
"نوع فروش",
"مجوز فروش",
"قیمت درب کارخانه",
"قیمت درب تعاونی",
]
excel_description(worksheet, 'B1',
'سهمیه {0} با شناسه سهمیه {1}'.format(quta_type, str(data['quota_id'] or '-')), row2='C2',
size=11)
create_header(worksheet, excel_options, 1, 4, height=25, width=20)
l = 5
m = 1
fa_mount = {
1: "فروردین",
2: "اردیبهشت",
3: "خرداد",
4: "تیر",
5: "مرداد",
6: "شهریور",
7: "مهر",
8: "آبان",
9: "آذر",
10: "دی",
11: "بهمن",
12: "اسفند",
}
group_type = data.get('month_choices')
sale_license = data.get('sale_license')
if group_type:
mount_num = [num for num in group_type]
fa_mount1 = [fa_mount.get(name, name) for name in mount_num]
fa_mount_text = ' - '.join(fa_mount1) if fa_mount1 else '-'
else:
fa_mount_text = '-'
if sale_license:
sale_license_mount_num = [num for num in sale_license]
fa_mount2 = [fa_mount.get(name, name) for name in sale_license_mount_num]
sale_license_fa_mount_text = ' - '.join(fa_mount2) if fa_mount2 else '-'
else:
sale_license_fa_mount_text = '-'
sale_type = 'دولتی' if data['sale_type'] == 'gov' else 'آزاد'
group_name = data.get('group')
if group_name:
if group_name == 'rural':
group_name_fa = 'روستایی'
elif group_name == 'nomadic':
group_name_fa = 'عشایری'
else:
group_name_fa = 'دولتی'
else:
group_name_fa = '-'
list1 = [
m,
str(data['quota_id'] or '-'),
(data.get('product') or {}).get('product') or '-',
data['quota_weight'] or '-',
data['remaining_weight'] or '-',
str(shamsi_date(convert_str_to_date(data.get('create_date')), in_value=True)),
(data['sale_unit'] or {}).get('unit') or '-',
group_name_fa,
fa_mount_text,
sale_type,
sale_license_fa_mount_text,
int(data['base_price_factory'].split('.')[0]),
int(data['base_price_cooperative'].split('.')[0]),
]
create_value(worksheet, list1, l, 1, height=24, m=m)
excel_description(worksheet, 'A8',
'سهمیه بندی دام'.format(quta_type, str(data['quota_id'] or '-')), row2='E8',
size=10)
excel_options = [
"ردیف",
"گروه",
"حجم",
"دسته",
"محصول",
]
livestock_allocations = data.get('livestock_allocations')
if livestock_allocations:
livestock_allocation_num = 10
livestock_allocation_m = 1
for livestock_allocation in livestock_allocations:
livestock_group = livestock_allocation.get('livestock_group')
if livestock_group:
if livestock_group == 'rural':
group_name_fa = 'روستایی'
elif livestock_group == 'nomadic':
group_name_fa = 'عشایری'
else:
group_name_fa = 'دولتی'
else:
group_name_fa = '-'
weight_type = (livestock_allocation.get('livestock_type') or {}).get('weight_type') or None
name = (livestock_allocation.get('livestock_type') or {}).get('name') or None
weight_type_fa='سبک' if weight_type == 'L' else 'سنگین'
list1 = [
livestock_allocation_m,
group_name_fa,
int(livestock_allocation['quantity_kg'].split('.')[0]),
weight_type_fa,
name,
]
create_value(worksheet, list1, livestock_allocation_num, 1, height=24, m=livestock_allocation_m,
border_style='thin',m_color='F2F2F2')
livestock_allocation_num += 1
livestock_allocation_m += 1
else:
excel_description(worksheet, 'A10',
'سهمیه بندی وجود ندارد', row2='E10',
size=10, color='red')
create_header(worksheet, excel_options, 1, 9, height=25, width=20, different_color='C9C9C9', text_color='262626',
border_style='thin')
excel_description(worksheet, 'G8',
'محدودیت ها', row2='H8',
size=10)
excel_options = [
"محدودیت بر اساس شهرستان و تعاونی",
"محدودیت بر اساس بازه سنی دام",
]
create_header(worksheet, excel_options, 7, 9, height=25, width=25, different_color='C9C9C9',
text_color='262626',
border_style='thin')
limit_by_organizations = data.get('limit_by_organizations')
if limit_by_organizations:
limit_by_organization_num = 10
limit_by_organization_m = 1
for limit_by_organization in limit_by_organizations:
name = limit_by_organization.get('name') or '-'
list1 = [
name
]
create_value(worksheet, list1, limit_by_organization_num, 7, height=24, m=limit_by_organization_m,
border_style='thin', m_color='F2F2F2')
limit_by_organization_num += 1
limit_by_organization_m += 1
livestock_limitations = data.get('livestock_limitations')
if livestock_limitations:
livestock_limitations_num = 10
livestock_limitations_m = 1
for livestock_limitation in livestock_limitations:
weight_type = (livestock_limitation.get('livestock_type') or {}).get('weight_type') or None
weight_type_fa = 'سبک' if weight_type == 'L' else 'سنگین'
livestock_type = livestock_limitation.get('livestock_type')
list1 = [
f'{livestock_type["name"]} ({weight_type_fa}) با سن {livestock_limitation["age_month"]}',
]
create_value(worksheet, list1, livestock_limitations_num, 8, height=24, m=livestock_limitations_m,
border_style='thin', m_color='F2F2F2')
livestock_limitations_m += 1
livestock_limitations_num += 1
excel_description(worksheet, 'J8',
'طرح های تشویقی', row2='M8',
size=10)
excel_options = [
"ردیف",
"طرح",
"وزن سبک",
"وزن سنگین",
]
create_header(worksheet, excel_options, 10, 9, height=25, width=25, different_color='C9C9C9',
text_color='262626',
border_style='thin')
incentive_plans = data.get('incentive_plan')
if incentive_plans:
incentive_plan_num = 10
incentive_plan_m = 1
for incentive_plan in incentive_plans:
list1 = [
incentive_plan_m,
incentive_plan['incentive_plan_name'],
incentive_plan['light_value'],
incentive_plan['heavy_value'],
]
create_value(worksheet, list1, incentive_plan_num, 10, height=24, m=incentive_plan_m,
border_style='thin', m_color='F2F2F2')
incentive_plan_num += 1
incentive_plan_m += 1
workbook.save(output)
output.seek(0)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response[
'Content-Disposition'] = f'attachment; filename="همیه {quta_type}.xlsx"'.encode( # noqa
'utf-8')
response.write(output.getvalue())
return response