From 4ba1ffff5645706d900de04e353f10c510babf59 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Sat, 12 Nov 2016 16:46:04 -0200 Subject: [PATCH] Fix #784 --- sapl/compilacao/compilacao_data_tables.sql | 3 +- sapl/compilacao/forms.py | 8 +- .../0071_tipotextoarticulado_perfis.py | 20 +++++ .../migrations/0072_auto_20161112_1553.py | 55 ++++++++++++ sapl/compilacao/models.py | 86 +++++++++---------- sapl/compilacao/views.py | 76 ++++++++-------- sapl/materia/forms.py | 68 +++++++++++++-- sapl/materia/models.py | 15 ++++ sapl/materia/views.py | 13 +-- sapl/templates/base.html | 6 +- .../compilacao/ajax_actions_dinamic_edit.html | 2 +- sapl/templates/compilacao/text_edit.html | 2 +- sapl/templates/compilacao/text_list.html | 5 ++ .../compilacao/textoarticulado_detail.html | 6 +- .../tipotextoarticulado_detail.html | 12 +++ sapl/templates/materia/proposicao_form.html | 15 ++++ 16 files changed, 285 insertions(+), 107 deletions(-) create mode 100644 sapl/compilacao/migrations/0071_tipotextoarticulado_perfis.py create mode 100644 sapl/compilacao/migrations/0072_auto_20161112_1553.py diff --git a/sapl/compilacao/compilacao_data_tables.sql b/sapl/compilacao/compilacao_data_tables.sql index 7681eedcd..ed7c70525 100644 --- a/sapl/compilacao/compilacao_data_tables.sql +++ b/sapl/compilacao/compilacao_data_tables.sql @@ -25,8 +25,8 @@ INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (123, 'Alinea', 'alinea', '', '', 0, ')', ' – ', '', '', '', '', false, 'a', '1', '1', '1', '1', '1', '-', '-', '-', '-', '-', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (124, 'Item', 'item', '', '', 0, '', ' – ', '', '', '', '', false, '1', '1', '1', '1', '1', '1', '.', '.', '.', '.', '.', false, false); INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (125, 'Texto Não Estruturado', 'texto_n_estruturado', '', '', 0, '', '', '', '', '', '', true, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); +INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (126, 'Justificativa', 'justificativa', '', '', 0, '', '', '', '
Justificativa
', '', '', true, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); -INSERT INTO compilacao_tipodispositivo (id, nome, class_css, rotulo_prefixo_html, rotulo_prefixo_texto, rotulo_ordinal, rotulo_sufixo_texto, rotulo_sufixo_html, texto_prefixo_html, texto_sufixo_html, nota_automatica_prefixo_html, nota_automatica_sufixo_html, contagem_continua, formato_variacao0, formato_variacao1, formato_variacao2, formato_variacao3, formato_variacao4, formato_variacao5, rotulo_separador_variacao01, rotulo_separador_variacao12, rotulo_separador_variacao23, rotulo_separador_variacao34, rotulo_separador_variacao45, dispositivo_de_articulacao, dispositivo_de_alteracao) VALUES (126, 'Justificativa', 'titulo', '', '', 0, '', '', '', '', '', '', true, 'N', 'N', 'N', 'N', 'N', 'N', '-', '-', '-', '-', '-', false, false); SELECT pg_catalog.setval('compilacao_tipodispositivo_id_seq', 126, true); @@ -248,6 +248,7 @@ INSERT INTO compilacao_tipodispositivorelationship (filho_permitido_id, pai_id, INSERT INTO compilacao_tipodispositivorelationship (filho_permitido_id, pai_id, filho_de_insercao_automatica, perfil_id, quantidade_permitida, permitir_variacao) VALUES (125, 104, false, 1, -1, false); INSERT INTO compilacao_tipodispositivorelationship (filho_permitido_id, pai_id, filho_de_insercao_automatica, perfil_id, quantidade_permitida, permitir_variacao) VALUES (125, 104, false, 2, -1, false); +INSERT INTO compilacao_tipodispositivorelationship (filho_permitido_id, pai_id, filho_de_insercao_automatica, perfil_id, quantidade_permitida, permitir_variacao) VALUES (126, 1, false, 3, -1, false); INSERT INTO compilacao_tiponota (id, sigla, nome, modelo) VALUES (1, 'NE', 'Nota Explicativa', ''); diff --git a/sapl/compilacao/forms.py b/sapl/compilacao/forms.py index 1559b97ef..0374846fc 100644 --- a/sapl/compilacao/forms.py +++ b/sapl/compilacao/forms.py @@ -8,6 +8,7 @@ from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset, from django import forms from django.core.exceptions import NON_FIELD_ERRORS, ValidationError from django.db.models import Q +from django.forms import widgets from django.forms.forms import Form from django.forms.models import ModelForm from django.template import defaultfilters @@ -24,6 +25,7 @@ from sapl.compilacao.utils import DISPOSITIVO_SELECT_RELATED from sapl.crispy_layout_mixin import SaplFormLayout, to_column, to_row from sapl.utils import YES_NO_CHOICES + error_messages = { 'required': _('Este campo é obrigatório'), 'invalid': _('URL inválida.') @@ -62,9 +64,12 @@ class TipoTaForm(ModelForm): 'descricao', 'content_type', 'participacao_social', - 'publicacao_func' + 'publicacao_func', + 'perfis' ] + widgets = {'perfis': widgets.CheckboxSelectMultiple()} + def __init__(self, *args, **kwargs): row1 = to_row([ @@ -75,6 +80,7 @@ class TipoTaForm(ModelForm): row2 = to_row([ (InlineRadios('participacao_social'), 3), (InlineRadios('publicacao_func'), 3), + ('perfis', 12), ]) self.helper = FormHelper() diff --git a/sapl/compilacao/migrations/0071_tipotextoarticulado_perfis.py b/sapl/compilacao/migrations/0071_tipotextoarticulado_perfis.py new file mode 100644 index 000000000..ee2639bc5 --- /dev/null +++ b/sapl/compilacao/migrations/0071_tipotextoarticulado_perfis.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-11-12 14:25 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0070_perfilestruturaltextoarticulado_parent'), + ] + + operations = [ + migrations.AddField( + model_name='tipotextoarticulado', + name='perfis', + field=models.ManyToManyField(blank=True, help_text='\n Apenas os perfis selecionados aqui estarão disponíveis\n para o editor de Textos Articulados cujo Tipo seja este\n em edição.\n ', to='compilacao.PerfilEstruturalTextoArticulado', verbose_name='Perfis Estruturais de Textos Articulados'), + ), + ] diff --git a/sapl/compilacao/migrations/0072_auto_20161112_1553.py b/sapl/compilacao/migrations/0072_auto_20161112_1553.py new file mode 100644 index 000000000..421215496 --- /dev/null +++ b/sapl/compilacao/migrations/0072_auto_20161112_1553.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-11-12 15:53 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0071_tipotextoarticulado_perfis'), + ] + + operations = [ + migrations.AlterField( + model_name='tipodispositivo', + name='nota_automatica_prefixo_html', + field=models.TextField(blank=True, verbose_name='Prefixo html da nota automática'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='nota_automatica_sufixo_html', + field=models.TextField(blank=True, verbose_name='Sufixo html da nota automática'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='rotulo_prefixo_html', + field=models.TextField(blank=True, verbose_name='Prefixo html do rótulo'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='rotulo_prefixo_texto', + field=models.TextField(blank=True, verbose_name='Prefixo de Edição do rótulo'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='rotulo_sufixo_html', + field=models.TextField(blank=True, verbose_name='Sufixo html do rótulo'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='rotulo_sufixo_texto', + field=models.TextField(blank=True, verbose_name='Sufixo de Edição do rótulo'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='texto_prefixo_html', + field=models.TextField(blank=True, verbose_name='Prefixo html do texto'), + ), + migrations.AlterField( + model_name='tipodispositivo', + name='texto_sufixo_html', + field=models.TextField(blank=True, verbose_name='Sufixo html do texto'), + ), + ] diff --git a/sapl/compilacao/models.py b/sapl/compilacao/models.py index 80d21c744..c131564aa 100644 --- a/sapl/compilacao/models.py +++ b/sapl/compilacao/models.py @@ -75,6 +75,31 @@ class BaseModel(models.Model): update_fields=update_fields) +class PerfilEstruturalTextoArticulado(BaseModel): + sigla = models.CharField( + max_length=10, unique=True, verbose_name=_('Sigla')) + nome = models.CharField(max_length=50, verbose_name=_('Nome')) + padrao = models.BooleanField( + default=False, + choices=YES_NO_CHOICES, verbose_name=_('Padrão')) + + parent = models.ForeignKey( + 'self', + blank=True, null=True, default=None, + related_name='perfil_parent_set', + on_delete=PROTECT, + verbose_name=_('Perfil Herdado')) + + class Meta: + verbose_name = _('Perfil Estrutural de Texto Articulado') + verbose_name_plural = _('Perfis Estruturais de Textos Articulados') + + ordering = ['-padrao', 'sigla'] + + def __str__(self): + return self.nome + + class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) @@ -94,6 +119,15 @@ class TipoTextoArticulado(models.Model): choices=YES_NO_CHOICES, verbose_name=_('Histórico de Publicação')) + perfis = models.ManyToManyField( + PerfilEstruturalTextoArticulado, + blank=True, verbose_name=_('Perfis Estruturais de Textos Articulados'), + help_text=_(""" + Apenas os perfis selecionados aqui estarão disponíveis + para o editor de Textos Articulados cujo Tipo seja este + em edição. + """)) + class Meta: verbose_name = _('Tipo de Texto Articulado') verbose_name_plural = _('Tipos de Texto Articulados') @@ -539,13 +573,11 @@ class TipoDispositivo(BaseModel): blank=True, max_length=20, verbose_name=_('Classe CSS')) - rotulo_prefixo_html = models.CharField( + rotulo_prefixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Prefixo html do rótulo')) - rotulo_prefixo_texto = models.CharField( + rotulo_prefixo_texto = models.TextField( blank=True, - max_length=30, verbose_name=_('Prefixo de Edição do rótulo')) rotulo_ordinal = models.IntegerField( choices=TIPO_NUMERO_ROTULO, @@ -575,29 +607,23 @@ class TipoDispositivo(BaseModel): max_length=1, default="-", verbose_name=_('Separador entre Variação 4 e Variação 5')) - rotulo_sufixo_texto = models.CharField( + rotulo_sufixo_texto = models.TextField( blank=True, - max_length=30, verbose_name=_('Sufixo de Edição do rótulo')) - rotulo_sufixo_html = models.CharField( + rotulo_sufixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Sufixo html do rótulo')) - texto_prefixo_html = models.CharField( + texto_prefixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Prefixo html do texto')) - texto_sufixo_html = models.CharField( + texto_sufixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Sufixo html do texto')) - nota_automatica_prefixo_html = models.CharField( + nota_automatica_prefixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Prefixo html da nota automática')) - nota_automatica_sufixo_html = models.CharField( + nota_automatica_sufixo_html = models.TextField( blank=True, - max_length=100, verbose_name=_('Sufixo html da nota automática')) contagem_continua = models.BooleanField( choices=YES_NO_CHOICES, verbose_name=_('Contagem contínua')) @@ -680,8 +706,7 @@ class TipoDispositivo(BaseModel): perfil = perfil.parent return False - def permitido_variacao( - self, base, perfil_pk=None): + def permitido_variacao(self, base, perfil_pk=None): perfil = PerfilEstruturalTextoArticulado.objects.all() if not perfil_pk: @@ -704,31 +729,6 @@ class TipoDispositivo(BaseModel): return False -class PerfilEstruturalTextoArticulado(BaseModel): - sigla = models.CharField( - max_length=10, unique=True, verbose_name=_('Sigla')) - nome = models.CharField(max_length=50, verbose_name=_('Nome')) - padrao = models.BooleanField( - default=False, - choices=YES_NO_CHOICES, verbose_name=_('Padrão')) - - parent = models.ForeignKey( - 'self', - blank=True, null=True, default=None, - related_name='perfil_parent_set', - on_delete=PROTECT, - verbose_name=_('Perfil Herdado')) - - class Meta: - verbose_name = _('Perfil Estrutural de Texto Articulado') - verbose_name_plural = _('Perfis Estruturais de Textos Articulados') - - ordering = ['-padrao', 'sigla'] - - def __str__(self): - return self.nome - - class TipoDispositivoRelationship(BaseModel): pai = models.ForeignKey(TipoDispositivo, related_name='filhos_permitidos') filho_permitido = models.ForeignKey( diff --git a/sapl/compilacao/views.py b/sapl/compilacao/views.py index 6a2c5aacd..5eab491dc 100644 --- a/sapl/compilacao/views.py +++ b/sapl/compilacao/views.py @@ -1638,9 +1638,6 @@ class ActionDispositivoCreateMixin(ActionsCommonsMixin): 'action': 'json_add_prior', 'itens': []}] - if request and 'perfil_estrutural' not in request.session: - self.set_perfil_in_session(request) - perfil_pk = request.session['perfil_estrutural'] prox_possivel = Dispositivo.objects.filter( @@ -2222,42 +2219,47 @@ class ActionsEditMixin(ActionDragAndMoveDispositivoAlteradoMixin, return JsonResponse(data, safe=False) - def get_queryset_perfil_estrutural(self): - perfis = PerfilEstruturalTextoArticulado.objects.all() - return perfis - def json_get_perfis(self, context): - - if 'perfil_pk' in self.request.GET: - self.set_perfil_in_session( - self.request, self.request.GET['perfil_pk']) - elif 'perfil_estrutural' not in self.request.session: - self.set_perfil_in_session(request=self.request) - data = {'pk': self.kwargs['dispositivo_id'], 'pai': [self.kwargs['dispositivo_id'], ]} return data - def set_perfil_in_session(self, request=None, perfil_id=0): - if not request: - return None + def update_perfis(self): + qs = PerfilEstruturalTextoArticulado.objects.all() + request = self.request - if perfil_id: - perfil = PerfilEstruturalTextoArticulado.objects.get( - pk=perfil_id) - request.session['perfil_estrutural'] = perfil.pk - return perfil.pk + ta = None + if hasattr(self, 'object') and isinstance(self.object, Dispositivo): + ta = self.object.ta + elif hasattr(self, 'object') and isinstance( + self.object, TextoArticulado): + ta = self.object else: - perfis = PerfilEstruturalTextoArticulado.objects.filter( - padrao=True)[:1] + ta_id = self.kwargs.get('ta_id', 0) + if ta_id: + ta = TextoArticulado.objects.get(pk=ta_id) - if not perfis.exists(): - request.session.pop('perfil_estrutural') + if ta: + if ta.content_object and hasattr(ta.content_object, 'perfis'): + qs = ta.content_object.perfis else: - request.session['perfil_estrutural'] = perfis[0].pk - return perfis[0].pk - return None + qs = ta.tipo_ta.perfis.all() + + perfil_get = request.GET.get('perfil_pk', 0) + if perfil_get and qs.filter(id=perfil_get).exists(): + request.session['perfil_estrutural'] = int(perfil_get) + return qs + + perfil_session = request.session.get('perfil_estrutural', perfil_get) + if perfil_session and qs.filter(id=perfil_session).exists(): + request.session['perfil_estrutural'] = int(perfil_session) + return qs + + if qs.exists(): + request.session['perfil_estrutural'] = qs.first().id + + return qs def json_add_next_registra_inclusao( self, context, local_add='json_add_next'): @@ -2500,6 +2502,9 @@ class DispositivoDinamicEditView( self.template_name = 'compilacao/text_edit_bloco.html' return TextEditView.get(self, request, *args, **kwargs) + self.object = Dispositivo.objects.get(pk=self.kwargs['dispositivo_id']) + perfil_estrutural_list = self.update_perfis() + self.template_name = 'compilacao/ajax_form.html' self.action = request.GET['action'] @@ -2519,9 +2524,6 @@ class DispositivoDinamicEditView( elif self.action.startswith('get_actions'): self.form_class = None - self.object = Dispositivo.objects.get( - pk=self.kwargs['dispositivo_id']) - ta_id = self.kwargs['ta_id'] context = {} @@ -2537,17 +2539,9 @@ class DispositivoDinamicEditView( 'ajax_actions_dinamic_edit.html') if ta_id == str(self.object.ta_id): + context['perfil_estrutural_list'] = perfil_estrutural_list context['allowed_inserts'] = self.allowed_inserts() - if 'perfil_pk' in request.GET: - self.set_perfil_in_session( - request, request.GET['perfil_pk']) - elif 'perfil_estrutural' not in request.session: - self.set_perfil_in_session(request=request) - - context['perfil_estrutural_list' - ] = PerfilEstruturalTextoArticulado.objects.all() - return self.render_to_response(context) elif self.action.startswith('json_'): diff --git a/sapl/materia/forms.py b/sapl/materia/forms.py index d1742521a..d4eadfee4 100644 --- a/sapl/materia/forms.py +++ b/sapl/materia/forms.py @@ -1,12 +1,13 @@ from datetime import date, datetime +from itertools import chain import os from crispy_forms.bootstrap import (Alert, FormActions, InlineCheckboxes, InlineRadios) from crispy_forms.helper import FormHelper from crispy_forms.layout import (HTML, Button, Column, Field, Fieldset, Layout, - Submit) + Submit, Div) from django import forms from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist, ValidationError @@ -16,6 +17,10 @@ from django.db import models, transaction from django.db.models import Max from django.forms import ModelForm, widgets from django.forms.forms import Form +from django.forms.widgets import Select +from django.utils.encoding import force_text +from django.utils.html import format_html +from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ import django_filters @@ -757,8 +762,8 @@ class TipoProposicaoForm(ModelForm): def __init__(self, *args, **kwargs): tipo_select = Fieldset(TipoProposicao._meta.verbose_name, - to_column(('descricao', 5)), - to_column(('content_type', 7)), + Div(to_column(('descricao', 5)), + to_column(('content_type', 7)), css_class='clearfix'), to_column(('tipo_conteudo_related_radio', 6)), to_column(('perfis', 6))) @@ -811,6 +816,44 @@ class TipoProposicaoForm(ModelForm): return super().save(True) +class TipoProposicaoSelect(Select): + + def render_tipo_option(self, selected_choices, option_value, option_label, + data_has_perfil=False): + if option_value is None: + option_value = '' + option_value = force_text(option_value) + if option_value in selected_choices: + selected_html = mark_safe(' selected="selected"') + if not self.allow_multiple_selected: + # Only allow for a single selection. + selected_choices.remove(option_value) + else: + selected_html = '' + return format_html('', + option_value, + selected_html, + str(data_has_perfil), + force_text(option_label)) + + def render_options(self, choices, selected_choices): + # Normalize to strings. + selected_choices = set(force_text(v) for v in selected_choices) + output = [] + output.append( + self.render_tipo_option( + selected_choices, '', self.choices.field.empty_label)) + + for tipo in self.choices.queryset.all(): + output.append( + self.render_tipo_option( + selected_choices, + str(tipo.pk), + str(tipo), + data_has_perfil=tipo.perfis.exists())) + return '\n'.join(output) + + class ProposicaoForm(forms.ModelForm): TIPO_TEXTO_CHOICE = [ @@ -830,7 +873,7 @@ class ProposicaoForm(forms.ModelForm): ano_materia = forms.CharField( label='Ano', required=False) - tipo_texto = forms.MultipleChoiceField( + tipo_texto = forms.ChoiceField( label=_('Tipo do Texto da Proposição'), required=False, choices=TIPO_TEXTO_CHOICE, @@ -854,7 +897,8 @@ class ProposicaoForm(forms.ModelForm): 'tipo_texto'] widgets = { - 'descricao': widgets.Textarea(attrs={'rows': 4})} + 'descricao': widgets.Textarea(attrs={'rows': 4}), + 'tipo': TipoProposicaoSelect()} def __init__(self, *args, **kwargs): self.texto_articulado_proposicao = sapl.base.models.AppConfig.attr( @@ -896,12 +940,12 @@ class ProposicaoForm(forms.ModelForm): super(ProposicaoForm, self).__init__(*args, **kwargs) if self.instance.pk: - self.fields['tipo_texto'].initial = [] + self.fields['tipo_texto'].initial = '' if self.instance.texto_original: - self.fields['tipo_texto'].initial.append('D') + self.fields['tipo_texto'].initial = 'D' if self.texto_articulado_proposicao: if self.instance.texto_articulado.exists(): - self.fields['tipo_texto'].initial.append('T') + self.fields['tipo_texto'].initial = 'T' if self.instance.materia_de_vinculo: self.fields[ @@ -944,6 +988,14 @@ class ProposicaoForm(forms.ModelForm): def save(self, commit=True): if self.instance.pk: + if 'tipo_texto' in self.cleaned_data: + if self.cleaned_data['tipo_texto'] in ['T', ''] and\ + self.instance.texto_original: + self.instance.texto_original.delete() + + if self.cleaned_data['tipo_texto'] in ['D', '']: + self.instance.texto_articulado.all().delete() + return super().save(commit) self.instance.ano = datetime.now().year diff --git a/sapl/materia/models.py b/sapl/materia/models.py index a96b1209b..d84e0f2bf 100644 --- a/sapl/materia/models.py +++ b/sapl/materia/models.py @@ -1,8 +1,11 @@ +from datetime import datetime + from django.contrib.auth.models import Group from django.contrib.contenttypes.fields import GenericRelation from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models.deletion import PROTECT +from django.utils import formats from django.utils.translation import ugettext_lazy as _ from model_utils import Choices @@ -15,6 +18,7 @@ from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES, SaplGenericForeignKey, SaplGenericRelation, restringe_tipos_de_arquivo_txt, texto_upload_path) + EM_TRAMITACAO = [(1, 'Sim'), (0, 'Não')] @@ -565,6 +569,17 @@ class Proposicao(models.Model): documento_gerado = models.ForeignKey( DocumentoAcessorio, blank=True, null=True)""" + @property + def perfis(self): + return self.tipo.perfis.all() + + @property + def title_type(self): + return '%s nº _____ %s' % ( + self.tipo, formats.date_format( + self.data_envio if self.data_envio else datetime.now(), + "\d\e d \d\e F \d\e Y")) + class Meta: verbose_name = _('Proposição') verbose_name_plural = _('Proposições') diff --git a/sapl/materia/views.py b/sapl/materia/views.py index 63d456a3e..dade1932b 100644 --- a/sapl/materia/views.py +++ b/sapl/materia/views.py @@ -624,18 +624,19 @@ class ProposicaoCrud(Crud): def get_rows(self, object_list): for obj in object_list: + if obj.data_recebimento is None: + obj.data_recebimento = 'Não recebida'\ + if obj.data_envio else 'Não enviada' + else: + obj.data_recebimento = formats.date_format( + obj.data_recebimento, "DATETIME_FORMAT") + if obj.data_envio is None: obj.data_envio = 'Em elaboração...' else: obj.data_envio = formats.date_format( obj.data_envio, "DATETIME_FORMAT") - if obj.data_recebimento is None: - obj.data_recebimento = 'Não recebida' - else: - obj.data_envio = formats.date_format( - obj.data_recebimento, "DATETIME_FORMAT") - return [self._as_row(obj) for obj in object_list] diff --git a/sapl/templates/base.html b/sapl/templates/base.html index d8c1d2c0c..c1ab49e09 100644 --- a/sapl/templates/base.html +++ b/sapl/templates/base.html @@ -94,7 +94,9 @@ - {% block sections_nav %} {% subnav %} {% endblock sections_nav %} +
+ {% block sections_nav %} {% subnav %} {% endblock sections_nav %} +
{% endblock main_header %} @@ -148,7 +150,7 @@ {% block footer_container %} -