diff --git a/compilacao/forms.py b/compilacao/forms.py index e3e5b19f4..606691d28 100644 --- a/compilacao/forms.py +++ b/compilacao/forms.py @@ -218,11 +218,13 @@ class VideForm(ModelForm): queryset=Dispositivo.objects.all(), widget=forms.HiddenInput()) - tipo_norma = forms.ModelChoiceField( - queryset=TipoNormaJuridica.objects.all(), + tipo_ta = forms.ModelChoiceField( + queryset=TipoTextoArticulado.objects.all(), required=False) - num_norma = forms.IntegerField(label=_('Núm. da Norma'), required=False) - ano_norma = forms.IntegerField(label=_('Ano da Norma'), required=False) + num_ta = forms.IntegerField( + label=_('Núm Texto Articulado'), required=False) + ano_ta = forms.IntegerField( + label=_('Ano Texto Articulado'), required=False) texto = forms.CharField( label='', @@ -280,9 +282,9 @@ class VideForm(ModelForm): ), 4)), to_column(( Div( - Div(to_column(('tipo_norma', 6))), - Div(to_column(('num_norma', 3)), - to_column(('ano_norma', 3))), + Div(to_column(('tipo_ta', 6))), + Div(to_column(('num_ta', 3)), + to_column(('ano_ta', 3))), Div(to_column( (Field( 'busca_dispositivo', diff --git a/compilacao/migrations/0035_auto_20151226_1349.py b/compilacao/migrations/0035_auto_20151226_1349.py new file mode 100644 index 000000000..ded460760 --- /dev/null +++ b/compilacao/migrations/0035_auto_20151226_1349.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import builtins + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('compilacao', '0034_auto_20151226_1321'), + ] + + operations = [ + migrations.AddField( + model_name='textoarticulado', + name='content_type', + field=models.ForeignKey( + to='contenttypes.ContentType', default=142), + preserve_default=False, + ), + migrations.AddField( + model_name='textoarticulado', + name='object_id', + field=models.PositiveIntegerField(default=1), + preserve_default=False, + ), + ] diff --git a/compilacao/migrations/0036_auto_20151226_1411.py b/compilacao/migrations/0036_auto_20151226_1411.py new file mode 100644 index 000000000..1ae7b9baf --- /dev/null +++ b/compilacao/migrations/0036_auto_20151226_1411.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0035_auto_20151226_1349'), + ] + + operations = [ + migrations.AlterField( + model_name='textoarticulado', + name='content_type', + field=models.ForeignKey(default=None, null=True, to='contenttypes.ContentType', blank=True), + ), + ] diff --git a/compilacao/migrations/0037_auto_20151226_1414.py b/compilacao/migrations/0037_auto_20151226_1414.py new file mode 100644 index 000000000..5420d7917 --- /dev/null +++ b/compilacao/migrations/0037_auto_20151226_1414.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0036_auto_20151226_1411'), + ] + + operations = [ + migrations.AlterField( + model_name='textoarticulado', + name='object_id', + field=models.PositiveIntegerField(blank=True, default=None, null=True), + ), + ] diff --git a/compilacao/migrations/0038_tipotextoarticulado_model.py b/compilacao/migrations/0038_tipotextoarticulado_model.py new file mode 100644 index 000000000..561196e71 --- /dev/null +++ b/compilacao/migrations/0038_tipotextoarticulado_model.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0037_auto_20151226_1414'), + ] + + operations = [ + migrations.AddField( + model_name='tipotextoarticulado', + name='model', + field=models.CharField(max_length=50, blank=True, default='', null=True, verbose_name='Modelagem Django'), + ), + ] diff --git a/compilacao/migrations/0039_auto_20151226_1433.py b/compilacao/migrations/0039_auto_20151226_1433.py new file mode 100644 index 000000000..807711408 --- /dev/null +++ b/compilacao/migrations/0039_auto_20151226_1433.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('compilacao', '0038_tipotextoarticulado_model'), + ] + + operations = [ + migrations.AlterField( + model_name='tipotextoarticulado', + name='model', + field=models.CharField(verbose_name='Modelagem Django', default='', blank=True, null=True, max_length=50, unique=True), + ), + ] diff --git a/compilacao/models.py b/compilacao/models.py index 908effd82..9fc246519 100644 --- a/compilacao/models.py +++ b/compilacao/models.py @@ -1,6 +1,8 @@ from datetime import datetime from django.contrib.auth.models import User +from django.contrib.contenttypes.fields import GenericForeignKey +from django.contrib.contenttypes.models import ContentType from django.db import models from django.db.models import F, Q from django.db.models.aggregates import Max @@ -61,6 +63,12 @@ class BaseModel(models.Model): class TipoTextoArticulado(models.Model): sigla = models.CharField(max_length=3, verbose_name=_('Sigla')) descricao = models.CharField(max_length=50, verbose_name=_('Descrição')) + model = models.CharField( + default='', + blank=True, null=True, + max_length=50, + unique=True, + verbose_name=_('Modelagem Django')) participacao_social = models.NullBooleanField( default=False, blank=True, null=True, @@ -98,16 +106,26 @@ class TextoArticulado(TimestampedMixin): choices=PARTICIPACAO_SOCIAL_CHOICES, verbose_name=_('Participação Social')) + content_type = models.ForeignKey( + ContentType, + blank=True, null=True, default=None) + object_id = models.PositiveIntegerField( + blank=True, null=True, default=None) + content_object = GenericForeignKey('content_type', 'object_id') + class Meta: verbose_name = _('Texto Articulado') verbose_name_plural = _('Textos Articulados') ordering = ['-data', '-numero'] def __str__(self): - return _('Texto Articulado nº %(numero)s de %(data)s') % { - 'tipo': self.tipo_ta, - 'numero': self.numero, - 'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")} + if self.content_object: + return str(self.content_object) + else: + return _('Texto Articulado nº %(numero)s de %(data)s') % { + 'tipo': self.tipo_ta, + 'numero': self.numero, + 'data': defaultfilters.date(self.data, "d \d\e F \d\e Y")} class TipoNota(models.Model): diff --git a/compilacao/urls.py b/compilacao/urls.py index 15232998b..109e7583a 100644 --- a/compilacao/urls.py +++ b/compilacao/urls.py @@ -13,55 +13,59 @@ urlpatterns_compilacao = [ url(r'^(?P[0-9]+)/text$', - views.TextoView.as_view(), name='ta_text'), + views.TextView.as_view(), name='ta_text'), url(r'^(?P[0-9]+)/text/vigencia/(?P.+)/$', - views.TextoView.as_view(), name='ta_vigencia'), -] + views.TextView.as_view(), name='ta_vigencia'), -urlpatterns = [ - url(r'^ta/', include(urlpatterns_compilacao)), -] + url(r'^(?P[0-9]+)/text/edit', + views.TextEditView.as_view(), name='ta_text_edit'), -""" - url(r'^(?P[0-9]+)/compilacao/(?P[0-9]+)/$', + url(r'^(?P[0-9]+)/text/(?P[0-9]+)/$', views.DispositivoView.as_view(), name='dispositivo'), - - - url(r'^(?P[0-9]+)/compilacao/edit', - views.CompilacaoEditView.as_view(), name='comp_edit'), - url(r'^(?P[0-9]+)/compilacao/(?P[0-9]+)/refresh', - views.DispositivoEditView.as_view(), name='dispositivo_edit'), - - url(r'^(?P[0-9]+)/compilacao/(?P[0-9]+)/actions', - views.ActionsEditView.as_view(), name='dispositivo_actions'), - - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/nota/create$', views.NotasCreateView.as_view(), name='nota_create'), - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/nota/(?P[0-9]+)/edit$', views.NotasEditView.as_view(), name='nota_edit'), - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/nota/(?P[0-9]+)/delete$', views.NotasDeleteView.as_view(), name='nota_delete'), - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/vide/create$', views.VideCreateView.as_view(), name='vide_create'), - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/vide/(?P[0-9]+)/edit$', views.VideEditView.as_view(), name='vide_edit'), - url(r'^(?P[0-9]+)/compilacao/' + url(r'^(?P[0-9]+)/text/' '(?P[0-9]+)/vide/(?P[0-9]+)/delete$', views.VideDeleteView.as_view(), name='vide_delete'), - url(r'^(?P[0-9]+)/compilacao/search$', + url(r'^(?P[0-9]+)/text/search$', views.DispositivoSearchFragmentFormView.as_view(), name='search_dispositivo'), +] + +urlpatterns = [ + url(r'^ta/', include(urlpatterns_compilacao)), +] + + +""" + + + + url(r'^(?P[0-9]+)/compilacao/(?P[0-9]+)/refresh', + views.DispositivoEditView.as_view(), name='dispositivo_edit'), + + url(r'^(?P[0-9]+)/compilacao/(?P[0-9]+)/actions', + views.ActionsEditView.as_view(), name='dispositivo_actions'), + """ diff --git a/compilacao/views.py b/compilacao/views.py index 50105e1dd..a98be81e2 100644 --- a/compilacao/views.py +++ b/compilacao/views.py @@ -104,7 +104,7 @@ class TaDeleteView(DeleteView): return reverse_lazy('ta_list') -class TextoView(ListView): +class TextView(ListView): template_name = 'compilacao/text_list.html' flag_alteradora = -1 @@ -118,7 +118,10 @@ class TextoView(ListView): fim_vigencia = None def get_context_data(self, **kwargs): - context = super(TextoView, self).get_context_data(**kwargs) + context = super(TextView, self).get_context_data(**kwargs) + + context['object'] = TextoArticulado.objects.get( + pk=self.kwargs['ta_id']) cita = Vide.objects.filter( Q(dispositivo_base__ta_id=self.kwargs['ta_id'])).\ @@ -185,16 +188,7 @@ class TextoView(ListView): r = Dispositivo.objects.filter( ordem__gt=0, ta_id=self.kwargs['ta_id'], - ).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') + ).select_related(*DISPOSITIVO_SELECT_RELATED) return r @@ -264,7 +258,7 @@ class TextoView(ListView): return self.flag_alteradora > 0 -class DispositivoView(TextoView): +class DispositivoView(TextView): # template_name = 'compilacao/index.html' template_name = 'compilacao/text_list_bloco.html' @@ -298,3 +292,310 @@ class DispositivoView(TextoView): ta_id=self.kwargs['ta_id'] ).select_related(*DISPOSITIVO_SELECT_RELATED) return itens + + +class TextEditView(TextView): + + template_name = 'compilacao/text_edit.html' + + flag_alteradora = -1 + + flag_nivel_ini = 0 + flag_nivel_old = -1 + + pk_edit = 0 + pk_view = 0 + """ + def get(self, request, *args, **kwargs): + + self.object_list = self.get_queryset() + context = self.get_context_data( + object_list=self.object_list) + + return self.render_to_response(context)""" + + def get_queryset(self): + self.pk_edit = 0 + self.pk_view = 0 + + self.flag_alteradora = -1 + self.flag_nivel_ini = 0 + self.flag_nivel_old = -1 + + result = Dispositivo.objects.filter( + ta_id=self.kwargs['ta_id'] + ).select_related(*DISPOSITIVO_SELECT_RELATED) + + if not result.exists(): + + ta = TextoArticulado.objects.get(pk=self.kwargs['ta_id']) + + td = TipoDispositivo.objects.filter(class_css='articulacao')[0] + a = Dispositivo() + a.nivel = 0 + a.ordem = Dispositivo.INTERVALO_ORDEM + a.ordem_bloco_atualizador = 0 + a.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + a.ta = ta + a.tipo_dispositivo = td + a.inicio_vigencia = ta.data + a.inicio_eficacia = ta.data + a.timestamp = datetime.now() + a.save() + + td = TipoDispositivo.objects.filter(class_css='ementa')[0] + e = Dispositivo() + e.nivel = 1 + e.ordem = a.ordem + Dispositivo.INTERVALO_ORDEM + e.ordem_bloco_atualizador = 0 + e.set_numero_completo([1, 0, 0, 0, 0, 0, ]) + e.ta = ta + e.tipo_dispositivo = td + e.inicio_vigencia = ta.data + e.inicio_eficacia = ta.data + e.timestamp = datetime.now() + e.texto = ta.ementa + e.dispositivo_pai = a + e.save() + + a.pk = None + a.nivel = 0 + a.ordem = e.ordem + Dispositivo.INTERVALO_ORDEM + a.ordem_bloco_atualizador = 0 + a.set_numero_completo([2, 0, 0, 0, 0, 0, ]) + a.timestamp = datetime.now() + a.save() + + result = Dispositivo.objects.filter( + ta_id=self.kwargs['ta_id'] + ).select_related(*DISPOSITIVO_SELECT_RELATED) + + return result + + def set_perfil_in_session(self, request=None, perfil_id=0): + if not request: + return None + + if perfil_id: + perfil = PerfilEstruturalTextoArticulado.objects.get( + pk=perfil_id) + request.session['perfil_estrutural'] = perfil.pk + else: + perfis = PerfilEstruturalTextoArticulado.objects.filter( + padrao=True)[:1] + + if not perfis.exists(): + request.session.pop('perfil_estrutural') + else: + request.session['perfil_estrutural'] = perfis[0].pk + + +class DispositivoSuccessUrlMixin(object): + + def get_success_url(self): + return reverse( + 'dispositivo', kwargs={ + 'ta_id': self.kwargs[ + 'ta_id'], + 'dispositivo_id': self.kwargs[ + 'dispositivo_id']}) + + +class NotaMixin(DispositivoSuccessUrlMixin): + + def get_modelo_nota(self, request): + if 'action' in request.GET and request.GET['action'] == 'modelo_nota': + tn = TipoNota.objects.get(pk=request.GET['id_tipo']) + return True, tn.modelo + return False, '' + + def get_initial(self): + dispositivo = get_object_or_404( + Dispositivo, pk=self.kwargs.get('dispositivo_id')) + initial = {'dispositivo': dispositivo} + + if 'pk' in self.kwargs: + initial['pk'] = self.kwargs.get('pk') + + return initial + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super(NotaMixin, self).dispatch(*args, **kwargs) + + +class NotasCreateView(NotaMixin, CreateView): + template_name = 'compilacao/ajax_form.html' + form_class = forms.NotaForm + + def get(self, request, *args, **kwargs): + flag_action, modelo_nota = self.get_modelo_nota(request) + if flag_action: + return HttpResponse(modelo_nota) + + return super(NotasCreateView, self).get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + try: + ta_id = kwargs.pop('ta_id') + dispositivo_id = kwargs.pop('dispositivo_id') + form = forms.NotaForm(request.POST, request.FILES, **kwargs) + kwargs['ta_id'] = ta_id + kwargs['dispositivo_id'] = dispositivo_id + + if form.is_valid(): + nt = form.save(commit=False) + nt.owner_id = request.user.pk + nt.save() + self.kwargs['pk'] = nt.pk + return self.form_valid(form) + else: + return self.form_invalid(form) + except Exception as e: + print(e) + return HttpResponse("post") + + +class NotasEditView(NotaMixin, UpdateView): + model = Nota + template_name = 'compilacao/ajax_form.html' + form_class = forms.NotaForm + + def get(self, request, *args, **kwargs): + flag_action, modelo_nota = self.get_modelo_nota(request) + if flag_action: + return HttpResponse(modelo_nota) + + return super(NotasEditView, self).get(request, *args, **kwargs) + + +class NotasDeleteView(NotaMixin, TemplateView): + + def get(self, request, *args, **kwargs): + nt = Nota.objects.get(pk=self.kwargs['pk']) + nt.delete() + return HttpResponseRedirect(self.get_success_url()) + + +class VideMixin(DispositivoSuccessUrlMixin): + + def get_initial(self): + dispositivo_base = get_object_or_404( + Dispositivo, pk=self.kwargs.get('dispositivo_id')) + + initial = {'dispositivo_base': dispositivo_base} + + if 'pk' in self.kwargs: + initial['pk'] = self.kwargs.get('pk') + + return initial + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super(VideMixin, self).dispatch(*args, **kwargs) + + +class VideCreateView(VideMixin, CreateView): + template_name = 'compilacao/ajax_form.html' + form_class = forms.VideForm + + def post(self, request, *args, **kwargs): + try: + ta_id = kwargs.pop('ta_id') + dispositivo_id = kwargs.pop('dispositivo_id') + form = forms.VideForm(request.POST, request.FILES, **kwargs) + kwargs['ta_id'] = ta_id + kwargs['dispositivo_id'] = dispositivo_id + + if form.is_valid(): + vd = form.save(commit=False) + vd.save() + self.kwargs['pk'] = vd.pk + return self.form_valid(form) + else: + return self.form_invalid(form) + except Exception as e: + print(e) + return HttpResponse("post") + + +class VideEditView(VideMixin, UpdateView): + model = Vide + template_name = 'compilacao/ajax_form.html' + form_class = forms.VideForm + + +class VideDeleteView(VideMixin, TemplateView): + + def get(self, request, *args, **kwargs): + vd = Vide.objects.get(pk=self.kwargs['pk']) + vd.delete() + return HttpResponseRedirect(self.get_success_url()) + + +class DispositivoSearchFragmentFormView(ListView): + template_name = 'compilacao/dispositivo_search_fragment_form.html' + + @method_decorator(login_required) + def dispatch(self, *args, **kwargs): + return super( + DispositivoSearchFragmentFormView, + self).dispatch(*args, **kwargs) + + def get_queryset(self): + try: + busca = '' + + if 'busca' in self.request.GET: + busca = self.request.GET['busca'] + + q = Q(nivel__gt=0) + busca = busca.split(' ') + n = 10 + + for item in busca: + + if not item: + continue + + if q: + q = q & (Q(dispositivo_pai__rotulo__icontains=item) | + Q(rotulo__icontains=item) | + Q(texto__icontains=item) | + Q(texto_atualizador__icontains=item)) + n = 50 + else: + q = (Q(dispositivo_pai__rotulo__icontains=item) | + Q(rotulo__icontains=item) | + 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 + + if 'initial_ref' in self.request.GET: + initial_ref = self.request.GET['initial_ref'] + if initial_ref: + q = q & Q(pk=initial_ref) + n = 50 + + return Dispositivo.objects.filter(q)[:n] + + except Exception as e: + print(e) diff --git a/compilacao/views2.py b/compilacao/views2.py index c2068fda7..5afd1a3a0 100644 --- a/compilacao/views2.py +++ b/compilacao/views2.py @@ -1135,217 +1135,3 @@ class ActionsEditView(ActionsEditMixin, TemplateView): context['perfil_pk'] = self.request.session['perfil_estrutural'] return self.render_to_json_response(context, **response_kwargs) - - -class DispositivoSuccessUrlMixin(object): - - def get_success_url(self): - return reverse( - 'dispositivo', kwargs={ - 'ta_id': self.kwargs[ - 'ta_id'], - 'dispositivo_id': self.kwargs[ - 'dispositivo_id']}) - - -class NotaMixin(DispositivoSuccessUrlMixin): - - def get_modelo_nota(self, request): - # TODO: permitir edição apenas das notas do usuário conectado - # TODO: tratar revalidação no método post - # TODO: não mostrar botão de edição na interface - if 'action' in request.GET and request.GET['action'] == 'modelo_nota': - tn = TipoNota.objects.get(pk=request.GET['id_tipo']) - return True, tn.modelo - return False, '' - - def get_initial(self): - dispositivo = get_object_or_404( - Dispositivo, pk=self.kwargs.get('dispositivo_id')) - initial = {'dispositivo': dispositivo} - - if 'pk' in self.kwargs: - initial['pk'] = self.kwargs.get('pk') - - return initial - - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super(NotaMixin, self).dispatch(*args, **kwargs) - - -class NotasCreateView(NotaMixin, CreateView): - template_name = 'compilacao/ajax_form.html' - form_class = forms.NotaForm - - def get(self, request, *args, **kwargs): - flag_action, modelo_nota = self.get_modelo_nota(request) - if flag_action: - return HttpResponse(modelo_nota) - - return super(NotasCreateView, self).get(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - try: - ta_id = kwargs.pop('ta_id') - dispositivo_id = kwargs.pop('dispositivo_id') - form = forms.NotaForm(request.POST, request.FILES, **kwargs) - kwargs['ta_id'] = ta_id - kwargs['dispositivo_id'] = dispositivo_id - - if form.is_valid(): - nt = form.save(commit=False) - nt.owner_id = request.user.pk - nt.save() - self.kwargs['pk'] = nt.pk - return self.form_valid(form) - else: - return self.form_invalid(form) - except Exception as e: - print(e) - return HttpResponse("post") - - -class NotasEditView(NotaMixin, UpdateView): - model = Nota - template_name = 'compilacao/ajax_form.html' - form_class = forms.NotaForm - - def get(self, request, *args, **kwargs): - flag_action, modelo_nota = self.get_modelo_nota(request) - if flag_action: - return HttpResponse(modelo_nota) - - return super(NotasEditView, self).get(request, *args, **kwargs) - - -class NotasDeleteView(NotaMixin, TemplateView): - - def get(self, request, *args, **kwargs): - nt = Nota.objects.get(pk=self.kwargs['pk']) - nt.delete() - return HttpResponseRedirect(self.get_success_url()) - - -class VideMixin(DispositivoSuccessUrlMixin): - - def get_initial(self): - dispositivo_base = get_object_or_404( - Dispositivo, pk=self.kwargs.get('dispositivo_id')) - - initial = {'dispositivo_base': dispositivo_base} - - if 'pk' in self.kwargs: - initial['pk'] = self.kwargs.get('pk') - - return initial - - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super(VideMixin, self).dispatch(*args, **kwargs) - - -class VideCreateView(VideMixin, CreateView): - template_name = 'compilacao/ajax_form.html' - form_class = forms.VideForm - - def post(self, request, *args, **kwargs): - try: - ta_id = kwargs.pop('ta_id') - dispositivo_id = kwargs.pop('dispositivo_id') - form = forms.VideForm(request.POST, request.FILES, **kwargs) - kwargs['ta_id'] = ta_id - kwargs['dispositivo_id'] = dispositivo_id - - if form.is_valid(): - vd = form.save(commit=False) - vd.save() - self.kwargs['pk'] = vd.pk - return self.form_valid(form) - else: - return self.form_invalid(form) - except Exception as e: - print(e) - return HttpResponse("post") - - -class VideEditView(VideMixin, UpdateView): - model = Vide - template_name = 'compilacao/ajax_form.html' - form_class = forms.VideForm - - -class VideDeleteView(VideMixin, TemplateView): - - def get(self, request, *args, **kwargs): - vd = Vide.objects.get(pk=self.kwargs['pk']) - vd.delete() - return HttpResponseRedirect(self.get_success_url()) - - -class DispositivoSearchFragmentFormView(ListView): - template_name = 'compilacao/dispositivo_search_fragment_form.html' - - @method_decorator(login_required) - def dispatch(self, *args, **kwargs): - return super( - DispositivoSearchFragmentFormView, - self).dispatch(*args, **kwargs) - - def get_queryset(self): - try: - busca = '' - - if 'busca' in self.request.GET: - busca = self.request.GET['busca'] - - q = Q(nivel__gt=0) - busca = busca.split(' ') - n = 10 - - for item in busca: - - if not item: - continue - - if q: - q = q & (Q(dispositivo_pai__rotulo__icontains=item) | - Q(rotulo__icontains=item) | - Q(texto__icontains=item) | - Q(texto_atualizador__icontains=item)) - n = 50 - else: - q = (Q(dispositivo_pai__rotulo__icontains=item) | - Q(rotulo__icontains=item) | - 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_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 - - if 'initial_ref' in self.request.GET: - initial_ref = self.request.GET['initial_ref'] - if initial_ref: - q = q & Q(pk=initial_ref) - n = 50 - - return Dispositivo.objects.filter(q)[:n] - - except Exception as e: - print(e) diff --git a/materia/urls.py b/materia/urls.py index f081515a8..7876a613d 100644 --- a/materia/urls.py +++ b/materia/urls.py @@ -15,7 +15,8 @@ from materia.views import (AutoriaEditView, AutoriaView, regime_tramitacao_crud, status_tramitacao_crud, tipo_autor_crud, tipo_documento_crud, tipo_fim_relatoria_crud, tipo_materia_crud, - tipo_proposicao_crud, unidade_tramitacao_crud) + tipo_proposicao_crud, unidade_tramitacao_crud, + MateriaTaView) materia_legislativa_patterns = materia_legislativa_crud.urlpatterns @@ -26,6 +27,11 @@ urlpatterns = [ materia_legislativa_crud.namespace, materia_legislativa_crud.namespace)), + + url(r'^materia/(?P[0-9]+)/ta$', + MateriaTaView.as_view(), name='materia_ta'), + + url(r'^sistema/proposicoes/tipo/', include(tipo_proposicao_crud.urls)), url(r'^sistema/proposicoes/autor/', include(autor_crud.urls)), url(r'^sistema/materia/tipo/', include(tipo_materia_crud.urls)), diff --git a/materia/views.py b/materia/views.py index 49a918abd..4026f85a5 100644 --- a/materia/views.py +++ b/materia/views.py @@ -4,10 +4,11 @@ from re import sub from crispy_forms.helper import FormHelper from crispy_forms.layout import ButtonHolder, Column, Fieldset, Layout, Submit from django import forms +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, reverse_lazy from django.forms import ModelForm -from django.shortcuts import redirect +from django.shortcuts import redirect, get_object_or_404 from django.utils.html import strip_tags from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ @@ -15,11 +16,12 @@ from django.views.generic import ListView from django.views.generic.edit import FormMixin from vanilla import GenericView -import sapl from comissoes.models import Comissao, Composicao +from compilacao.models import TextoArticulado, TipoTextoArticulado from norma.models import LegislacaoCitada, NormaJuridica, TipoNormaJuridica from parlamentares.models import Parlamentar from sapl.crud import build_crud +import sapl from .models import (Anexada, Autor, Autoria, DespachoInicial, DocumentoAcessorio, MateriaLegislativa, Numeracao, Orgao, @@ -28,6 +30,7 @@ from .models import (Anexada, Autor, Autoria, DespachoInicial, TipoFimRelatoria, TipoMateriaLegislativa, TipoProposicao, Tramitacao, UnidadeTramitacao) + origem_crud = build_crud( Origem, 'origem', [ @@ -508,10 +511,10 @@ class MateriaAnexadaView(FormMixin, GenericView): error = 'A matéria a ser anexada não pode ser do mesmo \ tipo da matéria principal.' return self.render_to_response( - {'error': error, - 'form': form, - 'materialegislativa': mat_principal, - 'anexadas': anexadas}) + {'error': error, + 'form': form, + 'materialegislativa': mat_principal, + 'anexadas': anexadas}) anexada = Anexada() anexada.materia_principal = mat_principal @@ -527,17 +530,17 @@ class MateriaAnexadaView(FormMixin, GenericView): error = 'A matéria a ser anexada não existe no cadastro \ de matérias legislativas.' return self.render_to_response( - {'error': error, - 'form': form, - 'materialegislativa': mat_principal, - 'anexadas': anexadas}) + {'error': error, + 'form': form, + 'materialegislativa': mat_principal, + 'anexadas': anexadas}) return self.form_valid(form) else: return self.render_to_response( - {'form': form, - 'materialegislativa': mat_principal, - 'anexadas': anexadas}) + {'form': form, + 'materialegislativa': mat_principal, + 'anexadas': anexadas}) def get_success_url(self): pk = self.kwargs['pk'] @@ -615,14 +618,14 @@ class MateriaAnexadaEditView(FormMixin, GenericView): error = 'A matéria a ser anexada não existe no cadastro \ de matérias legislativas.' return self.render_to_response( - {'error': error, - 'form': form, - 'materialegislativa': mat_principal}) + {'error': error, + 'form': form, + 'materialegislativa': mat_principal}) else: return self.render_to_response( - {'form': form, - 'materialegislativa': mat_principal}) + {'form': form, + 'materialegislativa': mat_principal}) def get_success_url(self): pk = self.kwargs['pk'] @@ -1519,7 +1522,7 @@ class TramitacaoEditView(FormMixin, GenericView): if form.is_valid(): if 'excluir' in request.POST: if tramitacao == Tramitacao.objects.filter( - materia=materia).last(): + materia=materia).last(): tramitacao.delete() return self.form_valid(form) else: @@ -1765,7 +1768,7 @@ class ProposicaoForm(ModelForm): ButtonHolder( Submit('sumbmit', 'Salvar', css_class='button primary') - ), css_class='columns large-2')) + ), css_class='columns large-2')) self.helper = FormHelper() self.helper.layout = Layout( @@ -1836,7 +1839,7 @@ class ProposicaoListView(ListView): page_obj = context['page_obj'] context['page_range'] = sapl.crud.make_pagination( - page_obj.number, paginator.num_pages) + page_obj.number, paginator.num_pages) return context @@ -1907,7 +1910,7 @@ class MateriaLegislativaPesquisaForm(forms.Form): label='Tramitando', choices=em_tramitacao(), widget=forms.Select( - attrs={'class': 'selector'})) + attrs={'class': 'selector'})) # TODO: Verificar se esses campos estão corretos # assunto? # -> usado 'ementa' em 'assunto' @@ -1979,13 +1982,13 @@ class MateriaLegislativaPesquisaView(FormMixin, GenericView): if request.POST['data_apresentacao']: kwargs['data_apresentacao'] = datetime.strptime( - request.POST['data_apresentacao'], - '%d/%m/%Y').strftime('%Y-%m-%d') + request.POST['data_apresentacao'], + '%d/%m/%Y').strftime('%Y-%m-%d') if request.POST['data_publicacao']: kwargs['data_publicacao'] = datetime.strptime( - request.POST['data_publicacao'], - '%d/%m/%Y').strftime('%Y-%m-%d') + request.POST['data_publicacao'], + '%d/%m/%Y').strftime('%Y-%m-%d') if request.POST['tramitacao']: kwargs['em_tramitacao'] = request.POST['tramitacao'] @@ -2018,3 +2021,35 @@ class PesquisaMateriaListView(FormMixin, ListView): context['page_range'] = sapl.crud.make_pagination( page_obj.number, paginator.num_pages) return context + + +class MateriaTaView(GenericView): + + def get(self, *args, **kwargs): + materia = get_object_or_404(MateriaLegislativa, pk=kwargs['pk']) + related_object_type = ContentType.objects.get_for_model(materia) + + ta = TextoArticulado.objects.filter( + object_id=materia.pk, + content_type=related_object_type) + + if not ta.exists(): + tipo_ta = TipoTextoArticulado.objects.filter( + model=materia.__class__.__name__.lower())[:1] + + ta = TextoArticulado() + + if tipo_ta.exists(): + ta.tipo_ta = tipo_ta[0] + + ta.ementa = materia.ementa + ta.numero = materia.numero + ta.ano = materia.ano + ta.data = materia.data_apresentacao + ta.content_object = materia + ta.save() + + else: + ta = ta[0] + + return redirect(to=reverse_lazy('ta_text', kwargs={'ta_id': ta.pk})) diff --git a/norma/urls.py b/norma/urls.py index fb3110513..a63322ad3 100644 --- a/norma/urls.py +++ b/norma/urls.py @@ -1,8 +1,10 @@ from django.conf.urls import include, url -from compilacao.urls import urlpatterns as __url__compilacao +from compilacao.urls import urlpatterns as __url__compilacao,\ + urlpatterns_compilacao from norma.views import (NormaIncluirView, assunto_norma_crud, - norma_temporario_crud, tipo_norma_crud) + norma_temporario_crud, tipo_norma_crud, + NormaTaView) norma_url_patterns = norma_temporario_crud.urlpatterns @@ -13,6 +15,9 @@ urlpatterns = [ norma_temporario_crud.namespace, norma_temporario_crud.namespace)), + url(r'^norma/(?P[0-9]+)/ta$', + NormaTaView.as_view(), name='norma_ta'), + url(r'^sistema/norma/tipo/', include(tipo_norma_crud.urls)), url(r'^sistema/norma/assunto/', include(assunto_norma_crud.urls)), diff --git a/norma/views.py b/norma/views.py index 11f4cffe7..3ed76f691 100644 --- a/norma/views.py +++ b/norma/views.py @@ -4,14 +4,19 @@ from re import sub from crispy_forms.helper import FormHelper from crispy_forms.layout import ButtonHolder, Fieldset, Layout, Submit from django import forms +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ObjectDoesNotExist +from django.core.urlresolvers import reverse_lazy from django.forms import ModelForm +from django.shortcuts import get_object_or_404, redirect from django.utils.html import strip_tags from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ +from django.views.generic.base import RedirectView from django.views.generic.edit import FormMixin from vanilla import GenericView +from compilacao.models import TextoArticulado, TipoTextoArticulado from materia.models import MateriaLegislativa, TipoMateriaLegislativa from sapl.crud import build_crud import sapl @@ -60,7 +65,7 @@ norma_temporario_crud = build_crud( NormaJuridica, 'normajuridica', [ [_('Identificação Básica'), - [('tipo_ta', 3), ('tipo', 3), ('numero', 2), ('ano', 2), ('data', 2)], + [('tipo', 5), ('numero', 2), ('ano', 2), ('data', 3)], [('ementa', 12)]], ]) @@ -219,3 +224,35 @@ class NormaIncluirView(FormMixin, GenericView): return self.form_valid(form) else: return self.form_invalid(form) + + +class NormaTaView(GenericView): + + def get(self, *args, **kwargs): + norma = get_object_or_404(NormaJuridica, pk=kwargs['pk']) + related_object_type = ContentType.objects.get_for_model(norma) + + ta = TextoArticulado.objects.filter( + object_id=norma.pk, + content_type=related_object_type) + + if not ta.exists(): + tipo_ta = TipoTextoArticulado.objects.filter( + model=norma.__class__.__name__.lower())[:1] + + ta = TextoArticulado() + + if tipo_ta.exists(): + ta.tipo_ta = tipo_ta[0] + + ta.ementa = norma.ementa + ta.numero = norma.numero + ta.ano = norma.ano + ta.data = norma.data + ta.content_object = norma + ta.save() + + else: + ta = ta[0] + + return redirect(to=reverse_lazy('ta_text', kwargs={'ta_id': ta.pk})) diff --git a/sapl/settings.py b/sapl/settings.py index d2de6e1c1..18ec530fa 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -59,8 +59,8 @@ INSTALLED_APPS = ( 'crispy_forms_foundation', 'sass_processor', ) -# if DEBUG: -# INSTALLED_APPS += ('debug_toolbar',) +if DEBUG: + INSTALLED_APPS += ('debug_toolbar',) MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', diff --git a/static/js/compilacao_notas.js b/static/js/compilacao_notas.js index 4c6a09bda..8d1168acd 100644 --- a/static/js/compilacao_notas.js +++ b/static/js/compilacao_notas.js @@ -21,7 +21,7 @@ function onEventsDneExec(pk) { $('#dne'+pk+" select[name='tipo']").change(function(event) { var url = ''; - url = 'compilacao/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value; + url = 'text/'+pk+'/nota/create?action=modelo_nota&id_tipo='+this.value; $.get(url).done(function( data ) { $('#dne'+pk+" textarea[name='texto']").val(data); }); @@ -40,9 +40,9 @@ function onEventsDneExec(pk) { onChangeParamNorma(); } var onChangeParamNorma = function(event) { - var tipo_norma = $("select[name='tipo_norma']").val(); - var num_norma = $("input[name='num_norma']").val(); - var ano_norma = $("input[name='ano_norma']").val(); + var tipo_ta = $("select[name='tipo_ta']").val(); + var num_ta = $("input[name='num_ta']").val(); + var ano_ta = $("input[name='ano_ta']").val(); var busca_dispositivo = $("input[name='busca_dispositivo']").val(); var dispositivo_ref = $("#id_dispositivo_ref").val(); $('#id_dispositivo_ref').remove(); @@ -51,18 +51,18 @@ var onChangeParamNorma = function(event) { dispositivo_ref = '' var url = ''; - var pk = $("select[name='tipo_norma']").closest('.dne').attr('pk') + var pk = $("select[name='tipo_ta']").closest('.dne').attr('pk') var formData = { - 'tipo_norma' : tipo_norma, - 'num_norma' : num_norma, - 'ano_norma' : ano_norma, + 'tipo_ta' : tipo_ta, + 'num_ta' : num_ta, + 'ano_ta' : ano_ta, 'busca' : busca_dispositivo, 'tipo_form' : 'radio', 'initial_ref' : dispositivo_ref }; - url = 'compilacao/search'; + url = 'text/search'; $('.container-busca').html(''); insertWaitAjax('.container-busca') $.get(url, formData).done(function( data ) { @@ -85,7 +85,7 @@ var onSubmitEditForm = function(event) { } id_edit = $('#id_pk').val(); - url = 'compilacao/'+id_dispositivo+'/'+model+'/' + url = 'text/'+id_dispositivo+'/'+model+'/' if (id_edit == null || id_edit == '') url += 'create'; else @@ -119,7 +119,7 @@ var onDelete = function(event) { var id_dispositivo = $(event).closest('.dn').attr('pk'); var id_delete = $(event).attr('pk'); - var url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_delete+'/delete'; + var url = 'text/'+id_dispositivo+'/'+model+'/'+id_delete+'/delete'; $.get( url, function(data) { $('#dne'+id_dispositivo+' .dne-form').closest('.dpt').html(data) @@ -140,12 +140,12 @@ function getForm(_this) { if (_this.className.indexOf('create') >= 0 ) { id_dispositivo = $(_this).attr('pk'); - url = 'compilacao/'+id_dispositivo+'/'+model+'/create'; + url = 'text/'+id_dispositivo+'/'+model+'/create'; } else if (_this.className.indexOf('edit') >= 0 ) { var id_edit = $(_this).attr('pk'); id_dispositivo = $(_this).closest('.dn').attr('pk'); - url = 'compilacao/'+id_dispositivo+'/'+model+'/'+id_edit+'/edit' + url = 'text/'+id_dispositivo+'/'+model+'/'+id_edit+'/edit' } $('#dne'+id_dispositivo).addClass('dne-nota'); diff --git a/static/js/compilacao_view.js b/static/js/compilacao_view.js index e02bd2471..55f474dd7 100644 --- a/static/js/compilacao_view.js +++ b/static/js/compilacao_view.js @@ -1,7 +1,7 @@ $( window ).scroll(function() { if (window.pageYOffset <= 180) $( "section.vigencias" ).removeClass("fixed"); - else if (!$( "section.vigencias" ).hasClass("fixed")) + else if ( ! $( "section.vigencias" ).hasClass("fixed") ) $( "section.vigencias" ).addClass("fixed"); }); @@ -41,7 +41,7 @@ function textoMultiVigente(item, diff) { for (var i = 0; i < ldpts.length; i++) { if ($(ldpts[i]).hasClass('displaynone')) continue; - if (isElementInViewport( ldpts[i])) { + if (isElementInViewport( ldpts[i])) { elv = ldpts[i]; break; } @@ -123,20 +123,20 @@ function textoVigente(item, link) { for (var i = 0; i < ldpts.length; i++) { if ($(ldpts[i]).hasClass('displaynone')) continue; - if (isElementInViewport( ldpts[i])) { + if (isElementInViewport( ldpts[i])) { elv = ldpts[i]; break; } } - + $(".cp .tipo-vigencias a").removeClass("selected") $(item).addClass("selected") - + $(".dptt.desativado").addClass("displaynone"); $(".link_alterador").removeClass("displaynone"); if (!link) $(".link_alterador").addClass("displaynone"); - + if (elv) { $('html, body').animate({ scrollTop: $(elv).parent().offset().top - 60 diff --git a/templates/compilacao/edit.html b/templates/compilacao/text_edit.html similarity index 50% rename from templates/compilacao/edit.html rename to templates/compilacao/text_edit.html index c544995d5..416c990a9 100644 --- a/templates/compilacao/edit.html +++ b/templates/compilacao/text_edit.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "compilacao/textoarticulado_detail.html" %} {% load i18n %} {% load compilacao_filters %} {% load staticfiles %} @@ -17,43 +17,19 @@

Edição: {{ view.get_ta }} - {% trans 'Texto Multivigente' %}

{% endblock %} -{% block base_content %} +{% block sections_nav %} +{% endblock %} + +{% block base_content %}{{block.super}} + {% block actions %}{% endblock %} + {% block detail_content %}{% endblock %}
{% trans 'Aguarde... Atualizando informações!!!'%}
- {% include 'compilacao/edit_bloco.html'%} + {% include 'compilacao/text_edit_bloco.html'%}
- -{% if False %} -
- {% csrf_token %} - - {% if message %} -
- {{message}} - × -
- {% endif %} - - -
- {% trans 'Parser ODF' %} - {{ form.as_p }} - -
-
- -{% for parser in parser_list %} -
- {{ parser|safe}} -
-{% endfor %} -{% endif%} - - - {% endblock base_content %} diff --git a/templates/compilacao/edit_bloco.html b/templates/compilacao/text_edit_bloco.html similarity index 98% rename from templates/compilacao/edit_bloco.html rename to templates/compilacao/text_edit_bloco.html index 1d53cece5..983f0a60d 100644 --- a/templates/compilacao/edit_bloco.html +++ b/templates/compilacao/text_edit_bloco.html @@ -116,7 +116,7 @@ {% endif %} {% endspaceless %} {% if view.is_ta_alterador and dpt.tipo_dispositivo.class_css == 'bloco_alteracao'%} - {%with node=dpt template_name='compilacao/edit_bloco_alteracao.html' %} + {%with node=dpt template_name='compilacao/text_edit_blocoalteracao.html' %} {%include template_name%} {%endwith%} {% endif%} diff --git a/templates/compilacao/edit_bloco_alteracao.html b/templates/compilacao/text_edit_blocoalteracao.html similarity index 100% rename from templates/compilacao/edit_bloco_alteracao.html rename to templates/compilacao/text_edit_blocoalteracao.html diff --git a/templates/compilacao/text_list.html b/templates/compilacao/text_list.html index 1dbc71c46..150442c70 100644 --- a/templates/compilacao/text_list.html +++ b/templates/compilacao/text_list.html @@ -1,4 +1,4 @@ -{% extends "base.html" %} +{% extends "compilacao/textoarticulado_detail.html" %} {% load i18n %} {% load compilacao_filters %} {% load staticfiles %} @@ -21,15 +21,24 @@

{{ view.get_ta }}

{% endblock %} -{% block base_content %} + +{% block sections_nav %}{{block.super}} +
{% trans 'Edição do Texto' %}
+{% endblock %} + +{% block base_content %}{{block.super}} + {% block actions %}{% endblock %} + {% block detail_content %}{% endblock %}
-
- a - A -
+ {% if object_list %} +
+ a + A +
+ {% endif %} {% for key, values in view.get_vigencias.items %} {% if forloop.first %} diff --git a/templates/compilacao/textoarticulado_detail.html b/templates/compilacao/textoarticulado_detail.html index afe849a8d..0aefd9bbd 100644 --- a/templates/compilacao/textoarticulado_detail.html +++ b/templates/compilacao/textoarticulado_detail.html @@ -1,4 +1,7 @@ -{% extends "base.html" %} {% load i18n %} {% load compilacao_filters %} {% block base_content %} {# FIXME is this the best markup to use? #} +{% extends "base.html" %} {% load i18n %} {% load compilacao_filters %} + +{% block base_content %} {# FIXME is this the best markup to use? #} +
{% block actions %}
- - - - + {% block detail_content %} {# TODO replace fieldset for something semantically correct, but with similar visual grouping style #} @@ -30,14 +29,23 @@
-
+

{{ object.tipo_ta}}

-
+ {% if object.content_object %} +
+
+ +

{{ object.content_object.tipo}}

+
+
+ {%endif%} + +

{{ object.numero}}

@@ -51,7 +59,7 @@
-
+

{{ object.data}}

@@ -69,8 +77,5 @@
- - - - + {% endblock detail_content %} {% endblock base_content %} diff --git a/templates/materia/materialegislativa_detail.html b/templates/materia/materialegislativa_detail.html index 21b38fc09..ec4a3d8a8 100644 --- a/templates/materia/materialegislativa_detail.html +++ b/templates/materia/materialegislativa_detail.html @@ -12,5 +12,6 @@
{% trans 'Numeração' %}
{% trans 'Tramitação' %}
{% trans 'Relatoria' %}
+
{% trans 'Texto' %}
{% endblock sections_nav %} diff --git a/templates/norma/normajuridica_detail.html b/templates/norma/normajuridica_detail.html index 6cd1c0499..7d60e6fbc 100644 --- a/templates/norma/normajuridica_detail.html +++ b/templates/norma/normajuridica_detail.html @@ -1,7 +1,15 @@ {% extends "crud/detail.html" %} {% load i18n %} -{% block actions %} {% endblock %} +{% block actions %} + +{% endblock actions %} {% block sections_nav %} - + + {% endblock sections_nav %}