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="fسهمیه {quta_type}.xlsx"'.encode( # noqa 'utf-8') response.write(output.getvalue()) return response