Browse Source

Gerador de minuta em DOCx

pull/159/head
Sesostris Vieira 3 years ago
parent
commit
69a058913c
  1. 23
      sigi/apps/convenios/migrations/0022_remove_projeto_texto_minuta_projeto_modelo_minuta.py
  2. 11
      sigi/apps/convenios/models.py
  3. 2
      sigi/apps/eventos/admin.py
  4. 19
      sigi/apps/eventos/migrations/0020_anexo_convite.py
  5. 3
      sigi/apps/eventos/models.py
  6. 2
      sigi/apps/eventos/templates/eventos/convida_casa.html
  7. 18
      sigi/apps/eventos/templates/eventos/evento.html
  8. 77
      sigi/apps/eventos/templates/eventos/minuta_pdf.html
  9. 45
      sigi/apps/eventos/views.py

23
sigi/apps/convenios/migrations/0022_remove_projeto_texto_minuta_projeto_modelo_minuta.py

@ -0,0 +1,23 @@
# Generated by Django 4.0.4 on 2022-05-05 13:17
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('convenios', '0021_projeto_texto_minuta_projeto_texto_oficio'),
]
operations = [
migrations.RemoveField(
model_name='projeto',
name='texto_minuta',
),
migrations.AddField(
model_name='projeto',
name='modelo_minuta',
field=models.FileField(blank=True, help_text='Use as seguintes marcações:<ul><li>{{ casa.nome }} para o nome da Casa Legislativa / órgão</li><li>{{ casa.municipio.uf.sigla }} para a sigla da UF da Casa legislativa</li><li>{{ presidente.nome }} para o nome do presidente</li><li>{{ contato.nome }} para o nome do contato Interlegis</li></ul>', upload_to='convenios/minutas/', validators=[django.core.validators.FileExtensionValidator], verbose_name='Modelo de minuta'),
),
]

11
sigi/apps/convenios/models.py

@ -4,6 +4,7 @@ from datetime import datetime, date
from django.db import models
from django.db.models import Q, fields
from django.core.mail import send_mail
from django.core.validators import FileExtensionValidator
from django.urls import reverse
from django.utils.formats import date_format
from django.utils.translation import gettext as _
@ -27,8 +28,14 @@ class Projeto(models.Model):
texto_oficio = HTMLField(
_("texto do ofício"), blank=True, help_text=MARKUP_HELP
)
texto_minuta = HTMLField(
_("texto da minuta"), blank=True, help_text=MARKUP_HELP
modelo_minuta = models.FileField(
_("Modelo de minuta"),
blank=True,
help_text=MARKUP_HELP,
upload_to="convenios/minutas/",
validators=[
FileExtensionValidator,
],
)
def __str__(self):

2
sigi/apps/eventos/admin.py

@ -122,7 +122,7 @@ class ModuloInline(admin.StackedInline):
class AnexoInline(admin.StackedInline):
model = Anexo
exclude = ("data_pub",)
exclude = ("data_pub", "convite")
@admin.register(Evento)

19
sigi/apps/eventos/migrations/0020_anexo_convite.py

@ -0,0 +1,19 @@
# Generated by Django 4.0.4 on 2022-05-05 14:35
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('eventos', '0019_alter_evento_status'),
]
operations = [
migrations.AddField(
model_name='anexo',
name='convite',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='eventos.convite'),
),
]

3
sigi/apps/eventos/models.py

@ -319,6 +319,9 @@ class Anexo(models.Model):
data_pub = models.DateTimeField(
_("data da publicação do anexo"), default=datetime.now
)
convite = models.ForeignKey(
Convite, blank=True, null=True, on_delete=models.SET_NULL
)
class Meta:
ordering = ("-data_pub",)

2
sigi/apps/eventos/templates/eventos/convida_casa.html

@ -69,7 +69,7 @@
</button>
{% for proj in projetos %}
<button class="btn waves-effect waves-light" type="submit" name="save" value="{{ proj.id }}">
{% blocktrans with sigla=proj.sigla %}Gerar minuta de {{ sigla}}{% endblocktrans %}
{% blocktrans with sigla=proj.sigla %}Salvar e gerar minuta de {{ sigla}}{% endblocktrans %}
<i class="material-icons right">picture_as_pdf</i>
</button>
{% endfor %}

18
sigi/apps/eventos/templates/eventos/evento.html

@ -96,7 +96,15 @@
{% for convite in evento.convite_set.all %}
<tr>
{% for field_name in convite_fields %}
<td>{{ convite|field_value:field_name }}</td>
<td>
{% if forloop.first %}
<a href="{% url 'eventos-evento-convida' evento.id convite.casa_id %}">
{{ convite|field_value:field_name }}
</a>
{% else %}
{{ convite|field_value:field_name }}
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
@ -135,7 +143,13 @@
<td>{{ anexo.data_pub|date:"SHORT_DATE_FORMAT" }}</td>
<td>
<a href="{{ anexo.arquivo.url }}" target="_blank">
<i class="material-icons">picture_as_pdf</i>
<i class="material-icons">
{% if 'pdf' in anexo.arquivo.path %}
picture_as_pdf
{% else %}
file_download
{% endif %}
</i>
</a>
</td>
</tr>

77
sigi/apps/eventos/templates/eventos/minuta_pdf.html

@ -1,77 +0,0 @@
{% extends 'pdf/base_report.html' %}
{% load i18n static %}
{% block page_margin %}4cm 2cm{% endblock page_margin %}
{% block page-header-settings %}
@top-center { content: element(header);}
{% endblock %}
{% block page-footer-settings %}
@bottom-center { content: element(footer); }
{% endblock %}
{% block extra_style %}
h1 {font-size: 1.2em;}
h2 {font-size: 1.1em;}
h3,h4,h5,h6 {font-size: 1em;}
header {
font-size: 1em;
text-align: center;
}
header p {
margin: 0 0 5px 0;
}
.strong {
font-weight: bold;
}
.header-title {
font-weight: bold;
font-size: 1.2em;
}
.header-subtitle {
font-weight: bold;
font-size: 1em;
}
.content {
font-size: 1.2em;
line-height: 1.4em;
padding-bottom: 5px;
}
footer {
width: 100%;
text-align: center;
}
.barra {
height: 15px;
}
{% endblock %}
{% block header %}
<img src="{% static 'img/logo-senado.png' %}">
<p class="header-title">SENADO FEDERAL</p>
<p class="header-subtitle">Instituto Legislativo Brasileiro - ILB</p>
<p class="header-subtitle">Programa Interlegis</p>
{% endblock %}
{% block main_content %}
<div class="content">
{% block text_body %}{% endblock %}
</div>
{% endblock %}
{% block footer %}
<img class="barra" src="{% static 'img/brasil-barra.jpg' %}"/>
<p>Instituto Legislativo Brasileiro - ILB - Av. N2 - Bloco 12 - CEP 70165-900 – Brasília DF</p>
<p>Telefone: +55 (61) 3303-2599 – interlegis@senado.leg.br – www.interlegis.leg.br</p>
<p class="strong">MINUTA-PADRÃO aprovada pela Diretoria-Geral do Senado Federal em 01/setembro/2021, conforme processo 00200.006818/2021-12.</p>
{% endblock %}

45
sigi/apps/eventos/views.py

@ -7,10 +7,12 @@ from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import redirect, render, get_object_or_404
from django.template import Template, Context
from django.template.exceptions import TemplateSyntaxError
from django.utils.text import slugify
from django.utils.translation import to_locale, get_language, gettext as _
from django.urls import reverse
from django_weasyprint.utils import django_url_fetcher
from docx import Document
from weasyprint import HTML
from sigi.apps.casas.models import Funcionario, Orgao, Presidente
from sigi.apps.convenios.models import Projeto
@ -102,7 +104,7 @@ def convida_casa(request, evento_id, casa_id):
evento = get_object_or_404(Evento, id=evento_id)
casa = get_object_or_404(Orgao, id=casa_id)
projetos = Projeto.objects.exclude(texto_minuta="")
projetos = Projeto.objects.exclude(modelo_minuta="")
if evento.convite_set.filter(casa=casa).exists():
convite = evento.convite_set.get(casa=casa)
@ -147,6 +149,7 @@ def convida_casa(request, evento_id, casa_id):
proj_id = request.POST.get("save", "")
if proj_id:
convite.anexo_set.all().delete()
query_str = ""
projeto = get_object_or_404(Projeto, id=proj_id)
if projeto.texto_oficio:
@ -162,17 +165,37 @@ def convida_casa(request, evento_id, casa_id):
oficio.evento = evento
oficio.save()
query_str += f"anexo_id={oficio.id}&"
if projeto.texto_minuta:
minuta = gerar_anexo(
casa,
presidente,
contato,
path=request.build_absolute_uri("/"),
nome=f"Minuta de {projeto.sigla}",
modelo="minuta_pdf.html",
texto=projeto.texto_minuta,
if projeto.modelo_minuta:
doc = Document(projeto.modelo_minuta.path)
doc_context = Context(
{
"evento": evento,
"casa": casa,
"presidente": presidente,
"contato": contato,
"data": datetime.date.today(),
"doravante": casa.tipo.nome.split(" ")[0],
}
)
minuta.evento = evento
for paragrafo in doc.paragraphs:
run_final = None
for run in paragrafo.runs:
if run_final is None:
run_final = run
else:
run_final.text += run.text
run.text = ""
try:
run_final.text = Template(
run_final.text
).render(doc_context)
run_final = None
except TemplateSyntaxError:
pass
nome = f"Minuta de {projeto.sigla} da {casa.nome}"[:70]
minuta = Anexo(descricao=nome, evento=evento)
minuta.arquivo.name = slugify(nome) + ".docx"
doc.save(minuta.arquivo.path)
minuta.save()
query_str += f"anexo_id={minuta.id}"

Loading…
Cancel
Save