diff --git a/compilacao/forms.py b/compilacao/forms.py index 8b52a4d81..da081e3b4 100644 --- a/compilacao/forms.py +++ b/compilacao/forms.py @@ -18,6 +18,7 @@ from compilacao.models import (NOTAS_PUBLICIDADE_CHOICES, Publicacao, TextoArticulado, TipoNota, TipoPublicacao, TipoTextoArticulado, TipoVide, VeiculoPublicacao, Vide, TipoDispositivo) +from compilacao.utils import DISPOSITIVO_SELECT_RELATED from crispy_layout_mixin import SaplFormLayout, to_column, to_row from sapl import utils from sapl.utils import YES_NO_CHOICES @@ -621,7 +622,7 @@ class DispositivoSearchModalForm(Form): label=_('Ano do Documento'), required=False) dispositivos_internos = forms.ChoiceField( - label=_('Incluir Dispositivos Internos?'), + label=_('Incluir Dispositivos Internos Imediatos?'), choices=utils.YES_NO_CHOICES, widget=forms.RadioSelect(), required=False) @@ -639,9 +640,9 @@ class DispositivoSearchModalForm(Form): fields_search = Fieldset( _('Busca por um Dispositivo'), Row( - to_column(('num_ta', 4)), - to_column(('ano_ta', 4)), - to_column((InlineRadios('dispositivos_internos'), 4))), + to_column(('num_ta', 3)), + to_column(('ano_ta', 3)), + to_column((InlineRadios('dispositivos_internos'), 6))), Row( to_column(('tipo_ta', 6)), to_column(('tipo_model', 6))), @@ -765,6 +766,14 @@ class DispositivoEdicaoVigenciaForm(ModelForm): pk=self.instance.dispositivo_vigencia_id) self.fields['dispositivo_vigencia'].choices = [(d.pk, d) for d in dvs] + def clean_dispositivo_vigencia(self): + dv = self.cleaned_data['dispositivo_vigencia'] + + if dv and dv.is_relative_auto_insert(): + dv = dv.dispositivo_pai + + return dv + def save(self): super(DispositivoEdicaoVigenciaForm, self).save() @@ -774,6 +783,10 @@ class DispositivoEdicaoVigenciaForm(ModelForm): if extensao: dv = data['dispositivo_vigencia'] + + if dv and dv.is_relative_auto_insert(): + dv = dv.dispositivo_pai + dv_pk = dv.pk if dv else None instance = self.instance @@ -833,17 +846,7 @@ class DispositivoDefinidorVigenciaForm(Form): dvs = Dispositivo.objects.order_by('ta', 'ordem').filter( dispositivo_vigencia_id=pk).select_related( - 'tipo_dispositivo', - 'ta_publicado', - 'ta', - 'dispositivo_atualizador', - 'dispositivo_atualizador__dispositivo_pai', - 'dispositivo_atualizador__dispositivo_pai__ta', - 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'ta_publicado', - 'ta',) + *DISPOSITIVO_SELECT_RELATED) self.initial['dispositivo_vigencia'] = [d.pk for d in dvs] tas = Dispositivo.objects.filter( @@ -854,18 +857,10 @@ class DispositivoDefinidorVigenciaForm(Form): if not tas: tas = Dispositivo.objects.filter(pk=pk).values_list('ta_id') - dvs = Dispositivo.objects.order_by('-ta__data', '-ta__ano', '-ta__numero', 'ta', 'ordem').filter( - ta__in=tas).select_related( - 'tipo_dispositivo', - 'ta_publicado', - 'ta', - 'dispositivo_atualizador', - 'dispositivo_atualizador__dispositivo_pai', - 'dispositivo_atualizador__dispositivo_pai__ta', - 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'ta_publicado', - 'ta',) + dvs = Dispositivo.objects.order_by( + '-ta__data', '-ta__ano', '-ta__numero', 'ta', 'ordem').filter( + ta__in=tas).select_related(*DISPOSITIVO_SELECT_RELATED) self.fields['dispositivo_vigencia'].choices = [ - (d.pk, d) for d in dvs] + (d.pk, d) + for d in dvs + if d.pk in self.initial['dispositivo_vigencia']] diff --git a/compilacao/migrations/0047_auto_20160330_0027.py b/compilacao/migrations/0047_auto_20160330_0027.py new file mode 100644 index 000000000..920c70c2a --- /dev/null +++ b/compilacao/migrations/0047_auto_20160330_0027.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-03-30 03:27 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0046_auto_20160319_1542'), + ] + + operations = [ + migrations.AlterField( + model_name='dispositivo', + name='dispositivo_vigencia', + field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dispositivos_vigencias_set', to='compilacao.Dispositivo', verbose_name='Dispositivo de Vigência'), + ), + ] diff --git a/compilacao/models.py b/compilacao/models.py index 96961f673..8b96aba33 100644 --- a/compilacao/models.py +++ b/compilacao/models.py @@ -627,6 +627,7 @@ class Dispositivo(BaseModel, TimestampedMixin): dispositivo_vigencia = models.ForeignKey( 'self', blank=True, null=True, default=None, + on_delete=models.SET_NULL, related_name='dispositivos_vigencias_set', verbose_name=_('Dispositivo de Vigência')) dispositivo_atualizador = models.ForeignKey( diff --git a/compilacao/utils.py b/compilacao/utils.py index ef517e08d..38c55239a 100644 --- a/compilacao/utils.py +++ b/compilacao/utils.py @@ -1,4 +1,17 @@ +DISPOSITIVO_SELECT_RELATED = ( + 'tipo_dispositivo', + 'ta_publicado', + 'ta', + 'dispositivo_atualizador', + 'dispositivo_atualizador__dispositivo_pai', + 'dispositivo_atualizador__dispositivo_pai__ta', + 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', + 'dispositivo_pai', + 'dispositivo_pai__tipo_dispositivo', + 'ta_publicado', + 'ta',) + def int_to_roman(int_value): # if isinstance(int_value, type(1)): diff --git a/compilacao/views.py b/compilacao/views.py index 1e6c901f4..4842f00b4 100644 --- a/compilacao/views.py +++ b/compilacao/views.py @@ -33,22 +33,10 @@ from compilacao.models import (Dispositivo, Nota, TextoArticulado, TipoDispositivo, TipoNota, TipoPublicacao, TipoTextoArticulado, TipoVide, VeiculoPublicacao, Vide) +from compilacao.utils import DISPOSITIVO_SELECT_RELATED from crud.base import Crud, CrudListView, make_pagination -DISPOSITIVO_SELECT_RELATED = ( - 'tipo_dispositivo', - 'ta_publicado', - 'ta', - 'dispositivo_atualizador', - 'dispositivo_atualizador__dispositivo_pai', - 'dispositivo_atualizador__dispositivo_pai__ta', - 'dispositivo_atualizador__dispositivo_pai__ta__tipo_ta', - 'dispositivo_pai', - 'dispositivo_pai__tipo_dispositivo', - 'ta_publicado', - 'ta',) - TipoNotaCrud = Crud.build(TipoNota, 'tipo_nota') TipoVideCrud = Crud.build(TipoVide, 'tipo_vide') TipoPublicacaoCrud = Crud.build(TipoPublicacao, 'tipo_publicacao') @@ -2090,8 +2078,8 @@ class DispositivoSearchFragmentFormView(ListView): def get_queryset(self): try: - n = 10 - q = Q(nivel__gt=0) + n = 50 + q = Q() if 'initial_ref' in self.request.GET: initial_ref = self.request.GET['initial_ref'] if initial_ref: @@ -2103,13 +2091,16 @@ class DispositivoSearchFragmentFormView(ListView): return result[:n] + str_texto = '' texto = '' rotulo = '' + num_ta = '' + ano_ta = '' if 'texto' in self.request.GET: - texto = self.request.GET['texto'] + str_texto = self.request.GET['texto'] - texto = texto.split(' ') + texto = str_texto.split(' ') if 'rotulo' in self.request.GET: rotulo = self.request.GET['rotulo'] @@ -2122,39 +2113,51 @@ class DispositivoSearchFragmentFormView(ListView): if q: q = q & (Q(texto__icontains=item) | Q(texto_atualizador__icontains=item)) - n = 50 else: q = (Q(texto__icontains=item) | Q(texto_atualizador__icontains=item)) - n = 50 if 'tipo_ta' in self.request.GET: tipo_ta = self.request.GET['tipo_ta'] if tipo_ta: q = q & Q(ta__tipo_ta_id=tipo_ta) - n = 50 if 'num_ta' in self.request.GET: num_ta = self.request.GET['num_ta'] if num_ta: q = q & Q(ta__numero=num_ta) - n = 50 if 'ano_ta' in self.request.GET: ano_ta = self.request.GET['ano_ta'] if ano_ta: q = q & Q(ta__ano=ano_ta) - n = 50 - result = Dispositivo.objects.filter(q).select_related( - 'ta').exclude(tipo_dispositivo__dispositivo_de_alteracao=True) + if not q.children: + n = 10 + q = q & Q(nivel__gt=0) + + result = Dispositivo.objects.order_by( + '-ta__data', + '-ta__ano', + '-ta__numero', + 'ta', + 'ordem').filter(q).select_related('ta').exclude( + tipo_dispositivo__dispositivo_de_alteracao=True) + + def resultados(r): + if num_ta and ano_ta and not rotulo and not str_texto and\ + 'data_type_selection' in self.request.GET and\ + self.request.GET['data_type_selection'] == 'checkbox': + return r + else: + return r[:n] if 'tipo_model' not in self.request.GET: - return result[:n] + return resultados(result) tipo_model = self.request.GET['tipo_model'] if not tipo_model: - return result[:n] + return resultados(result) integrations_view_names = get_integrations_view_names() @@ -2176,7 +2179,7 @@ class DispositivoSearchFragmentFormView(ListView): break if not model_class: - return result[:n] + return resultados(result) column_field = '' for field in model_class._meta.fields: @@ -2185,7 +2188,7 @@ class DispositivoSearchFragmentFormView(ListView): break if not column_field: - return result[:n] + return resultados(result) r = [] @@ -2197,7 +2200,8 @@ class DispositivoSearchFragmentFormView(ListView): if tipo_model.pk == getattr(d.ta.content_object, column_field): r.append(d) - if len(r) == n: + if (len(r) == n and (not num_ta or + not ano_ta or rotulo or str_texto)): break return r diff --git a/static/js/compilacao.js b/static/js/compilacao.js index 0a7f2aa3a..954e75121 100644 --- a/static/js/compilacao.js +++ b/static/js/compilacao.js @@ -23,45 +23,6 @@ function insertWaitAjax(element) { } -var tipo_select = ''; -var tipo_form = ''; -var configFormSearchTA = function(container, _tipo_form, _tipo_select) { - tipo_select = _tipo_select; - tipo_form = _tipo_form; - var ta_select = $(container+" select[name='tipo_ta']"); - $(container+" label[for='id_tipo_model']").html('Tipos de ' + ta_select[0].children[ta_select[0].selectedIndex].innerHTML); - - $(container+" select[name='tipo_ta']").change(function(event) { - var url = ''; - url = '/ta/search_fragment_form?action=get_tipos&tipo_ta='+this.value; - $(container+" label[for='id_tipo_model']").html('Tipos de ' + this.children[this.selectedIndex].innerHTML); - - var select = $(container+" select[name='tipo_model']"); - select.empty(); - $('').appendTo(select); - - $.get(url).done(function( data ) { - select.empty(); - for(var item in data) { - for (var i in data[item]) - select.append($("').appendTo(select); - } - select.change(onChangeParamTA) - }); - }); - $(container+" input[name='num_ta'], " - + container+" input[name='ano_ta'], " - + container+" select[name='tipo_model'], " - + container+" input[name='dispositivos_internos'], " - + container+" input[name='texto_dispositivo'], " - + container+" input[name='rotulo_dispositivo']" - ).change(onChangeParamTA); - - $(container+" .btn-busca").click(onChangeParamTA); -} - - function DispostivoSearch(opts) { @@ -80,23 +41,23 @@ function DispostivoSearch(opts) { var data_field = field.attr('data-field'); var onChangeFieldSelects = function(event) { - var selecionados = field.find('input'); - selecionados.off() - if (data_type_selection == 'checkbox') { - selecionados.on('change', function(event) { - if (!this.checked) { - if ($(this).closest('ul').find('li').length == 2) - $(this).closest('ul').remove(); - else - $(this).closest('li').remove(); - } + var tas = field.find('input[name="ta_select_all"]'); //tas - Textos Articulados + tas.off(); + + tas.on('change', function(event) { + $(this).closest('ul').find('input[name="'+data_field+'"]').prop("checked", this.checked); + //$(this).prop("checked", false); }); + + } else { - selecionados.attr('type', 'hidden'); + var dpts = field.find('input'); + dpts.off() + dpts.attr('type', 'hidden'); $('') - .insertBefore(selecionados) + .insertBefore(dpts) .append($('')) .on('click', function() { if ($(this).closest('ul').find('li').length == 2) @@ -117,6 +78,17 @@ function DispostivoSearch(opts) { var rotulo_dispositivo = $("input[name='rotulo_dispositivo']").val(); var texto_dispositivo = $("input[name='texto_dispositivo']").val(); var url = ''; + + if (rotulo_dispositivo.length > 0 || texto_dispositivo.length > 0) { + $("input[name='dispositivos_internos']").prop('disabled', false); + $("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','1'); + } + else { + $("input[name='dispositivos_internos']").filter('[value="False"]').prop('checked', true); + $("input[name='dispositivos_internos']").prop('disabled', true); + $("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','0.3'); + dispositivos_internos = 'False'; + } var formData = { 'tipo_ta' : tipo_ta, 'tipo_model' : tipo_model, @@ -134,9 +106,35 @@ function DispostivoSearch(opts) { insertWaitAjax('.result-busca-dispositivo') $.get(url, formData).done(function( data ) { $('.result-busca-dispositivo').html(data); + + if (data_type_selection == 'checkbox') { + var tas = $('.result-busca-dispositivo').find('input[name="ta_select_all"]'); + tas.off(); + tas.on('change', function(event) { + $(this).closest('ul').find('input[name="'+data_field+'"]').prop("checked", this.checked); + }); + } + }); } + var onKeyPressRotuloBuscaTextual = function(event) { + var rotulo_dispositivo = $("input[name='rotulo_dispositivo']").val(); + var texto_dispositivo = $("input[name='texto_dispositivo']").val(); + var dispositivos_internos = $("input[name='dispositivos_internos']:checked").val(); + + if (rotulo_dispositivo.length > 0 || texto_dispositivo.length > 0) { + $("input[name='dispositivos_internos']").prop('disabled', false); + $("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','1'); + } + else { + $("input[name='dispositivos_internos']").filter('[value="False"]').prop('checked', true); + $("input[name='dispositivos_internos']").prop('disabled', true); + $("input[name='dispositivos_internos']").closest('#div_id_dispositivos_internos').css('opacity','0.3'); + dispositivos_internos = 'False'; + } + } + var button_ds = field.children("#button_ds"); if (button_ds.length > 0) $(button_ds).remove(); @@ -168,17 +166,20 @@ function DispostivoSearch(opts) { for (var i in data[item]) select.append($("{% endif %} {% endfor %} diff --git a/templates/compilacao/layout/dispositivo_checkbox.html b/templates/compilacao/layout/dispositivo_checkbox.html index 815c9fd2d..3ab87c5cc 100644 --- a/templates/compilacao/layout/dispositivo_checkbox.html +++ b/templates/compilacao/layout/dispositivo_checkbox.html @@ -1,7 +1,6 @@ {% load crispy_forms_filters %} {% load i18n compilacao_filters common_tags%} -
{% include 'bootstrap/layout/field_errors_block.html' %} @@ -10,7 +9,14 @@ {% ifchanged choice.1.ta%} {% if not forloop.first %}{% endif %}
- + {% if choice.1.ta_publicado_id %} + {% trans "Herança:" %} {% nomenclatura_heranca choice.1 1 1 %} + {% endif %}
-
+
{{ choice.1.tipo_dispositivo.rotulo_prefixo_html|safe }} {% if choice.1.rotulo %}{{ choice.1.rotulo }}{%else%}[{{ choice.1|nomenclatura}}{% if choice.1.dispositivo_pai %} {% trans "de" %} {{ choice.1.dispositivo_pai.rotulo }}{% endif %}] - {% endif %} {{ choice.1.tipo_dispositivo.rotulo_sufixo_html|safe }} diff --git a/templates/compilacao/layout/dispositivo_radio.html b/templates/compilacao/layout/dispositivo_radio.html index 1192e86aa..8d019ccdb 100644 --- a/templates/compilacao/layout/dispositivo_radio.html +++ b/templates/compilacao/layout/dispositivo_radio.html @@ -12,7 +12,7 @@ {% ifchanged dpt.ta%} {% if not forloop.first %}{% endif %}
    -
  • {{dpt.ta}}
  • +
  • {{dpt.ta}}
  • {% endifchanged %} {% if dpt.is_relative_auto_insert %}
  • diff --git a/templates/compilacao/text_edit.html b/templates/compilacao/text_edit.html index e61c89f53..3e0bdfa66 100644 --- a/templates/compilacao/text_edit.html +++ b/templates/compilacao/text_edit.html @@ -63,7 +63,7 @@
  • (E) Editor Simples: Edição Básica de Texto, além de novas inserções e exclusões. É recomendável o uso deste sempre que possível.
  • (E+) Editor Rico: Edição do texto com o editor TinyMCE. Neste editor é possível registro de tabelas e textos customizados
  • (E*) Editor Avançado: Edição e Lançamento de Dispositivos Originais, Alterados e Alteradores, além de todos os dados que controlam a compilação.
  • -
  • (C) Construtor Estrutural: Neste modo, o editor foca na inserção de Dispositivos e busca deixar mais acessíveis as estas ações.
  • +
  • (C) Construtor Estrutural: Neste modo, o editor foca na inserção de Dispositivos e busca deixar mais acessíveis estas ações.
  • A Edição Avançada é complexa e sensível a erros de edição. É recomendável o uso cuidadoso e consciente das funcionalidades.
  • @@ -75,7 +75,7 @@
  • Inserir os Dispositivos na sequência natural é mais produtivo para você, além de ser também mais simples para o algorítmo que controla este processo. Quanto maior a mudança estutural, mais lento será o procedimento.
  • -
  • A Opção DVt (Dispositivo de Vigência do Texto) redefine o dispositivo em seleção, como o dispositivo de vigência de todos os outros, inclusive os dispositivos alterados, caso se trate de um Texto Alterador. +
  • A Opção DVt (Dispositivo de Vigência do Texto) redefine o dispositivo em seleção como o dispositivo de vigência de todos os outros, inclusive os dispositivos alterados, caso se trate de um Texto Alterador.
    1. O Dispositivo de Vigência de Dispositivos Alterados é, quase sempre, o Dispositivo do Texto Alterador, e não do Texto Alterado.
    2. Ao usar a opção DVt, todas as datas de início de vigência serão reenquadradas para a data de vigência do dispositivo de vigência. Posteriormente, alterações manuais poderão ser feitas.
    3. @@ -96,9 +96,9 @@ As exclusões podem ser diretas, individuais ou em bloco:
      1. Diretas: Dispositivos que não possuam itens internos são excluidos diretamente.
      2. -
      3. Individuais: Dispositivos que possuam itens internos e este podem ser reenquadrados no Dispositivo imediatamente anterior +
      4. Individuais: Dispositivos que possuam itens internos e estes podem ser reenquadrados no Dispositivo imediatamente anterior
          -
        • Ainda Não foi implementado a transferência de conteúdo na exclusão individual de DCC's que estão estruturalmente separados. Ex: Um artigo possui parágrafos, se seu artigo imediatamente anterior estiver no mesmo sub-grupo, esses parágrafos, na exlcusão individual, serão transferidos para o artigo anterior, no entanto, se estiverem em sub-grupo separados, o artigo será completamente excluido como em uma exclusão em bloco.
        • +
        • Ainda Não foi implementado a transferência de conteúdo na exclusão individual de DCC's que estão estruturalmente separados. Ex: Um artigo possui parágrafos, se seu artigo imediatamente anterior estiver no mesmo sub-grupo, esses parágrafos, na exclusão individual, serão transferidos para o artigo anterior, no entanto, se estiverem em sub-grupo separados, o artigo será completamente excluido como em uma exclusão em bloco.
      5. Em Bloco: Todo o conteúdo incluído no Dispositivo em edição será excluído.
      6. diff --git a/templates/compilacao/text_edit_bloco.html b/templates/compilacao/text_edit_bloco.html index 34e078de9..cc36d6bb6 100644 --- a/templates/compilacao/text_edit_bloco.html +++ b/templates/compilacao/text_edit_bloco.html @@ -99,7 +99,7 @@ {% if dpt.dispositivo_vigencia %}
      7. -
      8. {% field_verbose_name dpt 'dispositivo_vigencia'%}: {{dpt.dispositivo_vigencia|nomenclatura}}
      9. +
      10. {% field_verbose_name dpt 'dispositivo_vigencia'%}: {{dpt.dispositivo_vigencia|nomenclatura}}
      11. {% endif %}