diff --git a/requirements/requirements.txt b/requirements/requirements.txt
index abfd1d4..ab6351f 100644
--- a/requirements/requirements.txt
+++ b/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
\ No newline at end of file
diff --git a/sigi/apps/eventos/admin.py b/sigi/apps/eventos/admin.py
index 63ded3e..048ce57 100644
--- a/sigi/apps/eventos/admin.py
+++ b/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
diff --git a/sigi/apps/eventos/forms.py b/sigi/apps/eventos/forms.py
new file mode 100644
index 0000000..7ec8869
--- /dev/null
+++ b/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"),
+ )
\ No newline at end of file
diff --git a/sigi/apps/eventos/migrations/0013_modelodeclaracao.py b/sigi/apps/eventos/migrations/0013_modelodeclaracao.py
new file mode 100644
index 0000000..a8d9e4b
--- /dev/null
+++ b/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:
- {{ casa }} para o nome da Casa Legislativa / \xf3rg\xe3o
- {{ nome }} para o nome do visitante
- {{ data }} para a data de emiss\xe3o da declara\xe7\xe3o
- {{ evento.data_inicio }} para a data/hora do in\xedcio da visita
- {{ evento.data_termino }} para a data/hora do t\xe9rmino da visita
- {{ evento.nome }} para o nome do evento
- {{ evento.descricao }} para a descri\xe7\xe3o do evento
', 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,),
+ ),
+ ]
diff --git a/sigi/apps/eventos/models.py b/sigi/apps/eventos/models.py
index f9acacd..9a11315 100644
--- a/sigi/apps/eventos/models.py
+++ b/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:- {{ casa }} para o "
+ u"nome da Casa Legislativa / órgão
- {{ nome }} "
+ u"para o nome do visitante
- {{ data }} para a data "
+ u"de emissão da declaração
- {{ evento.data_inicio }}"
+ u" para a data/hora do início da visita
"
+ u"- {{ evento.data_termino }} para a data/hora do "
+ u"término da visita
- {{ evento.nome }} para o nome "
+ u"do evento
- {{ evento.descricao }} para a descrição"
+ u" do evento
")
+ )
+
+ 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()
+ )
diff --git a/sigi/apps/eventos/templates/admin/eventos/evento/change_form.html b/sigi/apps/eventos/templates/admin/eventos/evento/change_form.html
new file mode 100644
index 0000000..5dc8236
--- /dev/null
+++ b/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 %}
+
+
+ {% trans 'Declaração' %}
+
+ {{ block.super }}
+{% endblock %}
diff --git a/sigi/apps/eventos/templates/admin/eventos/change_list.html b/sigi/apps/eventos/templates/admin/eventos/evento/change_list.html
similarity index 100%
rename from sigi/apps/eventos/templates/admin/eventos/change_list.html
rename to sigi/apps/eventos/templates/admin/eventos/evento/change_list.html
diff --git a/sigi/apps/eventos/templates/eventos/declaracao_pdf.html b/sigi/apps/eventos/templates/eventos/declaracao_pdf.html
new file mode 100644
index 0000000..ec00d5d
--- /dev/null
+++ b/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 %}
+
+ {% endfor %}
+ {% endwith %}
+ {% endfor %}
+{% endblock %}
+
+{%block page_foot%}
+
+{% endblock %}
diff --git a/sigi/apps/eventos/templates/eventos/seleciona_modelo.html b/sigi/apps/eventos/templates/eventos/seleciona_modelo.html
new file mode 100644
index 0000000..c3180f0
--- /dev/null
+++ b/sigi/apps/eventos/templates/eventos/seleciona_modelo.html
@@ -0,0 +1,25 @@
+{% extends "admin/base_site.html" %}
+{% load i18n bootstrap3 %}
+
+{% block content_title %}
+{% trans 'Emitir declaração de comparecimento' %}
+{% endblock %}
+
+{% block content %}
+{% if error %}
+
+ {{ error }}
+
+{% endif %}
+
+{% endblock %}
+
diff --git a/sigi/apps/eventos/urls.py b/sigi/apps/eventos/urls.py
index 05af590..2d0a8f3 100644
--- a/sigi/apps/eventos/urls.py
+++ b/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\w+)/declaracao/$', 'declaracao',
+ name='evento-declaracao'),
+
)
diff --git a/sigi/apps/eventos/views.py b/sigi/apps/eventos/views.py
index 379e7c2..7697b86 100644
--- a/sigi/apps/eventos/views.py
+++ b/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}
+ )
\ No newline at end of file
diff --git a/sigi/apps/home/templatetags/menu_conf.yaml b/sigi/apps/home/templatetags/menu_conf.yaml
index 4d3f9f0..a230afd 100644
--- a/sigi/apps/home/templatetags/menu_conf.yaml
+++ b/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
diff --git a/sigi/settings/base.py b/sigi/settings/base.py
index e123cbc..cd57c67 100644
--- a/sigi/settings/base.py
+++ b/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,
+}
\ No newline at end of file
diff --git a/sigi/shortcuts.py b/sigi/shortcuts.py
index d27986c..4f31978 100644
--- a/sigi/shortcuts.py
+++ b/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%s
') % 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)
\ No newline at end of file
diff --git a/sigi/urls.py b/sigi/urls.py
index 7998344..d269737 100644
--- a/sigi/urls.py
+++ b/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)),
diff --git a/templates/base_report.html b/templates/base_report.html
index c5cc6e5..96e4495 100644
--- a/templates/base_report.html
+++ b/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 @@
|
|