diff --git a/compilacao/forms.py b/compilacao/forms.py index e765b28d2..f5ae76626 100644 --- a/compilacao/forms.py +++ b/compilacao/forms.py @@ -10,7 +10,8 @@ from django.utils.translation import ugettext_lazy as _ from compilacao.models import (PARTICIPACAO_SOCIAL_CHOICES, Dispositivo, Nota, TextoArticulado, TipoNota, TipoTextoArticulado, - TipoVide, Vide) + TipoVide, Vide, TipoPublicacao, + VeiculoPublicacao, Publicacao) from compilacao.utils import YES_NO_CHOICES, FormLayout, to_column, to_row @@ -19,7 +20,7 @@ class UpLoadImportFileForm(forms.Form): required=True, label=_('Arquivo formato ODF para Importanção')) -nota_error_messages = { +error_messages = { 'required': _('Este campo é obrigatório'), 'invalid': _('URL inválida.') } @@ -30,11 +31,16 @@ ta_error_messages = { class TipoTaForm(ModelForm): - sigla = forms.CharField(label='Sigla') - descricao = forms.CharField(label='Descrição') + sigla = forms.CharField( + label=TipoTextoArticulado._meta.get_field( + 'sigla').verbose_name) + descricao = forms.CharField( + label=TipoTextoArticulado._meta.get_field( + 'descricao').verbose_name) participacao_social = forms.NullBooleanField( - label=_('Participação Social'), + label=TipoTextoArticulado._meta.get_field( + 'participacao_social').verbose_name, widget=forms.Select(choices=YES_NO_CHOICES), required=True) @@ -64,15 +70,22 @@ class TipoTaForm(ModelForm): class TaForm(ModelForm): tipo_ta = forms.ModelChoiceField( - label=_('Tipo do Texto Articulado'), + label=TipoTextoArticulado._meta.verbose_name, queryset=TipoTextoArticulado.objects.all(), required=True, empty_label=None) - numero = forms.IntegerField(label=_('Número'), required=True) - ano = forms.IntegerField(label=_('Ano'), required=True) + numero = forms.IntegerField( + label=TextoArticulado._meta.get_field( + 'numero').verbose_name, + required=True) + ano = forms.IntegerField( + label=TextoArticulado._meta.get_field( + 'ano').verbose_name, + required=True) data = forms.DateField( - label=_('Data'), + label=TextoArticulado._meta.get_field( + 'data').verbose_name, input_formats=['%d/%m/%Y'], required=True, widget=forms.DateInput( @@ -89,7 +102,8 @@ class TaForm(ModelForm): error_messages=ta_error_messages, required=False) participacao_social = forms.NullBooleanField( - label=_('Participação Social'), + label=TextoArticulado._meta.get_field( + 'participacao_social').verbose_name, widget=forms.Select(choices=PARTICIPACAO_SOCIAL_CHOICES), required=False) @@ -117,9 +131,11 @@ class TaForm(ModelForm): self.helper = FormHelper() self.helper.layout = FormLayout( Fieldset(_('Identificação Básica'), row1, css_class="large-12"), - Fieldset(_('Ementa'), Column('ementa'), css_class="large-12"), + Fieldset(TextoArticulado._meta.get_field( + 'ementa').verbose_name, Column('ementa'), css_class="large-12"), Fieldset( - _('Observações'), Column('observacao'), css_class="large-12"), + TextoArticulado._meta.get_field( + 'observacao').verbose_name, Column('observacao'), css_class="large-12"), ) @@ -143,11 +159,11 @@ class NotaForm(ModelForm): texto = forms.CharField( label='', widget=forms.Textarea, - error_messages=nota_error_messages) + error_messages=error_messages) url_externa = forms.URLField( label='', required=False, - error_messages=nota_error_messages) + error_messages=error_messages) publicidade = forms.ChoiceField( required=True, label=_('Publicidade'), @@ -166,7 +182,7 @@ class NotaForm(ModelForm): required=True, widget=forms.DateInput( format='%d/%m/%Y'), - error_messages=nota_error_messages + error_messages=error_messages ) efetividade = forms.DateField( label=_('Efetividade'), @@ -174,7 +190,7 @@ class NotaForm(ModelForm): required=True, widget=forms.DateInput( format='%d/%m/%Y'), - error_messages=nota_error_messages) + error_messages=error_messages) dispositivo = forms.ModelChoiceField(queryset=Dispositivo.objects.all(), widget=forms.HiddenInput()) pk = forms.IntegerField(widget=forms.HiddenInput(), @@ -210,7 +226,7 @@ class NotaForm(ModelForm): ('publicidade', 3), ('publicacao', 3), ('efetividade', 3), - (Button('submit', 'Salvar', + (Button('submit', _('Salvar'), css_class='button primary radius'), 3) ]) @@ -235,7 +251,7 @@ class VideForm(ModelForm): widget=forms.HiddenInput()) tipo_ta = forms.ModelChoiceField( - label='Tipo do Texto Articulado', + label=_('Tipo do Texto Articulado'), queryset=TipoTextoArticulado.objects.all(), required=False) num_ta = forms.IntegerField( @@ -248,10 +264,10 @@ class VideForm(ModelForm): widget=forms.Textarea, required=False) tipo = forms.ModelChoiceField( - label=_('Tipo do Vide'), + label=TipoVide._meta.verbose_name, queryset=TipoVide.objects.all(), required=True, - error_messages=nota_error_messages) + error_messages=error_messages) busca_dispositivo = forms.CharField( label=_('Buscar Dispositivo a Referenciar'), @@ -269,7 +285,7 @@ class VideForm(ModelForm): error_messages = { NON_FIELD_ERRORS: { 'unique_together': - "Ja existe um Vide deste tipo para o Dispositivo Referido ", + _("Ja existe um Vide deste tipo para o Dispositivo Referido "), } } @@ -324,3 +340,86 @@ class VideForm(ModelForm): ) super(VideForm, self).__init__(*args, **kwargs) + + +class PublicacaoForm(ModelForm): + + tipo_publicacao = forms.ModelChoiceField( + label=TipoPublicacao._meta.verbose_name, + queryset=TipoPublicacao.objects.all()) + + veiculo_publicacao = forms.ModelChoiceField( + label=VeiculoPublicacao._meta.verbose_name, + queryset=VeiculoPublicacao.objects.all()) + + url_externa = forms.CharField( + label=Publicacao._meta.get_field('url_externa').verbose_name, + required=False) + + data = forms.DateField( + label=Publicacao._meta.get_field('data').verbose_name, + input_formats=['%d/%m/%Y'], + required=True, + widget=forms.DateInput( + format='%d/%m/%Y'), + error_messages=error_messages + ) + numero = forms.IntegerField( + label=Publicacao._meta.get_field( + 'numero').verbose_name, + required=False) + ano = forms.IntegerField( + label=Publicacao._meta.get_field( + 'ano').verbose_name) + edicao = forms.IntegerField( + label=Publicacao._meta.get_field( + 'edicao').verbose_name, + required=False) + pagina_inicio = forms.IntegerField( + label=Publicacao._meta.get_field( + 'pagina_inicio').verbose_name, + required=False) + pagina_fim = forms.IntegerField( + label=Publicacao._meta.get_field( + 'pagina_fim').verbose_name, + required=False) + ta = forms.ModelChoiceField(queryset=TextoArticulado.objects.all(), + widget=forms.HiddenInput()) + + class Meta: + model = Publicacao + fields = ['tipo_publicacao', + 'veiculo_publicacao', + 'url_externa', + 'data', + 'numero', + 'ano', + 'edicao', + 'pagina_inicio', + 'pagina_fim', + 'ta'] + + def __init__(self, *args, **kwargs): + + row1 = to_row([ + ('tipo_publicacao', 3), + ('data', 3), + ('ano', 2), + ('numero', 2), + ('edicao', 2), + ]) + + row2 = to_row([ + ('veiculo_publicacao', 3), + ('pagina_inicio', 2), + ('pagina_fim', 2), + ('url_externa', 5), + ]) + + self.helper = FormHelper() + self.helper.layout = FormLayout( + Fieldset(Publicacao._meta.verbose_name, + row1, row2, css_class="large-12")) + + super(PublicacaoForm, self).__init__(*args, **kwargs) + pass diff --git a/compilacao/migrations/0041_auto_20160109_1928.py b/compilacao/migrations/0041_auto_20160109_1928.py new file mode 100644 index 000000000..9d854832c --- /dev/null +++ b/compilacao/migrations/0041_auto_20160109_1928.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0040_auto_20160106_1956'), + ] + + operations = [ + migrations.RenameField( + model_name='publicacao', + old_name='publicacao', + new_name='data', + ), + migrations.AddField( + model_name='publicacao', + name='ano', + field=models.PositiveIntegerField(null=True, verbose_name='Pg. Início', blank=True), + ), + migrations.AddField( + model_name='publicacao', + name='edicao', + field=models.PositiveIntegerField(null=True, verbose_name='Pg. Início', blank=True), + ), + migrations.AddField( + model_name='publicacao', + name='numero', + field=models.PositiveIntegerField(null=True, verbose_name='Pg. Início', blank=True), + ), + migrations.AddField( + model_name='publicacao', + name='url_externa', + field=models.CharField(max_length=1024, verbose_name='Link para Versão Eletrônica', blank=True), + ), + ] diff --git a/compilacao/models.py b/compilacao/models.py index be6d0dfdd..0e0c4d6fd 100644 --- a/compilacao/models.py +++ b/compilacao/models.py @@ -443,7 +443,22 @@ class Publicacao(TimestampedMixin): VeiculoPublicacao, verbose_name=_('Veículo de Publicação')) tipo_publicacao = models.ForeignKey( TipoPublicacao, verbose_name=_('Tipo de Publicação')) - publicacao = models.DateTimeField(verbose_name=_('Data de Publicação')) + + data = models.DateTimeField(verbose_name=_('Data de Publicação')) + + numero = models.PositiveIntegerField( + blank=True, null=True, verbose_name=_('Número')) + + ano = models.PositiveIntegerField( + blank=True, null=True, verbose_name=_('Ano')) + + edicao = models.PositiveIntegerField( + blank=True, null=True, verbose_name=_('Edição')) + + url_externa = models.CharField( + max_length=1024, + blank=True, + verbose_name=_('Link para Versão Eletrônica')) pagina_inicio = models.PositiveIntegerField( blank=True, null=True, verbose_name=_('Pg. Início')) pagina_fim = models.PositiveIntegerField( @@ -454,7 +469,10 @@ class Publicacao(TimestampedMixin): verbose_name_plural = _('Publicações') def __str__(self): - return '%s: %s' % (self.veiculo_publicacao, self.publicacao) + return '%s\n%s: %s' % ( + self.ta, + self.tipo_publicacao, + defaultfilters.date(self.data, "d \d\e F \d\e Y")) class Dispositivo(BaseModel, TimestampedMixin): diff --git a/compilacao/urls.py b/compilacao/urls.py index f767469f2..93653f379 100644 --- a/compilacao/urls.py +++ b/compilacao/urls.py @@ -61,6 +61,19 @@ urlpatterns_compilacao = [ views.DispositivoSearchFragmentFormView.as_view(), name='search_dispositivo'), + + url(r'^(?P[0-9]+)/publicacao$', + views.PublicacaoListView.as_view(), name='ta_pub_list'), + url(r'^(?P[0-9]+)/publicacao/create$', + views.PublicacaoCreateView.as_view(), name='ta_pub_create'), + url(r'^(?P[0-9]+)/publicacao/(?P[0-9]+)$', + views.PublicacaoDetailView.as_view(), name='ta_pub_detail'), + url(r'^(?P[0-9]+)/publicacao/(?P[0-9]+)/edit$', + views.PublicacaoUpdateView.as_view(), name='ta_pub_edit'), + url(r'^(?P[0-9]+)/publicacao/(?P[0-9]+)/delete$', + views.PublicacaoDeleteView.as_view(), name='ta_pub_delete'), + + url(r'^config/tipo-textoarticulado$', views.TipoTaListView.as_view(), name='tipo_ta_list'), url(r'^config/tipo-textoarticulado/create$', diff --git a/compilacao/utils.py b/compilacao/utils.py index db48bd286..dd6b40f66 100644 --- a/compilacao/utils.py +++ b/compilacao/utils.py @@ -194,7 +194,7 @@ def build_crud(model, help_path, layout): def get_template_names(self): names = super(BaseMixin, self).get_template_names() - names.append("crud/%s.html" % + names.append("compilacao/%s.html" % self.template_name_suffix.lstrip('_')) return names diff --git a/compilacao/views.py b/compilacao/views.py index bb3d6389e..acc8b20d3 100644 --- a/compilacao/views.py +++ b/compilacao/views.py @@ -1,6 +1,6 @@ -import sys from collections import OrderedDict from datetime import datetime, timedelta +import sys from braces.views import FormMessagesMixin from django import forms @@ -21,13 +21,15 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView from django.views.generic.list import ListView from compilacao import utils -from compilacao.forms import NotaForm, TaForm, TipoTaForm, VideForm +from compilacao.forms import NotaForm, TaForm, TipoTaForm, VideForm,\ + PublicacaoForm from compilacao.models import (Dispositivo, Nota, PerfilEstruturalTextoArticulado, TextoArticulado, TipoDispositivo, TipoNota, TipoPublicacao, TipoTextoArticulado, TipoVide, - VeiculoPublicacao, Vide) -from compilacao.utils import build_crud + VeiculoPublicacao, Vide, Publicacao) +from compilacao.utils import build_crud, NO_ENTRIES_MSG + DISPOSITIVO_SELECT_RELATED = ( 'tipo_dispositivo', @@ -160,19 +162,25 @@ class CompMixin(object): @property def title(self): - return self.get_object() + try: + return self.get_object() + except: + return self.object class TipoTaListView(ListView): model = TipoTextoArticulado paginate_by = 10 verbose_name = model._meta.verbose_name - create_url = reverse_lazy('tipo_ta_create') @property def title(self): return self.model._meta.verbose_name_plural + @property + def create_url(self): + return reverse_lazy('tipo_ta_create') + class TipoTaCreateView(FormMessagesMixin, CreateView): model = TipoTextoArticulado @@ -239,12 +247,15 @@ class TaListView(ListView): model = TextoArticulado paginate_by = 10 verbose_name = model._meta.verbose_name - create_url = reverse_lazy('ta_create') @property def title(self): return self.model._meta.verbose_name_plural + @property + def create_url(self): + return reverse_lazy('ta_create') + def get_context_data(self, **kwargs): context = super(TaListView, self).get_context_data(**kwargs) paginator = context['paginator'] @@ -316,7 +327,7 @@ class TaDeleteView(CompMixin, DeleteView): return reverse_lazy('ta_list') -class TextView(ListView): +class TextView(ListView, CompMixin): template_name = 'compilacao/text_list.html' flag_alteradora = -1 @@ -1533,3 +1544,101 @@ class DispositivoSearchFragmentFormView(ListView): except Exception as e: print(e) + + +class PublicacaoListView(ListView): + model = Publicacao + verbose_name = model._meta.verbose_name + + @property + def title(self): + return _('%s de %s' % ( + self.model._meta.verbose_name_plural, + self.ta)) + + @property + def ta(self): + ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + return ta + + @property + def create_url(self): + return reverse_lazy( + 'ta_pub_create', + kwargs={'ta_id': self.kwargs['ta_id']}) + + def get_queryset(self): + pubs = Publicacao.objects.filter(ta_id=self.kwargs['ta_id']) + return pubs + + def get_context_data(self, **kwargs): + context = super(PublicacaoListView, self).get_context_data(**kwargs) + context['NO_ENTRIES_MSG'] = NO_ENTRIES_MSG + return context + + +class PublicacaoCreateView(FormMessagesMixin, CreateView): + model = Publicacao + form_class = PublicacaoForm + template_name = "compilacao/form.html" + form_valid_message = _('Registro criado com sucesso!') + form_invalid_message = _('O registro não foi criado.') + + def get_success_url(self): + return reverse_lazy( + 'ta_pub_detail', + kwargs={ + 'pk': self.object.id, + 'ta_id': self.kwargs['ta_id']}) + + @property + def cancel_url(self): + return reverse_lazy( + 'ta_pub_list', + kwargs={'ta_id': self.kwargs['ta_id']}) + + def get_initial(self): + return {'ta': self.kwargs['ta_id']} + + +class PublicacaoDetailView(CompMixin, DetailView): + model = Publicacao + + +class PublicacaoUpdateView(CompMixin, UpdateView): + model = Publicacao + form_class = PublicacaoForm + template_name = "compilacao/form.html" + + def get(self, request, *args, **kwargs): + self.object = self.get_object() + form = self.get_form() + # if self.object and self.object.content_object: + # form.fields['tipo_ta'].required = False + # form.fields['tipo_ta'].widget.attrs['disabled'] = 'disabled' + return self.render_to_response(self.get_context_data(form=form)) + + def get_success_url(self): + return reverse_lazy('ta_pub_detail', + kwargs={ + 'pk': self.object.id, + 'ta_id': self.kwargs['ta_id']}) + + @property + def cancel_url(self): + return self.get_success_url() + + +class PublicacaoDeleteView(CompMixin, DeleteView): + model = Publicacao + template_name = "compilacao/confirm_delete.html" + + @property + def detail_url(self): + return reverse_lazy('ta_pub_detail', + kwargs={ + 'pk': self.object.id, + 'ta_id': self.kwargs['ta_id']}) + + def get_success_url(self): + return reverse_lazy('ta_pub_list') diff --git a/templates/compilacao/detail.html b/templates/compilacao/detail.html new file mode 100644 index 000000000..f6b89bb8d --- /dev/null +++ b/templates/compilacao/detail.html @@ -0,0 +1,38 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block base_content %} + + {# FIXME is this the best markup to use? #} +
+ {% block actions %} + + {% endblock actions %} + {% block sections_nav %}{% endblock %} +
+ + {% block detail_content %} + {# TODO replace fieldset for something semantically correct, but with similar visual grouping style #} + {% for fieldset in view.fieldsets %} +
+ {{ fieldset.legend }} + {% for row in fieldset.rows %} +
+ {% for column in row %} +
+
+ {# TODO replace labels, probably (are they correct here?) #} +

{{ column.text }}

+
+
+ {% endfor %} +
+ {% endfor %} +
+ {% endfor %} + {% endblock detail_content %} + +{% endblock base_content %} diff --git a/templates/compilacao/list.html b/templates/compilacao/list.html new file mode 100644 index 000000000..97a1aa34b --- /dev/null +++ b/templates/compilacao/list.html @@ -0,0 +1,82 @@ +{% extends "base.html" %} +{% load i18n %} + +{% block base_content %} + +{# FIXME is this the best markup to use? #} + + +{% if not rows %} +

{{ NO_ENTRIES_MSG }}

+{% else %} + + + + {% for name in headers %} + + {% endfor %} + + + + {% for value_list in rows %} + + {% for value, href in value_list %} + + {% endfor %} + + {% endfor %} + +
{{ name }}
+ {% if href %} + {{ value }} + {% else %} + {{ value }} + {% endif %} +
+{% endif %} + + +{% if is_paginated %} +
+ +
+{% endif %} +{% endblock %} diff --git a/templates/compilacao/publicacao_detail.html b/templates/compilacao/publicacao_detail.html new file mode 100644 index 000000000..324dfbef1 --- /dev/null +++ b/templates/compilacao/publicacao_detail.html @@ -0,0 +1,85 @@ +{% extends "base.html" %} {% load i18n %} {% load compilacao_filters %} + +{% block base_content %} {# FIXME is this the best markup to use? #} +
+ {% block actions %} + + {% endblock actions %} + +
+ + {% block detail_content %} {# TODO replace fieldset for something semantically correct, but with similar visual grouping style #} +
+ {%trans 'Identificação Básica'%} + +
+
+
+ +

{{ object.tipo_publicacao}}

+
+
+
+
+ +

{{ object.data}}

+
+
+
+
+ +

{{ object.ano}}

+
+
+
+
+ +

{{ object.numero|default:''}}

+
+
+
+
+ +

{{ object.edicao|default:''}}

+
+
+
+
+
+
+ +

{{ object.veiculo_publicacao}}

+
+
+
+
+ +

{{ object.pagina_inicio|default:''}}

+
+
+
+
+ +

{{ object.pagina_fim|default:''}}

+
+
+
+
+
+
+ +

{{ object.url_externa|default:''}}

+
+
+ +
+
+ {% endblock detail_content %} + +{% endblock base_content %} diff --git a/templates/compilacao/publicacao_list.html b/templates/compilacao/publicacao_list.html new file mode 100644 index 000000000..6be141c93 --- /dev/null +++ b/templates/compilacao/publicacao_list.html @@ -0,0 +1,81 @@ +{% extends "base.html" %} +{% load i18n %} +{% load compilacao_filters %} + +{% block base_content %} + + + +{% if not object_list %} +

{{ NO_ENTRIES_MSG }}

+{% else %} + + + + + + + + + + + + + {% for pub in object_list %} + + + + + + + + + {% endfor %} + +
{% fieldclass_verbose_name 'Publicacao' 'data' %}{% fieldclass_verbose_name 'Publicacao' 'numero' %}{% fieldclass_verbose_name 'Publicacao' 'ano' %}{% fieldclass_verbose_name 'Publicacao' 'edicao' %}{% fieldclass_verbose_name 'Publicacao' 'veiculo_publicacao' %}{% fieldclass_verbose_name 'Publicacao' 'tipo_publicacao' %}
{{ pub.data }}{{ pub.numero|default:'' }}{{ pub.ano|default:'' }}{{ pub.edicao|default:'' }}{{ pub.veiculo_publicacao }}{{ pub.tipo_publicacao}}
+{%endif%} + +{% if is_paginated %} +
+ +
+{% endif %} +{% endblock %} diff --git a/templates/compilacao/textoarticulado_detail.html b/templates/compilacao/textoarticulado_detail.html index 33c5e57c5..c22ab825a 100644 --- a/templates/compilacao/textoarticulado_detail.html +++ b/templates/compilacao/textoarticulado_detail.html @@ -26,7 +26,7 @@ {%else%}
{% trans 'Início' %}
{%endif%} -
{% model_verbose_name_plural 'Publicacao' %}
+
{% model_verbose_name_plural 'Publicacao' %}
{% trans 'Texto' %}
{% trans 'Edição do Texto' %}
diff --git a/templates/compilacao/textoarticulado_list.html b/templates/compilacao/textoarticulado_list.html index 0c077e25e..169cd1b5c 100644 --- a/templates/compilacao/textoarticulado_list.html +++ b/templates/compilacao/textoarticulado_list.html @@ -20,7 +20,7 @@