Files
test/retraining/main/gen_doc.py

485 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.

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