diff --git a/.gitignore b/.gitignore index 317aed7..67e7e3a 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,6 @@ cython_debug/ .vscode/ *.xlsx + +# Temporary documents +makedoc/tempdoc/ diff --git a/docker-compose.yml b/docker-compose.yml index d02bd7e..f879dc5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.8' services: db: image: postgres:16.3-alpine diff --git a/makedoc/services.py b/makedoc/services.py index d62b6e7..4d79f3a 100644 --- a/makedoc/services.py +++ b/makedoc/services.py @@ -4,6 +4,7 @@ import babel.dates as bd import openpyxl import pymorphy3 +from openpyxl.styles import Alignment, Border, Font, Side from clients.models import Client from goods.models import Factory, Product @@ -13,403 +14,412 @@ morph = pymorphy3.MorphAnalyzer() -def get_region(request): - return City.objects.first() - - -def get_factory(request): - return Factory.objects.first() - - -def get_rw(request): - return RailwayStation.objects.first() - - -def get_client(request): - return Client.objects.all().first() - - -def get_user(request): - return CustomUser.objects.first() - - -def get_logistics(request): - pass - - -def get_product(request): - return Product.objects.first() - - def get_current_date(): - # Сегодняшняя дата return date.today() -def format_date_nomn_case(date_object): - # Приводим дату к именительному падежу - return morph.parse(date_object)[0].inflect({"nomn"}).word +def format_date_case(date_object, case): + # case - падеж + return morph.parse(str(date_object))[0].inflect({case}).word def format_month_ru_locale(date_object): - # Форматируем месяц согласно русской локали return bd.format_date(date_object, "MMMM", locale="ru_RU") def get_formatted_date_agreement(): - # Форматируем текущую дату согласно русской локали return bd.format_date(get_current_date(), "«d» MMMM y г.", locale="ru_RU") -def get_formatted_date_shipment(): +def get_formatted_date_shipment(case): current_date = get_current_date() - next_month_date = current_date.replace(day=1) + timedelta(days=31) + next_month_date = (current_date.replace(day=1) + timedelta(days=31)).replace(day=1) raw_current_month = format_month_ru_locale(current_date) raw_next_month = format_month_ru_locale(next_month_date) - current_month = format_date_nomn_case(raw_current_month) - next_month = format_date_nomn_case(raw_next_month) - if current_date.year == next_month_date.year: - return f"{current_month}-{next_month} {current_date.year} г." - next_month_date = current_date.replace(day=1) + timedelta(days=31) - raw_current_month = format_month_ru_locale(current_date) - raw_next_month = format_month_ru_locale(next_month_date) - current_month = format_date_nomn_case(raw_current_month) - next_month = format_date_nomn_case(raw_next_month) + current_month = format_date_case(raw_current_month, case) + next_month = format_date_case(raw_next_month, case) if current_date.year == next_month_date.year: return f"{current_month}-{next_month} {current_date.year} г." else: return f"{current_month} {current_date.year} г.-{next_month} {next_month_date.year} г." -def write_to_excel_auto(request): - user = get_user(request) - client = get_client(request) - product = get_product(request) - factory = get_factory(request) - - # Открытие файла шаблона - template_path = "makedoc/excel-templates/spec.xlsx" - wb = openpyxl.load_workbook(template_path) - ws = wb.active - - # Форматирование даты договора - formatted_contract_date = client.contract_date.strftime("%d.%m.%Y") - - # Номер приложения - ws.cell(row=1, column=1, value=f"Приложение № {client.last_application_number}") - - # Номер договора - ws.cell( - row=2, - column=1, - value=f"к договору поставки № {client.contract_number} от {formatted_contract_date}г.", - ) - ws.cell(row=4, column=1, value=client.client_name) - ws.cell(row=6, column=6, value=get_formatted_date_agreement()) - - # Значение строки для стартовой подвижной ячейки - caret = 10 - - # Берем количество товаров из реквеста - goods_quantity = 3 - - # Наполняем таблицу товарами - for _ in range(goods_quantity): - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=3) - ws.cell(row=caret, column=1, value=f"{str(product.flour_name)} {product.brand}") - ws.cell(row=caret, column=4, value=product.package.package) - # Берем из реквеста (рефакторинг) - ws.cell(row=caret, column=5, value=20) - # Возможно применить скидку тут - ws.cell(row=caret, column=6, value=str(product.price)) +class Documents: + def __init__(self): + self.auto = 0 + self.rw = 0 + self.service_note = 0 + self.transport_sheet = 0 + + def update_documents(self, documents_list): + if "auto" in documents_list: + self.auto = 1 + if "rw" in documents_list: + self.rw = 1 + if "service_note" in documents_list: + self.service_note = 1 + if "transport_sheet" in documents_list: + self.transport_sheet = 1 + + def form_auto_document(self, request): + self.docname = "auto" + try: + user = self.get_user(request) + client = self.get_client(request) + product = self.get_product(request) + factory = self.get_factory(request) + logistics = self.get_logistics(request) + except Exception as e: + return f"Error fetching data: {e}" + + template_path = "makedoc/excel-templates/spec.xlsx" + wb = openpyxl.load_workbook(template_path) + ws = wb.active + + self.fill_contract_info(ws, client) + self.fill_product_info(ws, product, logistics, 10) + self.fill_factory_info(ws, factory) + self.fill_auto_services(ws, logistics) + self.fill_debt_info(ws) + self.fill_legal_info(ws, client) + self.fill_signatures(ws, client) + self.fill_manager_contact(ws, user) + + self.apply_styles(ws) + + self.save_workbook(wb, user) + + def fill_contract_info(self, ws, client): + formatted_contract_date = client.contract_date.strftime("%d.%m.%Y") + title = ws.cell(row=1, column=1, value=f"Приложение № {client.last_application_number}") + title.font = Font(bold=True) + ws.cell( + row=2, + column=1, + value=f"к договору поставки № {client.contract_number} от {formatted_contract_date}г.", + ) + ws.cell(row=4, column=1, value=client.client_name) + ws.cell(row=6, column=6, value=get_formatted_date_agreement()) + + def fill_product_info(self, ws, product, logistics, caret): + goods_quantity = 7 + thin_border = Border( + left=Side(style="thin"), + right=Side(style="thin"), + top=Side(style="thin"), + bottom=Side(style="thin"), + ) + + for _ in range(goods_quantity): + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=3) + ws.cell(row=caret, column=1, value=f"{str(product.flour_name)} {product.brand}") + ws.cell(row=caret, column=4, value=product.package.package) + ws.cell(row=caret, column=5, value=20) + ws.cell(row=caret, column=6, value=str(product.price)) + ws.cell(row=caret, column=7, value=logistics) + ws.cell(row=caret, column=8, value=product.price - logistics) + + for col_num in range(1, 9): + cell = ws.cell(row=caret, column=col_num) + cell.border = thin_border + if cell.column > 2: + cell.alignment = Alignment(horizontal="center", vertical="center") + caret += 1 + self.caret_product = caret + 1 + + def fill_factory_info(self, ws, factory): + caret = self.caret_product + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) + ws.cell(row=caret, column=1, value="Грузоотправитель:") + ws.cell(row=caret, column=3, value=factory.full_name) + self.caret_factory = caret + 1 + + def fill_auto_services(self, ws, logistics): + caret = self.caret_factory + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) + ws.cell(row=caret, column=1, value="Автотранспортные услуги:") + ws.cell( + row=caret, + column=3, + value="не входят в стоимость товара" + if logistics != 0 + else "входят в стоимость товара", + ) + self.caret_services = caret + 1 + + def fill_debt_info(self, ws): + caret = self.caret_services + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) + ws.cell(row=caret, column=1, value="Срок отгрузки:") + ws.cell(row=caret, column=3, value=get_formatted_date_shipment("nomn")) + ws.merge_cells(start_row=caret + 1, start_column=1, end_row=caret + 1, end_column=6) + pdz = "▪Продавец имеет право не осуществлять отгрузку товара до полного погашения \ +Покупателем просроченной дебиторской задолженности." + debt = ws.cell(row=caret + 1, column=1, value=pdz) + debt.alignment = Alignment(wrap_text=True, horizontal="justify", vertical="center") + ws.row_dimensions[caret + 1].height = 30 + self.caret_debt = caret + 2 + + def fill_legal_info(self, ws, client): + caret = self.caret_debt + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) + formatted_contract_date = client.contract_date.strftime("%d.%m.%Y") + contract_option = f"▪Настоящее приложение составлено и подписано в двух экземплярах, \ +имеющих одинаковую юридическую силу, по одному для каждой из сторон, вступает в силу с момента \ +подписания и является неотъемлемой частью договора № {client.contract_number} от \ +{formatted_contract_date}г." + legal = ws.cell(row=caret, column=1, value=contract_option) + legal.alignment = Alignment(wrap_text=True, horizontal="justify", vertical="center") + ws.row_dimensions[caret].height = 40 + self.caret_legal = caret + 4 + + def fill_signatures(self, ws, client): + caret = self.caret_legal + ws.cell(row=caret, column=1, value="Генеральный директор") + ws.cell(row=caret + 1, column=1, value="ООО «Торговый дом «Оскольская мука»") + ws.cell(row=caret + 1, column=6, value="С.А. Годизов") + ws.cell(row=caret + 9, column=1, value=str(client.director_position)) + ws.cell(row=caret + 10, column=1, value=client.client_name) + ws.cell(row=caret + 10, column=6, value=client.director_name) + self.caret_signatures = caret + 11 + + def fill_manager_contact(self, ws, user): + caret = 59 + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) + manager = ws.cell( + row=caret, column=1, value=f"Ваш персональный менеджер: {user.full_name}" + ) + manager.alignment = Alignment(horizontal="center", vertical="center") + ws.merge_cells(start_row=caret + 1, start_column=1, end_row=caret + 1, end_column=6) + phone = ws.cell( + row=caret + 1, + column=1, + value=f"Тел. {user.phone_number_personal}, моб. {user.phone_number_work}", + ) + phone.alignment = Alignment(horizontal="center", vertical="center") + + def save_workbook(self, wb, user): + directory = os.path.join( + "makedoc", + "tempdoc", + get_current_date().strftime("%d.%m.%Y"), + user.full_name.split()[0], + ) + os.makedirs(directory, exist_ok=True) + new_file_path = os.path.join( + directory, + f"{self.docname}_{user.full_name.split()[0]}_\ +{get_current_date().strftime('%d.%m.%Y')}.xlsx", + ) + wb.save(new_file_path) + + def apply_styles(self, ws): + for row in ws.iter_rows(): + for cell in row: + if cell.value is not None: + cell.font = Font(name="Times New Roman", size=12) + + for row_num in [1, 9]: + for cell in ws[row_num]: + if cell.value is not None: + cell.font = Font(bold=True, size=12) + + def get_user(self, request): + try: + return CustomUser.objects.first() + except CustomUser.DoesNotExist: + raise Exception("User not found") + + def get_client(self, request): + try: + return Client.objects.all().first() + except Client.DoesNotExist: + raise Exception("Client not found") + + def get_product(self, request): + try: + return Product.objects.first() + except Product.DoesNotExist: + raise Exception("Product not found") + + def get_factory(self, request): + try: + return Factory.objects.first() + except Factory.DoesNotExist: + raise Exception("Factory not found") + + def get_rw(self, request): + try: + return RailwayStation.objects.all().first() + except RailwayStation.DoesNotExist: + raise Exception("Railway station not found") + + def get_discount(self, request): + return 15 + + def get_city(self, request): + try: + return City.objects.all().first() + except City.DoesNotExist: + raise Exception("City not found") + + def get_logistics(self, request): + return 2500 + + def form_rw_document(self, request): + self.docname = "rw" + try: + user = self.get_user(request) + client = self.get_client(request) + product = self.get_product(request) + rw = self.get_rw(request) + factory = self.get_factory(request) + logistics = self.get_logistics(request) + except Exception as e: + return f"Error fetching data: {e}" + + template_path = "makedoc/excel-templates/spec.xlsx" + wb = openpyxl.load_workbook(template_path) + ws = wb.active + + self.fill_contract_info(ws, client) + self.fill_product_info(ws, product, logistics, 10) + self.fill_factory_info(ws, factory) + self.fill_rw_services(ws, rw, factory, client, logistics) + self.fill_debt_info(ws) + self.fill_legal_info(ws, client) + self.fill_signatures(ws, client) + self.fill_manager_contact(ws, user) + + self.apply_styles(ws) + + self.save_workbook(wb, user) + + def fill_rw_services(self, ws, rw, factory, client, logistics): + caret = self.caret_factory + ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) + ws.cell(row=caret, column=1, value="Поставка осуществляется:") + ws.cell(row=caret, column=3, value="ж/д транспортом") caret += 1 - caret += 1 - - # Комбинат-грузоотправитель - # Берем из реквеста (рефакторинг) - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) - ws.cell(row=caret, column=1, value="Грузоотправитель:") - ws.cell(row=caret, column=3, value=factory.full_name) - caret += 1 - - # Автоуслуги - # Проверка стоимости доставки в реквесте (рефакторинг) - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) - ws.cell(row=caret, column=1, value="Автотранспортные услуги:") - ws.cell( - row=caret, - column=3, - value="не входят в стоимость товара" if 0 else "входят в стоимость товара", - ) - caret += 1 - - # Срок отгрузки - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=2) - ws.cell(row=caret, column=1, value="Срок отгрузки:") - - ws.cell(row=caret, column=3, value=get_formatted_date_shipment()) - caret += 2 - - # Право по дебиторской задолженности - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - - pdz = "▪Продавец имеет право не осуществлять отгрузку товара до полного погашения Покупателем \ -просроченной дебиторской задолженности." - ws.cell(row=caret, column=1, value=pdz) - caret += 1 - - # Юридическая информация - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - - contract_option = f"▪Настоящее приложение составлено и подписано в двух экземплярах, имеющих \ -одинаковую юридическую силу, по одному для каждой из сторон, вступает в силу с момента \ -подписания и является неотъемлемой частью договора № \ -{client.contract_number} от {formatted_contract_date}г." - ws.cell(row=caret, column=1, value=contract_option) - caret += 4 - - # Подписант продавца - ws.cell(row=caret, column=1, value="Генеральный директор") - caret += 1 - ws.cell(row=caret, column=1, value="ООО «Торговый дом «Оскольская мука»") - ws.cell(row=caret, column=6, value="С.А. Годизов") - caret += 8 - - # Подписант покупателя - ws.cell(row=caret, column=1, value=str(client.director_position)) - caret += 1 - ws.cell(row=caret, column=1, value=client.client_name) - # Нужно спарсить имя директора и вывести в сокращенном виде - ws.cell(row=caret, column=6, value=client.director_name) - - caret = 49 - # Контакты менеджера - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - ws.cell(row=caret, column=1, value=f"Ваш персональный менеджер: {user.full_name}") - caret += 1 - - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - ws.cell( - row=caret, - column=1, - value=f"Тел. {user.phone_number_personal}, моб. {user.phone_number_work}", - ) - - # Тут предлагаю тоже отрефакторить, сделать отдельную функцию для сохранения объекта - # Создать структуру каталогов - directory = os.path.join( - "makedoc", get_current_date().strftime("%d.%m.%Y"), user.full_name.split()[0] - ) - os.makedirs(directory, exist_ok=True) - - # Сохранить файл - new_file_path = os.path.join( - directory, - f"auto_{user.full_name.split()[0]}_{get_current_date().strftime('%d.%m.%Y')}.xlsx", - ) - wb.save(new_file_path) - wb.save(new_file_path) - - -def write_to_excel_rw(request): - user = get_user(request) - client = get_client(request) - product = get_product(request) - rw = get_rw(request) - factory = get_factory(request) - - # Открытие файла шаблона - template_path = "makedoc/excel-templates/spec.xlsx" - wb = openpyxl.load_workbook(template_path) - ws = wb.active - - # Форматирование даты договора - formatted_contract_date = client.contract_date.strftime("%d.%m.%Y") - - # Номер приложения - ws.cell(row=1, column=1, value=f"Приложение № {client.last_application_number}") - - # Номер договора - ws.cell( - row=2, - column=1, - value=f"к договору поставки № {client.contract_number} от {formatted_contract_date}г.", - ) - ws.cell(row=4, column=1, value=client.client_name) - ws.cell(row=6, column=6, value=get_formatted_date_agreement()) - - # Значение строки для стартовой подвижной ячейки - caret = 10 - - # Берем количество товаров из реквеста - goods_quantity = 3 - - ws.cell(row=4, column=1, value=client.client_name) - ws.cell(row=6, column=6, value=get_formatted_date_agreement()) - - # Наполняем таблицу товарами - for _ in range(goods_quantity): - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=3) - ws.cell(row=caret, column=1, value=f"{str(product.flour_name)} {product.brand}") - ws.cell(row=caret, column=4, value=product.package.package) - # Берем из реквеста (рефакторинг) - ws.cell(row=caret, column=5, value=20) - # Возможно применить скидку тут - ws.cell(row=caret, column=6, value=str(product.price)) + ws.cell(row=caret, column=1, value="Станция отправления:") + ws.cell(row=caret, column=3, value=rw.station_name) caret += 1 - caret += 1 - - ws.cell(row=caret, column=1, value="Поставка осуществляется:") - ws.cell(row=caret, column=3, value="ж/д транспортом") - - caret += 1 - - # Станция назначения - ws.cell(row=caret, column=1, value="Станция отправления:") - ws.cell(row=caret, column=3, value=rw.station_name) - - caret += 1 - - # Грузоотправитель - ws.cell(row=caret, column=1, value="Грузоотправитель:") - ws.cell(row=caret, column=3, value=factory.full_name) - - caret += 1 - - # Условия поставки - ws.cell(row=caret, column=1, value="Условия поставки") - ws.cell( - row=caret, - column=3, - value="франко-вагон станция отправления" if 0 else "франко-вагон станция назначения", - ) - - caret += 1 - - # Срок отгрузки - ws.cell(row=caret, column=1, value="Срок отгрузки:") - ws.cell(row=caret, column=3, value=get_formatted_date_shipment()) - - caret += 2 - - # Отгрузочные реквизиты - ws.cell(row=caret, column=1, value="Отгрузочные реквизиты:") - - caret += 1 - - ws.cell(row=caret, column=1, value="Станция назначения:") - ws.cell(row=caret, column=3, value=client.railway_station.station_name) - - caret += 1 - - # Код станции - ws.cell(row=caret, column=1, value="Код станции:") - ws.cell(row=caret, column=3, value=client.railway_station.station_id) - - caret += 1 - - # Получатель - ws.cell(row=caret, column=1, value="Получатель:") - ws.cell(row=caret, column=3, value=client.receiver_name) - - caret += 1 - - # Код получателя - ws.cell(row=caret, column=1, value="Код получателя:") - ws.cell(row=caret, column=3, value=client.receiver_id) - - caret += 1 - - # ОКПО - ws.cell(row=caret, column=1, value="ОКПО:") - ws.cell(row=caret, column=3, value=client.receiver_okpo) - - caret += 1 - - # Адрес - ws.cell(row=caret, column=1, value="Адрес:") - ws.cell(row=caret, column=3, value=client.receiver_adress) - - caret += 2 - - contract_option = f"▪Настоящее приложение составлено и подписано в двух экземплярах, имеющих \ -одинаковую юридическую силу, по одному для каждой из сторон, вступает в силу с момента \ -подписания и является неотъемлемой частью договора № \ -{client.contract_number} от {formatted_contract_date}г." - ws.cell(row=caret, column=1, value=contract_option) - caret += 4 - - # Подписант продавца - ws.cell(row=caret, column=1, value="Генеральный директор") - caret += 1 - ws.cell(row=caret, column=1, value="ООО «Торговый дом «Оскольская мука»") - ws.cell(row=caret, column=6, value="С.А. Годизов") - caret += 8 - - # Подписант покупателя - ws.cell(row=caret, column=1, value=str(client.director_position)) - caret += 1 - ws.cell(row=caret, column=1, value=client.client_name) - # Нужно спарсить имя директора и вывести в сокращенном виде - ws.cell(row=caret, column=6, value=client.director_name) - - caret = 49 - # Контакты менеджера - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - ws.cell(row=caret, column=1, value=f"Ваш персональный менеджер: {user.full_name}") - caret += 1 + ws.cell(row=caret, column=1, value="Грузоотправитель:") + ws.cell(row=caret, column=3, value=factory.full_name) + caret += 1 - ws.merge_cells(start_row=caret, start_column=1, end_row=caret, end_column=6) - ws.cell( - row=caret, - column=1, - value=f"Тел. {user.phone_number_personal}, моб. {user.phone_number_work}", - ) + ws.cell(row=caret, column=1, value="Условия поставки") + ws.cell( + row=caret, + column=3, + value="не входят в стоимость товара" + if logistics != 0 + else "входят в стоимость товара", + ) + caret += 2 + + ws.cell(row=caret, column=1, value="Отгрузочные реквизиты:") + caret += 1 - # Создать структуру каталогов - directory = os.path.join( - "makedoc", get_current_date().strftime("%d.%m.%Y"), user.full_name.split()[0] - ) - os.makedirs(directory, exist_ok=True) + ws.cell(row=caret, column=1, value="Станция назначения:") + ws.cell(row=caret, column=3, value=client.railway_station.station_name) + caret += 1 - # Сохранить файл - new_file_path = os.path.join( - directory, f"rw_{user.full_name.split()[0]}_{get_current_date().strftime('%d.%m.%Y')}.xlsx" - ) - wb.save(new_file_path) + ws.cell(row=caret, column=1, value="Код станции:") + station_code_value = ws.cell(row=caret, column=3, value=client.railway_station.station_id) + station_code_value.alignment = Alignment(horizontal="left") + caret += 1 + ws.cell(row=caret, column=1, value="Получатель:") + ws.cell(row=caret, column=3, value=client.receiver_name) + caret += 1 -def write_to_excel_sluzebnyi(request): - user = get_user(request) - city = get_region(request) - client = get_client(request) + ws.cell(row=caret, column=1, value="Код получателя:") + receiver_code_value = ws.cell(row=caret, column=3, value=client.receiver_id) + receiver_code_value.alignment = Alignment(horizontal="left") + caret += 1 - # Принимаем с фронта макс размер скидки (пока хардкод) - discount = 15 + ws.cell(row=caret, column=1, value="ОКПО:") + okpo_value = ws.cell(row=caret, column=3, value=client.receiver_okpo) + okpo_value.alignment = Alignment(horizontal="left") + caret += 1 - # Открытие файла шаблона - template_path = "makedoc/excel-templates/sluz.xlsx" - wb = openpyxl.load_workbook(template_path) - ws = wb.active + ws.cell(row=caret, column=1, value="Адрес:") + ws.cell(row=caret, column=3, value=client.receiver_adress) + caret += 1 - # Записка - ws.cell(row=15, column=1, value=f"{get_formatted_date_agreement()} № 12/2.2/23/3-") - text = f"В целях увеличения объема продаж на территории {city.region} прошу Вашего \ + self.caret_services = caret + 1 + + def form_service_note(self, request): + self.docname = "service_note" + try: + client = self.get_client(request) + discount = self.get_discount(request) + city = self.get_city(request) + user = self.get_user(request) + product = self.get_product(request) + logistics = self.get_logistics(request) + except Exception as e: + return f"Error fetching data: {e}" + + # Открытие файла шаблона + template_path = "makedoc/excel-templates/service_note.xlsx" + wb = openpyxl.load_workbook(template_path, keep_vba=True) + ws = wb.active + + self.fill_text_note(ws, client, discount, city) + self.fill_product_info(ws, product, logistics, 22) + self.apply_styles(ws) + + self.save_workbook(wb, user) + + def fill_text_note(self, ws, client, discount, city): + ws.cell(row=15, column=1, value=f"{get_formatted_date_agreement()} № 12/2.2/23/3-") + text = f" В целях увеличения объема продаж на территории {city.region} прошу Вашего \ согласования применить скидку для контрагента {client.client_name} (г. {city.city}) до {discount}%\ -в {get_formatted_date_shipment} на продукцию следующего ассортимента: " - ws.cell(row=19, column=1, value=text) - - # Создать структуру каталогов - directory = os.path.join( - "makedoc", get_current_date().strftime("%d.%m.%Y"), user.full_name.split()[0] - ) - os.makedirs(directory, exist_ok=True) - - # Сохранить файл - new_file_path = os.path.join( - directory, - f"sluz_{user.full_name.split()[0]}_{get_current_date().strftime('%d.%m.%Y')}.xlsx", - ) - wb.save(new_file_path) + в {get_formatted_date_shipment('loct')} на продукцию следующего ассортимента: " + ws.cell(row=19, column=1, value=text) + + def form_transport_sheet(self, request): + self.docname = "transport_sheet" + try: + user = self.get_user(request) + product = self.get_product(request) + client = self.get_client(request) + logistics = self.get_logistics(request) + factory = self.get_factory(request) + except Exception as e: + return f"Error fetching data: {e}" + + template_path = "makedoc/excel-templates/transport_sheet.xlsx" + wb = openpyxl.load_workbook(template_path, keep_vba=True) + ws = wb.active + + self.fill_contract_info_transport_sheet(ws, client) + self.fill_product_info(ws, product, logistics, 11) + + self.fill_factory_info(ws, factory) + self.fill_auto_services(ws, logistics) + self.fill_debt_info(ws) + self.fill_legal_info(ws, client) + self.fill_signatures(ws, client) + self.fill_manager_contact(ws, user) + + self.apply_styles(ws) + + self.save_workbook(wb, user) + + def fill_contract_info_transport_sheet(self, ws, client): + formatted_contract_date = client.contract_date.strftime("%d.%m.%Y") + ws.cell(row=1, column=1, value="СОПРОВОДИТЕЛЬНЫЙ ЛИСТ к") + title = ws.cell(row=2, column=1, value=f"Приложению № {client.last_application_number}") + title.font = Font(bold=True) + ws.cell( + row=3, + column=1, + value=f"к договору поставки № {client.contract_number} от {formatted_contract_date}г.", + ) + ws.cell(row=5, column=1, value=client.client_name) + ws.cell(row=7, column=8, value=get_formatted_date_agreement()) diff --git a/makedoc/tests/conftest.py b/makedoc/tests/conftest.py index 89c72bc..0debfc0 100644 --- a/makedoc/tests/conftest.py +++ b/makedoc/tests/conftest.py @@ -7,8 +7,9 @@ @pytest.fixture def user(django_user_model): - return CustomUser.objects.create_user(email='test@example.com', full_name='Test User', - password='testpassword') + return CustomUser.objects.create_user( + email="test@example.com", full_name="Test User", password="testpassword" + ) @pytest.fixture diff --git a/makedoc/tests/test_views_makedoc.py b/makedoc/tests/test_views_makedoc.py index 9c126e3..1ae2c8f 100644 --- a/makedoc/tests/test_views_makedoc.py +++ b/makedoc/tests/test_views_makedoc.py @@ -6,47 +6,47 @@ @pytest.mark.django_db def test__data_view__unauthorized_user_cannot_post_data() -> None: client = APIClient() - url = reverse('data') + url = reverse("data") data = { "client_id": 123, "items": [ {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4} + {"product_id": 2, "quantity": 5, "discount": 4}, ], "factory_id": 1, - "destination": "New York" + "destination": "New York", } - response = client.post(url, data, format='json') + response = client.post(url, data, format="json") assert response.status_code == 401 # Unauthorized @pytest.mark.django_db def test__goods__authorized_user_can_post_data(authorized_client) -> None: - url = reverse('data') + url = reverse("data") data = { "client_id": 123, "items": [ {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4} + {"product_id": 2, "quantity": 5, "discount": 4}, ], "factory_id": 1, - "destination": "New York" + "destination": "New York", } - response = authorized_client.post(url, data, format='json') + response = authorized_client.post(url, data, format="json") assert response.status_code == 200 @pytest.mark.django_db def test__goods__authorized_user_post_data_response_is_correct(authorized_client) -> None: - url = reverse('data') + url = reverse("data") data = { "client_id": 123, "items": [ {"product_id": 1, "quantity": 2, "discount": 10}, - {"product_id": 2, "quantity": 5, "discount": 4} + {"product_id": 2, "quantity": 5, "discount": 4}, ], "factory_id": 1, - "destination": "New York" + "destination": "New York", } - response = authorized_client.post(url, data, format='json') + response = authorized_client.post(url, data, format="json") assert response.json() == data diff --git a/makedoc/views.py b/makedoc/views.py index a763815..aef42e6 100644 --- a/makedoc/views.py +++ b/makedoc/views.py @@ -3,15 +3,23 @@ from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response +from makedoc.services import Documents + from .serializers import DataDocSerializer -from .services import write_to_excel_auto, write_to_excel_rw, write_to_excel_sluzebnyi def create_docs(request): - write_to_excel_auto(request) - write_to_excel_rw(request) - # Если применяется скидка, пишем служебную записку - write_to_excel_sluzebnyi(request) if 0 else None + docs = Documents() + docs.update_documents(["auto", "rw", "service_note", "transport_sheet"]) + if docs.auto: + docs.form_auto_document(request) + if docs.rw: + docs.form_rw_document(request) + if docs.service_note: + docs.form_service_note(request) + if docs.transport_sheet: + docs.form_transport_sheet(request) + return HttpResponse("Документы сохранены")