Browse Source

Merge branch 'stable/2.2' of https://github.com/interlegis/sigi into new_sigi

new_sigi^2
Lude Ribeiro 3 years ago
parent
commit
0722046345
  1. 1
      requirements/requirements.txt
  2. 27
      sigi/apps/eventos/admin.py
  3. 32
      sigi/apps/eventos/forms.py
  4. 30
      sigi/apps/eventos/migrations/0013_modelodeclaracao.py
  5. 43
      sigi/apps/eventos/models.py
  6. 10
      sigi/apps/eventos/templates/admin/eventos/evento/change_form.html
  7. 0
      sigi/apps/eventos/templates/admin/eventos/evento/change_list.html
  8. 24
      sigi/apps/eventos/templates/eventos/declaracao_pdf.html
  9. 25
      sigi/apps/eventos/templates/eventos/seleciona_modelo.html
  10. 3
      sigi/apps/eventos/urls.py
  11. 54
      sigi/apps/eventos/views.py
  12. 2
      sigi/apps/home/templatetags/menu_conf.yaml
  13. 10
      sigi/settings/base.py
  14. 14
      sigi/shortcuts.py
  15. 1
      sigi/urls.py
  16. 14
      templates/base_report.html

1
requirements/requirements.txt

@ -21,3 +21,4 @@ requests==2.8.1
six==1.10.0
djangorestframework==2.4.8
django-ipware==1.1.6
django-tinymce==2.6.0

27
sigi/apps/eventos/admin.py

@ -23,28 +23,9 @@ from django.contrib import admin
from django.db import models
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _
from sigi.apps.eventos.models import Modulo, TipoEvento, Funcao, Evento, Equipe, Convite
from sigi.apps.eventos.models import ModeloDeclaracao, Modulo, TipoEvento, Funcao, Evento, Equipe, Convite
from sigi.apps.eventos.views import adicionar_eventos_carrinho
class EventoAdminForm(forms.ModelForm):
class Meta:
model = Evento
fields = ('tipo_evento', 'nome', 'descricao', 'virtual', 'solicitante',
'data_inicio', 'data_termino', 'carga_horaria',
'casa_anfitria', 'municipio', 'local', 'publico_alvo',
'total_participantes', 'status', 'data_cancelamento',
'motivo_cancelamento', )
def clean(self):
cleaned_data = super(EventoAdminForm, self).clean()
data_inicio = cleaned_data.get("data_inicio")
data_termino = cleaned_data.get("data_termino")
if data_inicio > data_termino:
raise forms.ValidationError(
_(u"Data término deve ser posterior à data inicio"),
code="invalid_period"
)
from sigi.apps.eventos.forms import EventoAdminForm
@admin.register(TipoEvento)
class TipoEventAdmin(admin.ModelAdmin):
@ -55,6 +36,10 @@ class FuncaoAdmin(admin.ModelAdmin):
list_display = ('nome', 'descricao',)
search_fields = ('nome', 'descricao',)
@admin.register(ModeloDeclaracao)
class ModeloDeclaracaoAdmin(admin.ModelAdmin):
list_display = ('nome', 'formato')
class EquipeInline(admin.TabularInline):
model = Equipe

32
sigi/apps/eventos/forms.py

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from django import forms
from django.utils.translation import ugettext as _
from sigi.apps.eventos.models import ModeloDeclaracao, Evento
class EventoAdminForm(forms.ModelForm):
class Meta:
model = Evento
fields = ('tipo_evento', 'nome', 'descricao', 'virtual', 'solicitante',
'data_inicio', 'data_termino', 'carga_horaria',
'casa_anfitria', 'municipio', 'local', 'publico_alvo',
'total_participantes', 'status', 'data_cancelamento',
'motivo_cancelamento', )
def clean(self):
cleaned_data = super(EventoAdminForm, self).clean()
data_inicio = cleaned_data.get("data_inicio")
data_termino = cleaned_data.get("data_termino")
if data_inicio > data_termino:
raise forms.ValidationError(
_(u"Data término deve ser posterior à data inicio"),
code="invalid_period"
)
class SelecionaModeloForm(forms.Form):
modelo = forms.ModelChoiceField(
queryset=ModeloDeclaracao.objects.all(),
required=True,
label=_(u"Modelo de declaração"),
)

30
sigi/apps/eventos/migrations/0013_modelodeclaracao.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
import tinymce.models
class Migration(migrations.Migration):
dependencies = [
('eventos', '0012_auto_20211117_0657'),
]
operations = [
migrations.CreateModel(
name='ModeloDeclaracao',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('nome', models.CharField(max_length=100, verbose_name='Nome do modelo')),
('formato', models.CharField(default=b'A4 portrait', max_length=30, verbose_name='Formato da p\xe1gina', choices=[(b'A4 portrait', 'A4 retrato'), (b'A4 landscape', 'A4 paisagem'), (b'letter portrait', 'Carta retrato'), (b'letter landscape', 'Carta paisagem')])),
('margem', models.PositiveIntegerField(default=4, help_text='Margem da p\xe1gina em cent\xedmetros', verbose_name='Margem')),
('texto', tinymce.models.HTMLField(help_text='Use as seguintes marca\xe7\xf5es:<ul><li>{{ casa }} para o nome da Casa Legislativa / \xf3rg\xe3o</li><li>{{ nome }} para o nome do visitante</li><li>{{ data }} para a data de emiss\xe3o da declara\xe7\xe3o</li><li>{{ evento.data_inicio }} para a data/hora do in\xedcio da visita</li><li>{{ evento.data_termino }} para a data/hora do t\xe9rmino da visita</li><li>{{ evento.nome }} para o nome do evento</li><li>{{ evento.descricao }} para a descri\xe7\xe3o do evento</li></ul>', verbose_name='Texto da declara\xe7\xe3o')),
],
options={
'verbose_name': 'modelo de declara\xe7\xe3o',
'verbose_name_plural': 'modelos de declara\xe7\xe3o',
},
bases=(models.Model,),
),
]

43
sigi/apps/eventos/models.py

@ -10,6 +10,7 @@ from sigi.apps.casas.models import Orgao
from sigi.apps.contatos.models import Municipio
from sigi.apps.servidores.models import Servidor
from django.core.exceptions import ValidationError
from tinymce.models import HTMLField
class TipoEvento(models.Model):
CATEGORIA_CHOICES = (
@ -239,3 +240,45 @@ class Modulo(models.Model):
nome=self.nome,
tipo=self.get_tipo_display()
)
class ModeloDeclaracao(models.Model):
FORMATO_CHOICES = (
('A4 portrait', _(u"A4 retrato")),
('A4 landscape', _(u"A4 paisagem")),
('letter portrait', _(u"Carta retrato")),
('letter landscape', _(u"Carta paisagem"))
)
nome = models.CharField(_(u"Nome do modelo"), max_length=100)
formato = models.CharField(
_(u"Formato da página"),
max_length=30,
choices=FORMATO_CHOICES,
default=FORMATO_CHOICES[0][0]
)
margem = models.PositiveIntegerField(
_(u"Margem"),
help_text=_(u"Margem da página em centímetros"),
default=4
)
texto = HTMLField(
_(u"Texto da declaração"),
help_text=_(u"Use as seguintes marcações:<ul><li>{{ casa }} para o "
u"nome da Casa Legislativa / órgão</li><li>{{ nome }} "
u"para o nome do visitante</li><li>{{ data }} para a data "
u"de emissão da declaração</li><li>{{ evento.data_inicio }}"
u" para a data/hora do início da visita</li>"
u"<li>{{ evento.data_termino }} para a data/hora do "
u"término da visita</li><li>{{ evento.nome }} para o nome "
u"do evento</li><li>{{ evento.descricao }} para a descrição"
u" do evento</li></ul>")
)
class Meta:
verbose_name = _(u"modelo de declaração")
verbose_name_plural = _(u"modelos de declaração")
def __unicode__(self):
return _(u"{nome} ({formato})").format(
nome=self.nome,
formato=self.get_formato_display()
)

10
sigi/apps/eventos/templates/admin/eventos/evento/change_form.html

@ -0,0 +1,10 @@
{% extends "base_change_form.html" %}
{% load i18n %}
{% block object-tools-items %}
<li><a href="declaracao/">
<span class="glyphicon glyphicon-print"></span>
{% trans 'Declaração' %}
</a></li>
{{ block.super }}
{% endblock %}

0
sigi/apps/eventos/templates/admin/eventos/change_list.html → sigi/apps/eventos/templates/admin/eventos/evento/change_list.html

24
sigi/apps/eventos/templates/eventos/declaracao_pdf.html

@ -0,0 +1,24 @@
{% extends 'base_report.html' %}
{% load i18n %}
{% block pagesize %}{{ pagesize }}{% endblock pagesize %}
{% block pagemargin %}4cm {{ pagemargin }}cm {{ pagemargin }}cm 2cm{% endblock pagemargin %}
{% block report %}
{% for convite in evento.convite_set.all %}
{% with convite.casa.nome as casa %}
{% for nome in convite.nomes_participantes.splitlines %}
{% block text_body %}{% endblock %}
<pdf:nextpage />
{% endfor %}
{% endwith %}
{% endfor %}
{% endblock %}
{%block page_foot%}
<table>
<tr>
<td class="footer-left">{% trans 'Emissão:' %} {% now "d/m/Y H:i:s" %}</td>
</tr>
</table>
{% endblock %}

25
sigi/apps/eventos/templates/eventos/seleciona_modelo.html

@ -0,0 +1,25 @@
{% extends "admin/base_site.html" %}
{% load i18n bootstrap3 %}
{% block content_title %}
<h1 class="pull-left">{% trans 'Emitir declaração de comparecimento' %}</h1>
{% endblock %}
{% block content %}
{% if error %}
<div class="alert alert-danger" role="alert">
{{ error }}
</div>
{% endif %}
<div id="content-main">
<form action="" method="post">{% csrf_token %}
{% csrf_token %}
<div class="form-group">
{% bootstrap_form form %}
</div>
<input type="submit" value="Imprimir" class="btn btn-primary"/>
<a class="btn btn-danger" role="button" href="{% url 'admin:eventos_evento_change' evento_id %}">{% trans "Voltar" %}</a>
</form>
</div>
{% endblock %}

3
sigi/apps/eventos/urls.py

@ -15,5 +15,8 @@ urlpatterns = patterns(
url(r'^evento/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho',
name='deleta-itens-carrinho-evento'), # Error
url(r'^evento/csv/$', 'export_csv', name='evento-export-csv'), # Error
url(r'^evento/(?P<id>\w+)/declaracao/$', 'declaracao',
name='evento-declaracao'),
)

54
sigi/apps/eventos/views.py

@ -21,18 +21,21 @@
import calendar
import datetime
import locale
import csv
from django import template
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from django.shortcuts import get_object_or_404, render
from django.utils import translation
from django.utils.translation import ungettext, ugettext as _
from django.http.response import JsonResponse, HttpResponse
from django.template import Template, Context
from sigi.apps.eventos.models import Evento, Equipe, Convite
from sigi.apps.eventos.forms import SelecionaModeloForm
from sigi.apps.servidores.models import Servidor
from sigi.shortcuts import render_to_pdf
import csv
from django.http.response import JsonResponse, HttpResponse
from sigi.shortcuts import render_to_pdf, pdf_renderer
@login_required
def calendario(request):
@ -84,10 +87,10 @@ def calendario(request):
for linha in linhas:
sobrepoe = False
for e in linha:
if (((evento['evento'].data_inicio >= e['evento'].data_inicio) and
(evento['evento'].data_inicio <= e['evento'].data_termino)) or
((evento['evento'].data_termino >= e['evento'].data_inicio) and
(evento['evento'].data_termino <= e['evento'].data_termino))):
if (((evento['evento'].data_inicio.date() >= e['evento'].data_inicio.date()) and
(evento['evento'].data_inicio.date() <= e['evento'].data_termino.date())) or
((evento['evento'].data_termino.date() >= e['evento'].data_inicio.date()) and
(evento['evento'].data_termino.date() <= e['evento'].data_termino.date()))):
sobrepoe = True
break
if not sobrepoe:
@ -106,7 +109,7 @@ def calendario(request):
if anterior is None:
anterior = evento
continue
anterior['close'] = (evento['evento'].data_inicio - anterior['evento'].data_termino).days-1
anterior['close'] = (evento['evento'].data_inicio.date() - anterior['evento'].data_termino.date()).days-1
evento['start'] = 0
anterior = evento
@ -376,3 +379,36 @@ def export_csv(request):
return response
@login_required
def declaracao(request, id):
if request.method == 'POST':
form = SelecionaModeloForm(request.POST)
if form.is_valid():
evento = get_object_or_404(Evento, id=id)
modelo = form.cleaned_data['modelo']
template_string = (
"""
{% extends "eventos/declaracao_pdf.html" %}
{% block text_body %}""" +
modelo.texto + """
{% endblock %}
"""
)
context = Context(
{'pagesize': modelo.formato,
'pagemargin': modelo.margem,
'evento': evento,
'data': datetime.date.today(),
}
)
template = Template(template_string)
# return HttpResponse(template.render(context))
return pdf_renderer(template, context, 'declaracao.pdf')
else:
form = SelecionaModeloForm()
return render(
request,
'eventos/seleciona_modelo.html',
{'form': form, 'evento_id': id}
)

2
sigi/apps/home/templatetags/menu_conf.yaml

@ -85,6 +85,8 @@ main_menu:
url: eventos/tipoevento/
- title: Funções na equipe de eventos
url: eventos/funcao/
- title: Modelos de declaração
url: eventos/modelodeclaracao/
# Removidos

10
sigi/settings/base.py

@ -74,7 +74,7 @@ INSTALLED_APPS = (
'easy_thumbnails',
'image_cropping',
'rest_framework',
'tinymce',
)
MIDDLEWARE_CLASSES = (
@ -188,3 +188,11 @@ REST_FRAMEWORK = {
WHOIS_WHITELIST = [
'127.0.0.1',
]
# TinyMCE configuration
TINYMCE_SPELLCHECKER = True
TINYMCE_COMPRESSOR = True
TINYMCE_DEFAULT_CONFIG = {
'theme': "advanced",
"height": 500,
}

14
sigi/shortcuts.py

@ -24,12 +24,7 @@ def fetch_resources(uri, rel):
uri.replace(settings.MEDIA_URL, ""))
return path
def render_to_pdf(template_src, context_dict):
filename = template_src.replace('.html', '').replace('_pdf', '.pdf')
template = get_template(template_src)
context = Context(context_dict)
def pdf_renderer(template, context, filename='report.pdf'):
html = template.render(context)
response = HttpResponse(content_type='application/pdf')
@ -41,3 +36,10 @@ def render_to_pdf(template_src, context_dict):
if pdf.err:
return HttpResponse(_(u'We had some errors<pre>%s</pre>') % escape(html))
return response
def render_to_pdf(template_src, context_dict):
filename = template_src.replace('.html', '').replace('_pdf', '.pdf')
template = get_template(template_src)
context = Context(context_dict)
return pdf_renderer(template, context,filename)

1
sigi/urls.py

@ -20,6 +20,7 @@ urlpatterns = patterns(
url(r'^ocorrencias/', include('sigi.apps.ocorrencias.urls')),
url(r'^eventos/', include('sigi.apps.eventos.urls')),
url(r'^whois/', include('sigi.apps.whois.urls')),
url(r'^tinymce/', include('tinymce.urls')),
url(r'^', include('sigi.apps.home.urls')),
url(r'^', include(admin.site.urls)),

14
templates/base_report.html

@ -11,11 +11,9 @@
text-align: center;
}
td.header_text p {
margin: 0px;
font-size: 1.4em;
}
td.header_text {
width: 550px;
margin: 5px;
font-size: 1.2em;
text-align: center;
}
h1 {
font-size: 2em;
@ -58,12 +56,12 @@
}
@page {
size: {% block pagesize %}{{ pagesize }}{% endblock pagesize %};
margin: 4cm 1cm 1cm 2cm;
margin: {% block pagemargin %}4cm 1cm 1cm 2cm{% endblock pagemargin %};
font-family: "Helvetica, Arial, sans-serif";
font-size: 2em;
@frame header {
-pdf-frame-content: header;
top: 1cm;
{% block header-settings %}top: 1cm;{% endblock header-settings %}
}
@frame footer {
-pdf-frame-content: footer;
@ -84,7 +82,7 @@
<td class="logo"><img src="{% static 'img/logo-senado.jpg' %}" /></td>
<td class="header_text">
<p><strong>{% trans 'SENADO FEDERAL' %}</strong></p>
<p><strong>{% trans 'ILB - PROGRAMA INTERLEGIS' %}</strong></p>
<p><strong>{% trans 'INSTITUTO LEGISLATIVO BRASILEIRO - ILB / INTERLEGIS' %}</strong></p>
<p>{% block subsecretaria %}{% endblock %}</p>
</td>
<td class="logo"><img src="{% static 'img/logo-interlegis.jpg' %}" /></td>

Loading…
Cancel
Save