create my_products_stat_excel

This commit is contained in:
7nimor
2025-08-03 13:56:59 +03:30
parent 275b84467e
commit ddc434d63e
4 changed files with 163 additions and 10 deletions

View File

@@ -14,7 +14,7 @@
</component> </component>
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.10 (env)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.10 (bazrasienv)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="PyDocumentationSettings"> <component name="PyDocumentationSettings">

2
.idea/misc.xml generated
View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (env)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (bazrasienv)" project-jdk-type="Python SDK" />
</project> </project>

View File

@@ -10,7 +10,7 @@ from rest_framework.decorators import action
from apps.core.mixins.search_mixin import ExcelDynamicSearchMixin from apps.core.mixins.search_mixin import ExcelDynamicSearchMixin
from apps.product import models as product_models 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 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.product_serializers import IncentivePlanSerializer, ProductStatsSerializer
from apps.product.web.api.v1.serializers.quota_serializers import QuotaSerializer 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, \ from common.helper_excel import create_header, excel_description, create_header_freez, create_value, shamsi_date, \
convert_str_to_date convert_str_to_date
@@ -688,3 +688,157 @@ class ProductExcelViewSet(viewsets.ModelViewSet, ExcelDynamicSearchMixin):
'utf-8') 'utf-8')
response.write(output.getvalue()) response.write(output.getvalue())
return response return response
# noqa # گزارش گیری
@action(
methods=['get'],
detail=False,
url_path='my_products_stat_excel',
url_name='my_products_stat_excel',
name='my_products_stat_excel'
)
def my_products_stat_excel(self, request):
search_fields_quota = [
"registerer_organization__name",
"quota_id",
"product__name",
"sale_type",
"sale_unit__unit",
"group",
]
queryset = product_models.Quota.objects.all()
serializer_class = QuotaSerializer
output = BytesIO()
workbook = Workbook()
worksheet = workbook.active
worksheet.sheet_view.rightToLeft = True
worksheet.insert_rows(1)
queryset = product_models.ProductStats.objects.all()
organization = get_organization_by_user(request.user)
product_stats = queryset.filter(organization=organization).order_by('-modify_date')
ser_data = ProductStatsSerializer(product_stats, many=True).data
excel_options = [
"ردیف",
"محصول",
"تعداد طرح ها",
"طرح های فعال (کیلوگرم)",
"طرح های بایگانی شده (کیلوگرم)",
"وزن کل طرح ها (کیلوگرم)",
"باقیمانده وزن طرح ها (کیلوگرم)",
"باقیمانده وزن توزیع ها (کیلوگرم)",
"توزیع دریافتی (کیلوگرم)",
"توزیع ارسال شده (کیلوگرم)",
"حجم توزیع دریافتی (کیلوگرم)",
"حجم توزیع ارسالی",
"کل وزن ورودی به انبار (کیلوگرم)",
"وزن فروش رفته (کیلوگرم)"
]
header_list = [
"تعداد طرح ها",
"طرح های فعال",
"طرح های بایگانی شده",
"وزن کل طرح ها",
"باقیمانده وزن طرح ها",
"باقیمانده وزن توزیع ها",
"توزیع دریافتی",
"توزیع ارسال شده",
"حجم توزیع دریافتی",
"حجم توزیع ارسالی",
"کل وزن ورودی به انبار",
"وزن فروش رفته"
]
create_header(worksheet, header_list, 3, 2, height=28, border_style='thin')
excel_description(worksheet, 'A1',
'گزارش گیری', row2='B2',
size=11)
create_header_freez(worksheet, excel_options, 1, 6, 7, height=28, width=20)
l = 7
m = 1
if ser_data:
for data in ser_data:
list1 = [
m,
(data.get('product') or {}).get('name') or '-',
data.get('quotas_number') or 0,
data.get('active_quotas_weight') or 0,
data.get('closed_quotas_weight') or 0,
data.get('total_quota_weight') or 0,
data.get('total_quota_remaining') or 0,
data.get('total_remaining_distribution_weight') or 0,
data.get('received_distribution_weight') or 0,
data.get('given_distribution_weight') or 0,
data.get('received_distribution_number') or 0,
data.get('given_distribution_number') or 0,
data.get('total_warehouse_entry') or 0,
data.get('total_sold') or 0,
]
create_value(worksheet, list1, l, 1, height=25, m=m)
l += 1
m += 1
quotas_number = sum((data.get('quotas_number') or 0 for data in ser_data))
active_quotas_weight = sum((data.get('active_quotas_weight') or 0 for data in ser_data))
closed_quotas_weight = sum((data.get('closed_quotas_weight') or 0 for data in ser_data))
total_quota_weight = sum((data.get('total_quota_weight') or 0 for data in ser_data))
total_quota_remaining = sum((data.get('total_quota_remaining') or 0 for data in ser_data))
total_remaining_distribution_weight = sum(
(data.get('total_remaining_distribution_weight') or 0 for data in ser_data))
received_distribution_weight = sum((data.get('received_distribution_weight') or 0 for data in ser_data))
given_distribution_weight = sum((data.get('given_distribution_weight') or 0 for data in ser_data))
received_distribution_number = sum((data.get('received_distribution_number') or 0 for data in ser_data))
given_distribution_number = sum((data.get('given_distribution_number') or 0 for data in ser_data))
total_warehouse_entry = sum((data.get('total_warehouse_entry') or 0 for data in ser_data))
total_sold = sum((data.get('total_sold') or 0 for data in ser_data))
value_list = [
quotas_number,
active_quotas_weight,
closed_quotas_weight,
total_quota_weight,
total_quota_remaining,
total_remaining_distribution_weight,
received_distribution_weight,
given_distribution_weight,
received_distribution_number,
given_distribution_number,
total_warehouse_entry,
total_sold
]
create_value(worksheet, value_list, 3, 3, border_style='thin')
list2 = [
'مجموع==>',
'',
quotas_number,
active_quotas_weight,
closed_quotas_weight,
total_quota_weight,
total_quota_remaining,
total_remaining_distribution_weight,
received_distribution_weight,
given_distribution_weight,
received_distribution_number,
given_distribution_number,
total_warehouse_entry,
total_sold
]
create_value(worksheet, list2, l + 2, 1, color='gray')
workbook.save(output)
output.seek(0)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response[
'Content-Disposition'] = f'attachment; filename="fگزارش گیری.xlsx"'.encode( # noqa
'utf-8')
response.write(output.getvalue())
return response

View File

@@ -139,6 +139,11 @@ def create_value(worksheet, list, l, num, border_style=None, m=None, height=None
for item in range(len(list)): for item in range(len(list)):
cell = worksheet.cell(row=l, column=item + num, value=list[item]) cell = worksheet.cell(row=l, column=item + num, value=list[item])
cell.alignment = Alignment_CELL cell.alignment = Alignment_CELL
if height is not None:
worksheet.row_dimensions[l].height = height
if width is not None:
worksheet.column_dimensions[openpyxl.utils.get_column_letter(item + num)].width = width
if border_style: if border_style:
cell.border = openpyxl.styles.Border( cell.border = openpyxl.styles.Border(
@@ -162,9 +167,6 @@ def create_value(worksheet, list, l, num, border_style=None, m=None, height=None
else: else:
cell.fill = PatternFill(start_color="FAF0E7", fill_type="solid") cell.fill = PatternFill(start_color="FAF0E7", fill_type="solid")
if height is not None:
worksheet.row_dimensions[l + 1].height = height
if item_num is not None and item == item_num: if item_num is not None and item == item_num:
if item_color: if item_color:
cell.fill = item_color cell.fill = item_color
@@ -174,9 +176,6 @@ def create_value(worksheet, list, l, num, border_style=None, m=None, height=None
if different_cell is not None and list[different_cell] == different_value: if different_cell is not None and list[different_cell] == different_value:
cell.fill = RED_CELL cell.fill = RED_CELL
if width is not None:
worksheet.column_dimensions[openpyxl.utils.get_column_letter(item + num)].width = width
def merge_cells(worksheet, l, s, cell1=None, cell2=None, lst=None): def merge_cells(worksheet, l, s, cell1=None, cell2=None, lst=None):
if lst is not None: if lst is not None:
@@ -311,4 +310,4 @@ def convert_str_to_date(string):
try: try:
return datetime.strptime(string, '%Y-%m-%d').date() return datetime.strptime(string, '%Y-%m-%d').date()
except ValueError: except ValueError:
return None return None