import os from django.conf import settings from typing import Dict from openpyxl import Workbook from docxtpl import DocxTemplate import jinja2 from docxcompose.composer import Composer from docx import Document from docx.enum.text import WD_PARAGRAPH_ALIGNMENT # from docx.enum.style import WD_STYLE_TYPE from docx.shared import Mm, Pt # from django.http import FileResponse from datetime import datetime, timedelta import io from .models import * # Для доступа к моделялям импортируем и их. FONT_SIZE = 12 def short_date(date, offset=0): return f'{date+timedelta(days=offset):%d.%m.%Y}' def gender_text(gender): return 'защитивший' if gender == 'муж.' else 'защитившая' def rus_month(date): MONTH=[ '', 'января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря', ] return f'{date:%d} {MONTH[date.month]} {date:%Y}\xa0' jinja_env = jinja2.Environment() jinja_env.filters['tmpl_date'] = rus_month jinja_env.filters['tmpl_short_date'] = short_date jinja_env.filters['tmpl_gender'] = gender_text def order_start(document, number, date, type): document.core_properties.title = f'№ {number} от {rus_month(date)}' document.core_properties.subject = type section = document.sections[0] section.left_margin = Mm(30) section.right_margin = Mm(14) section.top_margin = Mm(10) section.bottom_margin = Mm(10) # Меняем стиль абзаца по умолчанию: # получаем объект стиля `Normal` style = document.styles['Normal'] # # изменяем настройки шрифта style.font.name = 'Times New Roman' style.font.size = Pt(FONT_SIZE) # # настраиваем красную строку абзаца style.paragraph_format.first_line_indent = Mm(0) style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY style.paragraph_format.line_spacing = 1.0 style.paragraph_format.space_after = 0 def order_footer(document, list_proposers:Dict, list_approvers:Dict, rector:str): p = document.add_paragraph(f'Ректор___________________________________________________{rector}') p.paragraph_format.space_before = Pt(30) p.paragraph_format.space_after = Pt(20) p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER lines_number = max(len(list_approvers), len(list_proposers)) table = document.add_table(rows=lines_number * 2 + 1, cols=2) table.cell(0, 0).text = 'Проект вносят:' table.cell(0, 0).width = Mm(120) table.cell(0, 0).paragraphs[0].paragraph_format.space_after = Pt(8) table.cell(0, 1).text = 'Согласовано:' number = 1 for key, value in list_approvers.items(): table.cell(number * 2 - 1, 1).text = key table.cell(number * 2 - 1, 1).paragraphs[0].paragraph_format.space_after = Pt(2) table.cell(number * 2, 1).text = f'_____________ {value}' table.cell(number * 2, 1).paragraphs[0].paragraph_format.space_after = Pt(4) number += 1 number = 1 for key, value in list_proposers.items(): table.cell(number * 2 - 1, 0).text = key table.cell(number * 2 - 1, 0).paragraphs[0].paragraph_format.space_after = Pt(2) table.cell(number * 2, 0).text = f'_____________ {value}' table.cell(number * 2, 0).paragraphs[0].paragraph_format.space_after = Pt(4) number += 1 # return document def order_by_id(order_id): '''Подготовка документа приказа по шаблону''' order = Orders.objects.get(pk=order_id) contracts = Orders.objects.get(pk=order_id).contracts.all().order_by('client') buf = io.BytesIO() text = '' if contracts.count()==1 else 'ы' # document.add_paragraph(f'Основание: договор{text} на обучение') filename = order.template.file tpl = DocxTemplate(filename) context = { 'order': order, 'contracts': contracts, 'plural': text, } tpl.render(context, jinja_env) tpl.save(buf) buf.seek(0) return buf def order_on_enrollment(object, contracts): buf = io.BytesIO() document = Document() order_start(document, object.number, object.registered, object.type_order) p = document.add_paragraph() p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER p.paragraph_format.space_before = Mm(90) run = p.add_run('О движении контингента слушателей ИДО') run.font.bold = True document.add_paragraph() p = document.add_paragraph() p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run = p.add_run('ПРИКАЗЫВАЮ:') run.font.bold = True p = document.add_paragraph( f'Зачислить с {rus_month(object.event_date)} в число слушателей ИДО ЮРГПУ(НПИ) по дополнительной профессиональной ' 'программе профессиональной переподготовки «Машины и оборудование нефтяных и газовых промыслов». Срок ' 'обучения – 521 час. Форма обучения заочная с применением электронного обучения и дистанционных ' 'образовательных технологий.' ) p.paragraph_format.first_line_indent = Mm(12.5) p.paragraph_format.space_after = Pt(12) table = document.add_table(rows=1, cols=2) for number, item in enumerate(contracts): cell = table.cell(number, 0) cell.text = f'{number+1}. {item.client.surname} {item.client.name} {item.client.patronymic}' p = cell.paragraphs[0] p.paragraph_format.first_line_indent = Mm(10) cell = table.cell(number, 1) cell.text = f'{item.number}' table.add_row() text = '' if contracts.count()==1 else 'ы' document.add_paragraph(f'Основание: договор{text} на обучение') list_proposers = { 'Директор ИДО': 'И. А. Ревин', } list_approvers = { 'Проректор по ОД': 'Е. М. Дьяконов', 'Начальник ЮУ': 'Т. А. Кузьменко', 'Директор ДЭиФ': 'А. П. Игнатьева', 'Директор АД': 'Р. Г. Зайцев', } order_footer(document, list_proposers, list_approvers, object.structure.rector) document.save(buf) buf.seek(0) return buf def order_on_theme(order, contracts): buf = io.BytesIO() document = Document() order_start(document, order.number, order.registered, order.type_order) p = document.add_paragraph() p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER p.paragraph_format.space_before = Mm(90) run = p.add_run('Об утверждении тем выпускных работ для слушателей ИДО') run.font.bold = True document.add_paragraph() p = document.add_paragraph('В соответствии с дополнительной профессиональной программой профессиональной' ' переподготовки «Машины и оборудование нефтяных и газовых промыслов»') p.paragraph_format.first_line_indent = Mm(12.5) p = document.add_paragraph() p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER run = p.add_run('ПРИКАЗЫВАЮ:') run.font.bold = True document.add_paragraph('1. Утвердить темы выпускных квалификационных работ слушателям по дополнительной ' 'профессиональной образовательной программе профессиональной переподготовки «Машины и оборудование ' 'нефтяных и газовых промыслов»:') for number, item in enumerate(contracts): p = document.add_paragraph(f'1.{number+1}. {item.client.surname} {item.client.name} {item.client.patronymic}') p.paragraph_format.space_before = Pt(8) p.paragraph_format.first_line_indent = Mm(12.5) p.paragraph_format.keep_with_next = True p = document.add_paragraph(f'{item.degree_work.title}. Руководитель: {item.degree_work.adviser.surname} {item.degree_work.adviser.name} {item.degree_work.adviser.patronymic} - ') if item.degree_work.adviser.degree: p.add_run(f'{str(item.degree_work.adviser.degree).lower()}, ') p.add_run(f'{str(item.degree_work.adviser.post).lower()} кафедры «{order.extract.department}».') p.add_run(f' Тема предложена кафедрой «{order.extract.department}».') text = f'Основание: протокол заседания кафедры «{order.extract.department}» №{order.extract.number} от {rus_month(order.extract.date)}' list_proposers = { 'Директор ИДО': 'И. А. Ревин', } list_approvers = { 'Проректор по ОД': 'Е. М. Дьяконов', 'Директор АД': 'Р. Г. Зайцев', } order_footer(document, list_proposers, list_approvers, order.structure.rector) document.save(buf) buf.seek(0) return buf def extract_department_meeting (object, contracts): buf = io.BytesIO() document = Document() section = document.sections[0] section.left_margin = Mm(20) section.right_margin = Mm(10) section.top_margin = Mm(10) section.bottom_margin = Mm(10) # Меняем стиль абзаца по умолчанию: # получаем объект стиля `Normal` style = document.styles['Normal'] # # изменяем настройки шрифта style.font.name = 'Times New Roman' style.font.size = Pt(13) # # настраиваем красную строку абзаца # style.paragraph_format.first_line_indent = Mm(12.5) style.paragraph_format.first_line_indent = Mm(12.5) style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY style.paragraph_format.line_spacing = 1.2 style.paragraph_format.space_after = 0 text = f'Выписка из протокола №{object.extract.number} заседания кафедры\n «{object.extract.department}» от {rus_month(object.extract.date)}' p = document.add_paragraph(text) p.paragraph_format.first_line_indent = Mm(0) p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER document.add_paragraph('СЛУШАЛИ:') document.add_paragraph( 'Доцента кафедры ТМТМО, кандидата технических наук Мирного Сергея Георгиевича о рассмотрении' ' тем выпускных квалификационных работ слушателям по дополнительному профессиональному ' 'образованию по направлению профессиональной переподготовки «Машины и оборудование нефтяных и ' 'газовых промыслов»') document.add_paragraph('ПОСТАНОВИЛИ:') document.add_paragraph('Ходатайствовать об утверждении тем выпускных квалификационных работ слушателям ' 'по дополнительному профессиональному образованию по направлению ' 'профессиональной переподготовки «Машины и оборудование нефтяных и ' 'газовых промыслов»:') for number, item in enumerate(contracts): p = document.add_paragraph(f'{number+1}. {item.client.surname} {item.client.name} {item.client.patronymic}') p.paragraph_format.keep_with_next = True p = document.add_paragraph(f'{item.degree_work.title}. Руководитель: {item.degree_work.adviser.surname} {item.degree_work.adviser.name} {item.degree_work.adviser.patronymic} - ') if item.degree_work.adviser.degree: p.add_run(f'{str(item.degree_work.adviser.degree).lower()}, ') p.add_run(f'{str(item.degree_work.adviser.post).lower()} кафедры «{object.extract.department}».') document.add_paragraph() p = document.add_paragraph(f'Доцент кафедры «ТМТМО», \nкандидат технических наук, доцент \t\t\t\t' f'________________ {object.extract.speaker.name[:1]}. {object.extract.speaker.patronymic[:1]}. {object.extract.speaker.surname}') p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT p.paragraph_format.first_line_indent = Mm(0) p = document.add_paragraph(f'Секретарь \t\t\t\t\t\t\t\t' f'________________ {object.extract.secretary.name[:1]}. {object.extract.secretary.patronymic[:1]}. {object.extract.secretary.surname}') p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT p.paragraph_format.first_line_indent = Mm(0) p.paragraph_format.space_before = Pt(10) document.save(buf) buf.seek(0) return buf def protocol_by_order(order_id): '''Генерация протоколов защиты по айди приказа ''' contracts = Orders.objects.get(pk=order_id).contracts.all().order_by('degree_work__protocol__number') buf = io.BytesIO() last = len(contracts) - 1 for n, item in enumerate(contracts): doc2 = Document(protocol_by_id(item.id)) if n != last: doc2.add_page_break() if n == 0: composer = Composer(doc2) else: composer.append(doc2) composer.save(buf) buf.seek(0) return buf def memo_by_order(acces_id): '''Генерация служебки на пропуска по айди ''' acces = Access_lists.objects.get(pk=acces_id) contracts = Contracts.objects.filter(access_lists__pk = acces_id).order_by('client__surname', 'client__name', 'group__graduation_date', ) buf = io.BytesIO() filename = acces.template.file tpl = DocxTemplate(filename) date = acces.registration_date number = acces.number context = { 'contracts': contracts, 'date': date, 'number': number, } tpl.render(context, jinja_env) tpl.save(buf) buf.seek(0) return buf def protocol_by_id(contract_id): '''Генерация протокола защиты ВКР по айди договора ''' contract = Contracts.objects.get(pk=contract_id) questions = Protocols.objects.get(pk=contract.degree_work.protocol.pk).questions.all() buf = io.BytesIO() filename = contract.degree_work.protocol.template.file tpl = DocxTemplate(filename) dt = contract.degree_work.protocol.date_time dte = dt + timedelta(minutes=25) date_time = f'{rus_month(dt)}г. c {dt:%H} час. {dt:%M} мин. до {dte:%H} час. {dte:%M} мин.' context = { 'contract': contract, 'title': contract.degree_work.title, 'date_time': date_time, 'questions': questions, 'fio_genitive': f'{contract.client.surname_cases.genitive} {contract.client.name_cases.genitive} {contract.client.patronymic_cases.genitive}', 'fio_dative': f'{contract.client.surname_cases.dative} {contract.client.name_cases.dative[:1]}. {contract.client.patronymic_cases.dative[:1]}.' } tpl.render(context) tpl.save(buf) buf.seek(0) return buf def filefor_registry(order_id): '''генерация файла с данными для внесения в базу по дипломам''' order = Orders.objects.get(pk=order_id) contracts = Orders.objects.get(pk=order_id).contracts.all().order_by('client') filename = os.path.join(settings.MEDIA_ROOT, 'templates\for_registry1.xlsx' ) wb = Workbook() buf = io.BytesIO() ws = wb.active # ws.append(['Фамилия', 'Имя', 'Отчество', 'Дата рождения', 'СНИЛС', 'Диплом серия/номер', 'Начало обучения', 'Конец обучения']) string_stub = '' for item in contracts: print(item.client.diploma) ws.append([ 'Диплом о профессиональной переподготовке', 'Оригинал', 'Нет', 'Нет', 'Нет', 'Нет', '', f'{item.end_date:%d.%m.%Y}', # '05/07/2024', '', 'Профессиональная переподготовка', 'Машины и оборудование нефтяных и газовых промыслов', 'Добыча, переработка, транспортировка нефти и газа', 'Бурение скважин, добыча нефти и газа', 'Образование', 'Высшее образование', item.client.surname, f'{item.client.diploma.series if item.client.diploma else string_stub}', f'{item.client.diploma.number if item.client.diploma else string_stub}', f'{item.start_date:%Y}', f'{item.end_date:%Y}', '521', item.client.surname, item.client.name, item.client.patronymic, f'{item.client.birthdate:%d.%m.%Y}', f'{"Муж" if item.client.gender=="муж." else "Жен"}', item.client.snils, 'Заочная', 'Платное обучение', 'в образовательной организации', '643', # f'{item.start_date:%d.%m.%Y}', # f'{item.end_date:%d.%m.%Y}', ]) wb.save(buf) buf.seek(0) return buf def gen_diploma(contract, form:bool): buf = io.BytesIO() document_name = 'templates\diploma_form.docx' if form else 'templates\diploma_supplement.docx' filename = os.path.join(settings.MEDIA_ROOT, document_name) tpl = DocxTemplate(filename) context = { 'surname': contract.client.surname, 'name': contract.client.name, 'patronymic': contract.client.patronymic, 'diploma_number': contract.degree_work.diploma_number, 'registration_number': contract.degree_work.registration_number, 'start_date': rus_month(contract.start_date), 'end_date': rus_month(contract.end_date), 'protocol_date': f'{contract.degree_work.protocol.date_time:%d.%m.%Y}', 'protocol_number': contract.degree_work.protocol.number, } tpl.render(context) tpl.save(buf) buf.seek(0) return buf