mirror of https://github.com/interlegis/sapl.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1985 lines
67 KiB
1985 lines
67 KiB
|
|
import os
|
|
|
|
import django_filters
|
|
from crispy_forms.bootstrap import Alert, FormActions, InlineRadios
|
|
from crispy_forms.helper import FormHelper
|
|
from crispy_forms.layout import (HTML, Button, Column, Div, Field, Fieldset,
|
|
Layout, Submit)
|
|
from django import forms
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
|
from django.core.files.base import File
|
|
from django.core.urlresolvers import reverse
|
|
from django.db import models, transaction
|
|
from django.db.models import Max
|
|
from django.forms import ModelChoiceField, ModelForm, widgets
|
|
from django.forms.forms import Form
|
|
from django.forms.models import ModelMultipleChoiceField
|
|
from django.forms.widgets import CheckboxSelectMultiple, HiddenInput, Select
|
|
from django.utils import timezone
|
|
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 sapl
|
|
from sapl.base.models import AppConfig, Autor, TipoAutor
|
|
from sapl.comissoes.models import Comissao
|
|
from sapl.compilacao.models import (STATUS_TA_IMMUTABLE_PUBLIC,
|
|
STATUS_TA_PRIVATE)
|
|
from sapl.crispy_layout_mixin import (SaplFormLayout, form_actions, to_column,
|
|
to_row)
|
|
from sapl.materia.models import (AssuntoMateria, Autoria, MateriaAssunto,
|
|
MateriaLegislativa, Orgao, RegimeTramitacao,
|
|
TipoDocumento, TipoProposicao)
|
|
from sapl.norma.models import (LegislacaoCitada, NormaJuridica,
|
|
TipoNormaJuridica)
|
|
from sapl.parlamentares.models import Legislatura
|
|
from sapl.protocoloadm.models import Protocolo
|
|
from sapl.settings import MAX_DOC_UPLOAD_SIZE
|
|
from sapl.utils import (RANGE_ANOS, YES_NO_CHOICES,
|
|
ChoiceWithoutValidationField,
|
|
MateriaPesquisaOrderingFilter, RangeWidgetOverride,
|
|
autor_label, autor_modal, gerar_hash_arquivo,
|
|
models_with_gr_for_model, qs_override_django_filter)
|
|
|
|
from .models import (AcompanhamentoMateria, Anexada, Autoria, DespachoInicial,
|
|
DocumentoAcessorio, Numeracao, Proposicao, Relatoria,
|
|
TipoMateriaLegislativa, Tramitacao, UnidadeTramitacao)
|
|
|
|
|
|
def ANO_CHOICES():
|
|
return [('', '---------')] + RANGE_ANOS
|
|
|
|
|
|
def em_tramitacao():
|
|
return [('', 'Tanto Faz'),
|
|
(1, 'Sim'),
|
|
(0, 'Não')]
|
|
|
|
|
|
class AdicionarVariasAutoriasFilterSet(django_filters.FilterSet):
|
|
|
|
class Meta:
|
|
model = Autor
|
|
fields = ['nome']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(AdicionarVariasAutoriasFilterSet, self).__init__(*args, **kwargs)
|
|
|
|
row1 = to_row([('nome', 12)])
|
|
|
|
self.form.helper = FormHelper()
|
|
self.form.helper.form_method = 'GET'
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(_('Filtrar Autores'),
|
|
row1, form_actions(label='Filtrar'))
|
|
)
|
|
|
|
|
|
class OrgaoForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = Orgao
|
|
fields = ['nome', 'sigla', 'unidade_deliberativa',
|
|
'endereco', 'telefone']
|
|
|
|
@transaction.atomic
|
|
def save(self, commit=True):
|
|
orgao = super(OrgaoForm, self).save(commit)
|
|
content_type = ContentType.objects.get_for_model(Orgao)
|
|
object_id = orgao.pk
|
|
tipo = TipoAutor.objects.get(descricao='Órgão')
|
|
nome = orgao.nome + ' - ' + orgao.sigla
|
|
Autor.objects.create(
|
|
content_type=content_type,
|
|
object_id=object_id,
|
|
tipo=tipo,
|
|
nome=nome
|
|
)
|
|
return orgao
|
|
|
|
|
|
class ReceberProposicaoForm(Form):
|
|
cod_hash = forms.CharField(label='Código do Documento', required=True)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
row1 = to_row([('cod_hash', 12)])
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
_('Incorporar Proposição'), row1,
|
|
form_actions(label='Buscar Proposição')
|
|
)
|
|
)
|
|
super(ReceberProposicaoForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
class MateriaSimplificadaForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
fields = ['tipo', 'numero', 'ano', 'data_apresentacao',
|
|
'numero_protocolo', 'regime_tramitacao',
|
|
'em_tramitacao', 'ementa', 'texto_original']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
row1 = to_row([('tipo', 6), ('numero', 3), ('ano', 3)])
|
|
row2 = to_row([('data_apresentacao', 6), ('numero_protocolo', 6)])
|
|
row3 = to_row([('regime_tramitacao', 6), ('em_tramitacao', 6)])
|
|
row4 = to_row([('ementa', 12)])
|
|
row5 = to_row([('texto_original', 12)])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
_('Formulário Simplificado'),
|
|
row1, row2, row3, row4, row5,
|
|
form_actions(label='Salvar')
|
|
)
|
|
)
|
|
super(MateriaSimplificadaForm, self).__init__(*args, **kwargs)
|
|
|
|
def clean(self):
|
|
super(MateriaSimplificadaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
data_apresentacao = cleaned_data['data_apresentacao']
|
|
ano = cleaned_data['ano']
|
|
|
|
if data_apresentacao.year != ano:
|
|
raise ValidationError("O ano da matéria não pode ser "
|
|
"diferente do ano na data de apresentação")
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class MateriaLegislativaForm(ModelForm):
|
|
|
|
autor = forms.ModelChoiceField(required=False,
|
|
empty_label='------',
|
|
queryset=Autor.objects.all()
|
|
)
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
exclude = ['texto_articulado', 'autores', 'proposicao',
|
|
'anexadas', 'data_ultima_atualizacao']
|
|
|
|
def clean(self):
|
|
super(MateriaLegislativaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
data_apresentacao = cleaned_data['data_apresentacao']
|
|
ano = cleaned_data['ano']
|
|
|
|
if data_apresentacao.year != ano:
|
|
raise ValidationError("O ano da matéria não pode ser "
|
|
"diferente do ano na data de apresentação")
|
|
|
|
ano_origem_externa = cleaned_data['ano_origem_externa']
|
|
data_origem_externa = cleaned_data['data_origem_externa']
|
|
|
|
if ano_origem_externa and data_origem_externa and \
|
|
ano_origem_externa != data_origem_externa.year:
|
|
raise ValidationError("O ano de origem externa da matéria não "
|
|
"pode ser diferente do ano na data de "
|
|
"origem externa")
|
|
|
|
return cleaned_data
|
|
|
|
def save(self, commit=False):
|
|
materia = super(MateriaLegislativaForm, self).save(commit)
|
|
materia.save()
|
|
|
|
if self.cleaned_data['autor']:
|
|
autoria = Autoria()
|
|
autoria.primeiro_autor = True
|
|
autoria.materia = materia
|
|
autoria.autor = self.cleaned_data['autor']
|
|
autoria.save()
|
|
|
|
return materia
|
|
|
|
class UnidadeTramitacaoForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = UnidadeTramitacao
|
|
fields = ['comissao', 'orgao', 'parlamentar']
|
|
|
|
def clean(self):
|
|
super(UnidadeTramitacaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
for key in list(cleaned_data.keys()):
|
|
if cleaned_data[key] is None:
|
|
del cleaned_data[key]
|
|
|
|
if len(cleaned_data) != 1:
|
|
msg = _('Somente um campo deve preenchido!')
|
|
raise ValidationError(msg)
|
|
return cleaned_data
|
|
|
|
|
|
class AcompanhamentoMateriaForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = AcompanhamentoMateria
|
|
fields = ['email']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
row1 = to_row([('email', 10)])
|
|
|
|
row1.append(
|
|
Column(form_actions(label='Cadastrar'), css_class='col-md-2')
|
|
)
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
_('Acompanhamento de Matéria por e-mail'), row1
|
|
)
|
|
)
|
|
super(AcompanhamentoMateriaForm, self).__init__(*args, **kwargs)
|
|
|
|
|
|
class DocumentoAcessorioForm(ModelForm):
|
|
data = forms.DateField(required=True)
|
|
|
|
class Meta:
|
|
model = DocumentoAcessorio
|
|
fields = ['tipo', 'nome', 'data', 'autor', 'ementa', 'arquivo']
|
|
|
|
|
|
class RelatoriaForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = Relatoria
|
|
fields = ['data_designacao_relator', 'comissao', 'parlamentar',
|
|
'data_destituicao_relator', 'tipo_fim_relatoria']
|
|
|
|
widgets = {'comissao': forms.Select(attrs={'disabled': 'disabled'})}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(RelatoriaForm, self).__init__(*args, **kwargs)
|
|
|
|
def clean(self):
|
|
super(RelatoriaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
try:
|
|
comissao = Comissao.objects.get(id=self.initial['comissao'])
|
|
except ObjectDoesNotExist:
|
|
msg = _('A localização atual deve ser uma comissão.')
|
|
raise ValidationError(msg)
|
|
else:
|
|
cleaned_data['comissao'] = comissao
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class TramitacaoForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = Tramitacao
|
|
fields = ['data_tramitacao',
|
|
'unidade_tramitacao_local',
|
|
'status',
|
|
'turno',
|
|
'urgente',
|
|
'unidade_tramitacao_destino',
|
|
'data_encaminhamento',
|
|
'data_fim_prazo',
|
|
'texto']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(TramitacaoForm, self).__init__(*args, **kwargs)
|
|
self.fields['data_tramitacao'].initial = timezone.now().date()
|
|
|
|
def clean(self):
|
|
super(TramitacaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
if 'data_encaminhamento' in cleaned_data:
|
|
data_enc_form = cleaned_data['data_encaminhamento']
|
|
if 'data_fim_prazo' in cleaned_data:
|
|
data_prazo_form = cleaned_data['data_fim_prazo']
|
|
if 'data_tramitacao' in cleaned_data:
|
|
data_tram_form = cleaned_data['data_tramitacao']
|
|
|
|
ultima_tramitacao = Tramitacao.objects.filter(
|
|
materia_id=self.instance.materia_id).exclude(
|
|
id=self.instance.id).order_by(
|
|
'-data_tramitacao',
|
|
'-id').first()
|
|
|
|
if not self.instance.data_tramitacao:
|
|
|
|
if ultima_tramitacao:
|
|
destino = ultima_tramitacao.unidade_tramitacao_destino
|
|
if (destino != self.cleaned_data['unidade_tramitacao_local']):
|
|
msg = _('A origem da nova tramitação deve ser igual ao '
|
|
'destino da última adicionada!')
|
|
raise ValidationError(msg)
|
|
|
|
if cleaned_data['data_tramitacao'] > timezone.now().date():
|
|
msg = _(
|
|
'A data de tramitação deve ser ' +
|
|
'menor ou igual a data de hoje!')
|
|
raise ValidationError(msg)
|
|
|
|
if (ultima_tramitacao and
|
|
data_tram_form < ultima_tramitacao.data_tramitacao):
|
|
msg = _('A data da nova tramitação deve ser ' +
|
|
'maior que a data da última tramitação!')
|
|
raise ValidationError(msg)
|
|
|
|
if data_enc_form:
|
|
if data_enc_form < data_tram_form:
|
|
msg = _('A data de encaminhamento deve ser ' +
|
|
'maior que a data de tramitação!')
|
|
raise ValidationError(msg)
|
|
|
|
if data_prazo_form:
|
|
if data_prazo_form < data_tram_form:
|
|
msg = _('A data fim de prazo deve ser ' +
|
|
'maior que a data de tramitação!')
|
|
raise ValidationError(msg)
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class TramitacaoUpdateForm(TramitacaoForm):
|
|
unidade_tramitacao_local = forms.ModelChoiceField(
|
|
queryset=UnidadeTramitacao.objects.all(),
|
|
widget=forms.HiddenInput())
|
|
|
|
data_tramitacao = forms.DateField(widget=forms.HiddenInput())
|
|
|
|
class Meta:
|
|
model = Tramitacao
|
|
fields = ['data_tramitacao',
|
|
'unidade_tramitacao_local',
|
|
'status',
|
|
'turno',
|
|
'urgente',
|
|
'unidade_tramitacao_destino',
|
|
'data_encaminhamento',
|
|
'data_fim_prazo',
|
|
'texto',
|
|
]
|
|
|
|
widgets = {
|
|
'data_encaminhamento': forms.DateInput(format='%d/%m/%Y'),
|
|
'data_fim_prazo': forms.DateInput(format='%d/%m/%Y'),
|
|
}
|
|
|
|
def clean(self):
|
|
super(TramitacaoUpdateForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
ultima_tramitacao = Tramitacao.objects.filter(
|
|
materia_id=self.instance.materia_id).order_by(
|
|
'-data_tramitacao',
|
|
'-id').first()
|
|
|
|
# Se a Tramitação que está sendo editada não for a mais recente,
|
|
# ela não pode ter seu destino alterado.
|
|
if ultima_tramitacao != self.instance:
|
|
if self.cleaned_data['unidade_tramitacao_destino'] != \
|
|
self.instance.unidade_tramitacao_destino:
|
|
raise ValidationError(
|
|
'Você não pode mudar a Unidade de Destino desta '
|
|
'tramitação, pois irá conflitar com a Unidade '
|
|
'Local da tramitação seguinte')
|
|
|
|
self.cleaned_data['data_tramitacao'] = \
|
|
self.instance.data_tramitacao
|
|
self.cleaned_data['unidade_tramitacao_local'] = \
|
|
self.instance.unidade_tramitacao_local
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
class LegislacaoCitadaForm(ModelForm):
|
|
|
|
tipo = forms.ModelChoiceField(
|
|
label=_('Tipo Norma'),
|
|
required=True,
|
|
queryset=TipoNormaJuridica.objects.all(),
|
|
empty_label='Selecione',
|
|
)
|
|
|
|
numero = forms.CharField(label='Número', required=True)
|
|
|
|
ano = forms.CharField(label='Ano', required=True)
|
|
|
|
class Meta:
|
|
model = LegislacaoCitada
|
|
fields = ['tipo',
|
|
'numero',
|
|
'ano',
|
|
'disposicoes',
|
|
'parte',
|
|
'livro',
|
|
'titulo',
|
|
'capitulo',
|
|
'secao',
|
|
'subsecao',
|
|
'artigo',
|
|
'paragrafo',
|
|
'inciso',
|
|
'alinea',
|
|
'item']
|
|
|
|
def clean(self):
|
|
super(LegislacaoCitadaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
try:
|
|
norma = NormaJuridica.objects.get(
|
|
numero=cleaned_data['numero'],
|
|
ano=cleaned_data['ano'],
|
|
tipo=cleaned_data['tipo'])
|
|
except ObjectDoesNotExist:
|
|
msg = _('A norma a ser inclusa não existe no cadastro'
|
|
' de Normas.')
|
|
raise ValidationError(msg)
|
|
else:
|
|
cleaned_data['norma'] = norma
|
|
|
|
filtro_base = LegislacaoCitada.objects.filter(
|
|
materia=self.instance.materia,
|
|
norma=self.cleaned_data['norma'],
|
|
disposicoes=self.cleaned_data['disposicoes'],
|
|
parte=self.cleaned_data['parte'],
|
|
livro=self.cleaned_data['livro'],
|
|
titulo=self.cleaned_data['titulo'],
|
|
capitulo=self.cleaned_data['capitulo'],
|
|
secao=self.cleaned_data['secao'],
|
|
subsecao=self.cleaned_data['subsecao'],
|
|
artigo=self.cleaned_data['artigo'],
|
|
paragrafo=self.cleaned_data['paragrafo'],
|
|
inciso=self.cleaned_data['inciso'],
|
|
alinea=self.cleaned_data['alinea'],
|
|
item=self.cleaned_data['item'])
|
|
|
|
if not self.instance.id:
|
|
if filtro_base.exists():
|
|
msg = _('Essa Legislação já foi cadastrada.')
|
|
raise ValidationError(msg)
|
|
else:
|
|
if filtro_base.exclude(id=self.instance.id).exists():
|
|
msg = _('Essa Legislação já foi cadastrada.')
|
|
raise ValidationError(msg)
|
|
return cleaned_data
|
|
|
|
def save(self, commit=False):
|
|
legislacao = super(LegislacaoCitadaForm, self).save(commit)
|
|
|
|
legislacao.norma = self.cleaned_data['norma']
|
|
legislacao.save()
|
|
return legislacao
|
|
|
|
|
|
class NumeracaoForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = Numeracao
|
|
fields = ['tipo_materia',
|
|
'numero_materia',
|
|
'ano_materia',
|
|
'data_materia']
|
|
|
|
def clean(self):
|
|
super(NumeracaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
try:
|
|
MateriaLegislativa.objects.get(
|
|
numero=self.cleaned_data['numero_materia'],
|
|
ano=self.cleaned_data['ano_materia'],
|
|
tipo=self.cleaned_data['tipo_materia'])
|
|
except ObjectDoesNotExist:
|
|
msg = _('A matéria a ser inclusa não existe no cadastro'
|
|
' de matérias legislativas.')
|
|
raise ValidationError(msg)
|
|
|
|
if Numeracao.objects.filter(
|
|
materia=self.instance.materia,
|
|
tipo_materia=self.cleaned_data['tipo_materia'],
|
|
ano_materia=self.cleaned_data['ano_materia'],
|
|
numero_materia=self.cleaned_data['numero_materia']
|
|
).exists():
|
|
msg = _('Essa numeração já foi cadastrada.')
|
|
raise ValidationError(msg)
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
class AnexadaForm(ModelForm):
|
|
|
|
tipo = forms.ModelChoiceField(
|
|
label='Tipo',
|
|
required=True,
|
|
queryset=TipoMateriaLegislativa.objects.all(),
|
|
empty_label='Selecione',
|
|
)
|
|
|
|
numero = forms.CharField(label='Número', required=True)
|
|
|
|
ano = forms.CharField(label='Ano', required=True)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
return super(AnexadaForm, self).__init__(*args, **kwargs)
|
|
|
|
def clean(self):
|
|
super(AnexadaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
try:
|
|
materia_anexada = MateriaLegislativa.objects.get(
|
|
numero=cleaned_data['numero'],
|
|
ano=cleaned_data['ano'],
|
|
tipo=cleaned_data['tipo'])
|
|
except ObjectDoesNotExist:
|
|
msg = _('A matéria a ser anexada não existe no cadastro'
|
|
' de matérias legislativas.')
|
|
raise ValidationError(msg)
|
|
else:
|
|
cleaned_data['materia_anexada'] = materia_anexada
|
|
|
|
return cleaned_data
|
|
|
|
def save(self, commit=False):
|
|
anexada = super(AnexadaForm, self).save(commit)
|
|
anexada.materia_anexada = self.cleaned_data['materia_anexada']
|
|
anexada.save()
|
|
return anexada
|
|
|
|
class Meta:
|
|
model = Anexada
|
|
fields = ['tipo', 'numero', 'ano', 'data_anexacao', 'data_desanexacao']
|
|
|
|
|
|
class MateriaLegislativaFilterSet(django_filters.FilterSet):
|
|
|
|
filter_overrides = {models.DateField: {
|
|
'filter_class': django_filters.DateFromToRangeFilter,
|
|
'extra': lambda f: {
|
|
'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
|
|
'widget': RangeWidgetOverride}
|
|
}}
|
|
|
|
ano = django_filters.ChoiceFilter(required=False,
|
|
label='Ano da Matéria',
|
|
choices=ANO_CHOICES)
|
|
|
|
autoria__autor = django_filters.CharFilter(widget=forms.HiddenInput())
|
|
|
|
autoria__primeiro_autor = django_filters.BooleanFilter(
|
|
required=False,
|
|
label='Primeiro Autor',
|
|
widget=forms.HiddenInput())
|
|
|
|
ementa = django_filters.CharFilter(lookup_expr='icontains')
|
|
|
|
em_tramitacao = django_filters.ChoiceFilter(required=False,
|
|
label='Em tramitação',
|
|
choices=em_tramitacao)
|
|
|
|
materiaassunto__assunto = django_filters.ModelChoiceFilter(
|
|
queryset=AssuntoMateria.objects.all(),
|
|
label=_('Assunto da Matéria'))
|
|
|
|
numeracao__numero_materia = django_filters.NumberFilter(
|
|
required=False,
|
|
label=_('Número do Processo'))
|
|
|
|
o = MateriaPesquisaOrderingFilter()
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
fields = ['numero',
|
|
'numero_protocolo',
|
|
'numeracao__numero_materia',
|
|
'ano',
|
|
'tipo',
|
|
'data_apresentacao',
|
|
'data_publicacao',
|
|
'autoria__autor__tipo',
|
|
'autoria__primeiro_autor',
|
|
# FIXME 'autoria__autor__partido',
|
|
'relatoria__parlamentar_id',
|
|
'local_origem_externa',
|
|
'tramitacao__unidade_tramitacao_destino',
|
|
'tramitacao__status',
|
|
'materiaassunto__assunto',
|
|
'em_tramitacao',
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(MateriaLegislativaFilterSet, self).__init__(*args, **kwargs)
|
|
|
|
self.filters['tipo'].label = 'Tipo de Matéria'
|
|
self.filters['autoria__autor__tipo'].label = 'Tipo de Autor'
|
|
# self.filters['autoria__autor__partido'].label = 'Partido do Autor'
|
|
self.filters['relatoria__parlamentar_id'].label = 'Relatoria'
|
|
|
|
row1 = to_row(
|
|
[('tipo', 12)])
|
|
row2 = to_row(
|
|
[('numero', 3),
|
|
('numeracao__numero_materia', 3),
|
|
('numero_protocolo', 3),
|
|
('ano', 3)])
|
|
row3 = to_row(
|
|
[('data_apresentacao', 6),
|
|
('data_publicacao', 6)])
|
|
row4 = to_row(
|
|
[('autoria__autor', 0),
|
|
('autoria__primeiro_autor', 0),
|
|
(Button('pesquisar',
|
|
'Pesquisar Autor',
|
|
css_class='btn btn-primary btn-sm'), 2),
|
|
(Button('limpar',
|
|
'limpar Autor',
|
|
css_class='btn btn-primary btn-sm'), 10)])
|
|
row5 = to_row(
|
|
[('autoria__autor__tipo', 12),
|
|
# ('autoria__autor__partido', 6)
|
|
])
|
|
row6 = to_row(
|
|
[('relatoria__parlamentar_id', 6),
|
|
('local_origem_externa', 6)])
|
|
row7 = to_row(
|
|
[('tramitacao__unidade_tramitacao_destino', 6),
|
|
('tramitacao__status', 6)])
|
|
row8 = to_row(
|
|
[('em_tramitacao', 6),
|
|
('o', 6)])
|
|
row9 = to_row(
|
|
[('materiaassunto__assunto', 12)])
|
|
row10 = to_row(
|
|
[('ementa', 12)])
|
|
|
|
self.form.helper = FormHelper()
|
|
self.form.helper.form_method = 'GET'
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(_('Pesquisa de Matéria'),
|
|
row1, row2, row3,
|
|
HTML(autor_label),
|
|
HTML(autor_modal),
|
|
row4, row5, row6, row7, row8, row9, row10,
|
|
form_actions(label='Pesquisar'))
|
|
)
|
|
|
|
@property
|
|
def qs(self):
|
|
return qs_override_django_filter(self)
|
|
|
|
|
|
def pega_ultima_tramitacao():
|
|
ultimas_tramitacoes = Tramitacao.objects.values(
|
|
'materia_id').annotate(data_encaminhamento=Max(
|
|
'data_encaminhamento'),
|
|
id=Max('id')).values_list('id')
|
|
|
|
lista = [item for sublist in ultimas_tramitacoes for item in sublist]
|
|
|
|
return lista
|
|
|
|
|
|
def filtra_tramitacao_status(status):
|
|
lista = pega_ultima_tramitacao()
|
|
return Tramitacao.objects.filter(
|
|
id__in=lista,
|
|
status=status).distinct().values_list('materia_id', flat=True)
|
|
|
|
|
|
def filtra_tramitacao_destino(destino):
|
|
lista = pega_ultima_tramitacao()
|
|
return Tramitacao.objects.filter(
|
|
id__in=lista,
|
|
unidade_tramitacao_destino=destino).distinct().values_list(
|
|
'materia_id', flat=True)
|
|
|
|
|
|
def filtra_tramitacao_destino_and_status(status, destino):
|
|
lista = pega_ultima_tramitacao()
|
|
return Tramitacao.objects.filter(
|
|
id__in=lista,
|
|
status=status,
|
|
unidade_tramitacao_destino=destino).distinct().values_list(
|
|
'materia_id', flat=True)
|
|
|
|
|
|
class DespachoInicialForm(ModelForm):
|
|
comissao = forms.ModelChoiceField(
|
|
queryset=Comissao.objects.filter(ativa=True))
|
|
|
|
class Meta:
|
|
model = DespachoInicial
|
|
fields = ['comissao']
|
|
|
|
def clean(self):
|
|
super(DespachoInicialForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
if DespachoInicial.objects.filter(
|
|
materia=self.instance.materia,
|
|
comissao=self.cleaned_data['comissao'],
|
|
).exists():
|
|
msg = _('Esse Despacho já foi cadastrado.')
|
|
raise ValidationError(msg)
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
class AutoriaForm(ModelForm):
|
|
|
|
tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
|
|
required=False,
|
|
queryset=TipoAutor.objects.all(),
|
|
empty_label=_('Selecione'),)
|
|
|
|
data_relativa = forms.DateField(
|
|
widget=forms.HiddenInput(), required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(AutoriaForm, self).__init__(*args, **kwargs)
|
|
|
|
row1 = to_row([('tipo_autor', 4),
|
|
('autor', 4),
|
|
('primeiro_autor', 4)])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(_('Autoria'),
|
|
row1, 'data_relativa', form_actions(label='Salvar')))
|
|
|
|
if not kwargs['instance']:
|
|
self.fields['autor'].choices = []
|
|
|
|
class Meta:
|
|
model = Autoria
|
|
fields = ['tipo_autor', 'autor', 'primeiro_autor', 'data_relativa']
|
|
|
|
def clean(self):
|
|
cd = super(AutoriaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
autorias = Autoria.objects.filter(
|
|
materia=self.instance.materia, autor=cd['autor'])
|
|
pk = self.instance.pk
|
|
|
|
if ((not pk and autorias.exists()) or
|
|
(pk and autorias.exclude(pk=pk).exists())):
|
|
raise ValidationError(_('Esse Autor já foi cadastrado.'))
|
|
|
|
return cd
|
|
|
|
|
|
class AutoriaMultiCreateForm(Form):
|
|
|
|
tipo_autor = ModelChoiceField(label=_('Tipo Autor'),
|
|
required=False,
|
|
queryset=TipoAutor.objects.all(),
|
|
empty_label=_('Selecione'),)
|
|
|
|
data_relativa = forms.DateField(
|
|
widget=forms.HiddenInput(), required=False)
|
|
|
|
autor = ModelMultipleChoiceField(
|
|
queryset=Autor.objects.all(),
|
|
label=_('Possiveis Autores'),
|
|
required=False,
|
|
widget=CheckboxSelectMultiple)
|
|
|
|
autores = ModelMultipleChoiceField(
|
|
queryset=Autor.objects.all(),
|
|
required=False,
|
|
widget=HiddenInput)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
row1 = to_row([('tipo_autor', 12), ])
|
|
|
|
row2 = to_row([('autor', 12), ])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
_('Autorias'), row1, row2, 'data_relativa', 'autores',
|
|
form_actions(label='Incluir Autores Selecionados')))
|
|
|
|
self.fields['autor'].choices = []
|
|
|
|
def clean(self):
|
|
cd = super().clean()
|
|
|
|
if 'autores' in self.errors:
|
|
del self.errors['autores']
|
|
|
|
if 'autor' not in cd or not cd['autor'].exists():
|
|
raise ValidationError(
|
|
_('Ao menos um autor deve ser selecionado para inclusão'))
|
|
|
|
return cd
|
|
|
|
|
|
class AcessorioEmLoteFilterSet(django_filters.FilterSet):
|
|
|
|
filter_overrides = {models.DateField: {
|
|
'filter_class': django_filters.DateFromToRangeFilter,
|
|
'extra': lambda f: {
|
|
'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
|
|
'widget': RangeWidgetOverride}
|
|
}}
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
fields = ['tipo', 'data_apresentacao']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(AcessorioEmLoteFilterSet, self).__init__(*args, **kwargs)
|
|
|
|
self.filters['tipo'].label = 'Tipo de Matéria'
|
|
self.filters['data_apresentacao'].label = 'Data (Inicial - Final)'
|
|
self.form.fields['tipo'].required = True
|
|
self.form.fields['data_apresentacao'].required = True
|
|
|
|
row1 = to_row([('tipo', 12)])
|
|
row2 = to_row([('data_apresentacao', 12)])
|
|
|
|
self.form.helper = FormHelper()
|
|
self.form.helper.form_method = 'GET'
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(_('Documentos Acessórios em Lote'),
|
|
row1, row2, form_actions(label='Pesquisar')))
|
|
|
|
|
|
class PrimeiraTramitacaoEmLoteFilterSet(django_filters.FilterSet):
|
|
|
|
filter_overrides = {models.DateField: {
|
|
'filter_class': django_filters.DateFromToRangeFilter,
|
|
'extra': lambda f: {
|
|
'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
|
|
'widget': RangeWidgetOverride}
|
|
}}
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
fields = ['tipo', 'data_apresentacao']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(PrimeiraTramitacaoEmLoteFilterSet, self).__init__(
|
|
*args, **kwargs)
|
|
|
|
self.filters['tipo'].label = 'Tipo de Matéria'
|
|
self.filters['data_apresentacao'].label = 'Data (Inicial - Final)'
|
|
self.form.fields['tipo'].required = True
|
|
self.form.fields['data_apresentacao'].required = False
|
|
|
|
row1 = to_row([('tipo', 12)])
|
|
row2 = to_row([('data_apresentacao', 12)])
|
|
|
|
self.form.helper = FormHelper()
|
|
self.form.helper.form_method = 'GET'
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(_('Primeira Tramitação'),
|
|
row1, row2, form_actions(label='Pesquisar')))
|
|
|
|
|
|
class TramitacaoEmLoteFilterSet(django_filters.FilterSet):
|
|
|
|
filter_overrides = {models.DateField: {
|
|
'filter_class': django_filters.DateFromToRangeFilter,
|
|
'extra': lambda f: {
|
|
'label': '%s (%s)' % (f.verbose_name, _('Inicial - Final')),
|
|
'widget': RangeWidgetOverride}
|
|
}}
|
|
|
|
class Meta:
|
|
model = MateriaLegislativa
|
|
fields = ['tipo', 'data_apresentacao', 'tramitacao__status',
|
|
'tramitacao__unidade_tramitacao_destino']
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(TramitacaoEmLoteFilterSet, self).__init__(
|
|
*args, **kwargs)
|
|
|
|
self.filters['tipo'].label = 'Tipo de Matéria'
|
|
self.filters['data_apresentacao'].label = 'Data (Inicial - Final)'
|
|
self.filters['tramitacao__unidade_tramitacao_destino'
|
|
].label = 'Unidade Destino (Último Destino)'
|
|
self.form.fields['tipo'].required = True
|
|
self.form.fields['data_apresentacao'].required = False
|
|
self.form.fields['tramitacao__status'].required = True
|
|
self.form.fields[
|
|
'tramitacao__unidade_tramitacao_destino'].required = True
|
|
|
|
row1 = to_row([
|
|
('tipo', 4),
|
|
('tramitacao__unidade_tramitacao_destino', 4),
|
|
('tramitacao__status', 4)])
|
|
row2 = to_row([('data_apresentacao', 12)])
|
|
|
|
self.form.helper = FormHelper()
|
|
self.form.helper.form_method = 'GET'
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(_('Tramitação em Lote'),
|
|
row1, row2, form_actions(label='Pesquisar')))
|
|
|
|
|
|
class TipoProposicaoForm(ModelForm):
|
|
|
|
content_type = forms.ModelChoiceField(
|
|
queryset=ContentType.objects.all(),
|
|
label=TipoProposicao._meta.get_field('content_type').verbose_name,
|
|
required=True)
|
|
|
|
tipo_conteudo_related_radio = ChoiceWithoutValidationField(
|
|
label="Seleção de Tipo",
|
|
required=False,
|
|
widget=forms.RadioSelect())
|
|
|
|
tipo_conteudo_related = forms.IntegerField(
|
|
widget=forms.HiddenInput(),
|
|
required=True)
|
|
|
|
class Meta:
|
|
model = TipoProposicao
|
|
fields = ['descricao',
|
|
'content_type',
|
|
'tipo_conteudo_related_radio',
|
|
'tipo_conteudo_related',
|
|
'perfis']
|
|
|
|
widgets = {'tipo_conteudo_related': forms.HiddenInput(),
|
|
'perfis': widgets.CheckboxSelectMultiple()}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
tipo_select = Fieldset(TipoProposicao._meta.verbose_name,
|
|
Div(to_column(('descricao', 5)),
|
|
to_column(('content_type', 7)),
|
|
css_class='clearfix'),
|
|
to_column(('tipo_conteudo_related_radio', 6)),
|
|
|
|
to_column(('perfis', 6)))
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = SaplFormLayout(tipo_select)
|
|
|
|
super(TipoProposicaoForm, self).__init__(*args, **kwargs)
|
|
|
|
content_types = ContentType.objects.get_for_models(
|
|
*models_with_gr_for_model(TipoProposicao))
|
|
|
|
self.fields['content_type'].choices = [
|
|
(ct.pk, ct) for k, ct in content_types.items()]
|
|
self.fields['content_type'].choices.sort(key=lambda x: str(x[1]))
|
|
|
|
if self.instance.pk:
|
|
self.fields[
|
|
'tipo_conteudo_related'].initial = self.instance.object_id
|
|
|
|
def clean(self):
|
|
super(TipoProposicaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cd = self.cleaned_data
|
|
|
|
content_type = cd['content_type']
|
|
|
|
if 'tipo_conteudo_related' not in cd or not cd[
|
|
'tipo_conteudo_related']:
|
|
raise ValidationError(
|
|
_('Seleção de Tipo não definida'))
|
|
|
|
if not content_type.model_class().objects.filter(
|
|
pk=cd['tipo_conteudo_related']).exists():
|
|
raise ValidationError(
|
|
_('O Registro definido (%s) não está na base de %s.'
|
|
) % (cd['tipo_conteudo_related'], content_type))
|
|
|
|
"""
|
|
A unicidade de tipo proposição para tipo de conteudo
|
|
foi desabilitada pois existem casos em quem é o procedimento da
|
|
instituição convergir vários tipos de proposição
|
|
para um tipo de matéria.
|
|
|
|
unique_value = self._meta.model.objects.filter(
|
|
content_type=content_type, object_id=cd['tipo_conteudo_related'])
|
|
|
|
if self.instance.pk:
|
|
unique_value = unique_value.exclude(pk=self.instance.pk)
|
|
|
|
unique_value = unique_value.first()
|
|
|
|
if unique_value:
|
|
raise ValidationError(
|
|
_('Já existe um Tipo de Proposição (%s) '
|
|
'que foi defindo como (%s) para (%s)'
|
|
) % (unique_value,
|
|
content_type,
|
|
unique_value.tipo_conteudo_related))"""
|
|
|
|
return self.cleaned_data
|
|
|
|
@transaction.atomic
|
|
def save(self, commit=False):
|
|
|
|
tipo_proposicao = self.instance
|
|
|
|
assert tipo_proposicao.content_type
|
|
|
|
tipo_proposicao.tipo_conteudo_related = \
|
|
tipo_proposicao.content_type.model_class(
|
|
).objects.get(pk=self.cleaned_data['tipo_conteudo_related'])
|
|
|
|
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="{}"{} data-has-perfil={}>{}</option>',
|
|
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 = [
|
|
('D', _('Arquivo Digital')),
|
|
('T', _('Texto Articulado'))
|
|
]
|
|
|
|
tipo_materia = forms.ModelChoiceField(
|
|
label=TipoMateriaLegislativa._meta.verbose_name,
|
|
required=False,
|
|
queryset=TipoMateriaLegislativa.objects.all(),
|
|
empty_label='Selecione')
|
|
|
|
numero_materia = forms.CharField(
|
|
label='Número', required=False)
|
|
|
|
ano_materia = forms.CharField(
|
|
label='Ano', required=False)
|
|
|
|
tipo_texto = forms.ChoiceField(
|
|
label=_('Tipo do Texto da Proposição'),
|
|
required=False,
|
|
choices=TIPO_TEXTO_CHOICE,
|
|
widget=widgets.RadioSelect())
|
|
|
|
materia_de_vinculo = forms.ModelChoiceField(
|
|
queryset=MateriaLegislativa.objects.all(),
|
|
widget=widgets.HiddenInput(),
|
|
required=False)
|
|
|
|
receber_recibo = forms.TypedChoiceField(
|
|
choices=YES_NO_CHOICES,
|
|
widget=widgets.HiddenInput(),
|
|
required=False)
|
|
|
|
class Meta:
|
|
model = Proposicao
|
|
fields = ['tipo',
|
|
'receber_recibo',
|
|
'descricao',
|
|
'texto_original',
|
|
'materia_de_vinculo',
|
|
|
|
'tipo_materia',
|
|
'numero_materia',
|
|
'ano_materia',
|
|
'tipo_texto',
|
|
'hash_code']
|
|
|
|
widgets = {
|
|
'descricao': widgets.Textarea(attrs={'rows': 4}),
|
|
'tipo': TipoProposicaoSelect(),
|
|
'hash_code': forms.HiddenInput(), }
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.texto_articulado_proposicao = sapl.base.models.AppConfig.attr(
|
|
'texto_articulado_proposicao')
|
|
|
|
self.receber_recibo = sapl.base.models.AppConfig.attr(
|
|
'receber_recibo_proposicao')
|
|
|
|
if not self.texto_articulado_proposicao:
|
|
if 'tipo_texto' in self._meta.fields:
|
|
self._meta.fields.remove('tipo_texto')
|
|
else:
|
|
if 'tipo_texto' not in self._meta.fields:
|
|
self._meta.fields.append('tipo_texto')
|
|
|
|
fields = [
|
|
to_column((Fieldset(
|
|
TipoProposicao._meta.verbose_name, Field('tipo')), 12)),
|
|
to_column(
|
|
(Alert('teste',
|
|
css_class="ementa_materia hidden alert-info",
|
|
dismiss=False), 12)),
|
|
to_column(('descricao', 12)),
|
|
|
|
]
|
|
|
|
if self.texto_articulado_proposicao:
|
|
fields.append(
|
|
to_column((InlineRadios('tipo_texto'), 5)),)
|
|
|
|
fields.append(to_column((
|
|
'texto_original', 7 if self.texto_articulado_proposicao else 12)))
|
|
|
|
fields.append(to_column((Fieldset(_('Outras informações - Vincular a Matéria Legislativa Existente'),
|
|
to_column(('tipo_materia', 12)),
|
|
to_column(('numero_materia', 6)),
|
|
to_column(('ano_materia', 6))
|
|
), 12)),
|
|
)
|
|
self.helper = FormHelper()
|
|
self.helper.layout = SaplFormLayout(*fields)
|
|
|
|
super(ProposicaoForm, self).__init__(*args, **kwargs)
|
|
|
|
if self.instance.pk:
|
|
self.fields['tipo_texto'].initial = ''
|
|
if self.instance.texto_original:
|
|
self.fields['tipo_texto'].initial = 'D'
|
|
if self.texto_articulado_proposicao:
|
|
if self.instance.texto_articulado.exists():
|
|
self.fields['tipo_texto'].initial = 'T'
|
|
|
|
if self.instance.materia_de_vinculo:
|
|
self.fields[
|
|
'tipo_materia'
|
|
].initial = self.instance.materia_de_vinculo.tipo
|
|
self.fields[
|
|
'numero_materia'
|
|
].initial = self.instance.materia_de_vinculo.numero
|
|
self.fields[
|
|
'ano_materia'
|
|
].initial = self.instance.materia_de_vinculo.ano
|
|
|
|
def clean_texto_original(self):
|
|
texto_original = self.cleaned_data.get('texto_original', False)
|
|
if texto_original:
|
|
if texto_original.size > MAX_DOC_UPLOAD_SIZE:
|
|
max_size = str(MAX_DOC_UPLOAD_SIZE / (1024 * 1024))
|
|
raise ValidationError(
|
|
"Arquivo muito grande. ( > {0}MB )".format(max_size))
|
|
return texto_original
|
|
|
|
def gerar_hash(self, inst, receber_recibo):
|
|
|
|
inst.save()
|
|
if receber_recibo == True:
|
|
inst.hash_code = ''
|
|
else:
|
|
if inst.texto_original:
|
|
inst.hash_code = gerar_hash_arquivo(
|
|
inst.texto_original.path, str(inst.pk))
|
|
elif inst.texto_articulado.exists():
|
|
ta = inst.texto_articulado.first()
|
|
# FIXME hash para textos articulados
|
|
inst.hash_code = 'P' + ta.hash() + '/' + str(inst.pk)
|
|
|
|
def clean(self):
|
|
super(ProposicaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cd = self.cleaned_data
|
|
|
|
tm, am, nm = (cd.get('tipo_materia', ''),
|
|
cd.get('ano_materia', ''),
|
|
cd.get('numero_materia', ''))
|
|
|
|
if tm and am and nm:
|
|
try:
|
|
materia_de_vinculo = MateriaLegislativa.objects.get(
|
|
tipo_id=tm,
|
|
ano=am,
|
|
numero=nm
|
|
)
|
|
except ObjectDoesNotExist:
|
|
raise ValidationError(_('Matéria Vinculada não existe!'))
|
|
else:
|
|
cd['materia_de_vinculo'] = materia_de_vinculo
|
|
return cd
|
|
|
|
def save(self, commit=True):
|
|
cd = self.cleaned_data
|
|
inst = self.instance
|
|
receber_recibo = AppConfig.objects.last().receber_recibo_proposicao
|
|
|
|
if inst.pk:
|
|
if 'tipo_texto' in cd:
|
|
|
|
if cd['tipo_texto'] == 'T' and inst.texto_original:
|
|
inst.texto_original.delete()
|
|
|
|
elif cd['tipo_texto'] != 'T':
|
|
inst.texto_articulado.all().delete()
|
|
|
|
if 'texto_original' in cd and\
|
|
not cd['texto_original'] and \
|
|
inst.texto_original:
|
|
inst.texto_original.delete()
|
|
self.gerar_hash(inst, receber_recibo)
|
|
|
|
|
|
return super().save(commit)
|
|
|
|
inst.ano = timezone.now().year
|
|
numero__max = Proposicao.objects.filter(
|
|
autor=inst.autor,
|
|
ano=timezone.now().year).aggregate(Max('numero_proposicao'))
|
|
numero__max = numero__max['numero_proposicao__max']
|
|
inst.numero_proposicao = (
|
|
numero__max + 1) if numero__max else 1
|
|
|
|
self.gerar_hash(inst, receber_recibo)
|
|
|
|
inst.save()
|
|
|
|
return inst
|
|
|
|
|
|
class DevolverProposicaoForm(forms.ModelForm):
|
|
|
|
justificativa_devolucao = forms.CharField(
|
|
required=False, widget=widgets.Textarea(attrs={'rows': 5}))
|
|
|
|
class Meta:
|
|
model = Proposicao
|
|
fields = [
|
|
'justificativa_devolucao',
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
# esta chamada isola o __init__ de ProposicaoForm
|
|
super(DevolverProposicaoForm, self).__init__(*args, **kwargs)
|
|
fields = []
|
|
|
|
fields.append(
|
|
Fieldset(
|
|
_('Registro de Devolução'),
|
|
to_column(('justificativa_devolucao', 12)),
|
|
to_column(
|
|
(form_actions(label=_('Devolver'),
|
|
name='devolver',
|
|
css_class='btn-danger pull-right'), 12)
|
|
)
|
|
)
|
|
)
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(*fields)
|
|
|
|
def clean(self):
|
|
super(DevolverProposicaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cd = self.cleaned_data
|
|
|
|
if 'justificativa_devolucao' not in cd or\
|
|
not cd['justificativa_devolucao']:
|
|
# TODO Implementar notificação ao autor por email
|
|
raise ValidationError(
|
|
_('Adicione uma Justificativa para devolução.'))
|
|
return cd
|
|
|
|
@transaction.atomic
|
|
def save(self, commit=False):
|
|
cd = self.cleaned_data
|
|
|
|
self.instance.data_devolucao = timezone.now()
|
|
self.instance.data_recebimento = None
|
|
self.instance.data_envio = None
|
|
self.instance.save()
|
|
|
|
if self.instance.texto_articulado.exists():
|
|
ta = self.instance.texto_articulado.first()
|
|
ta.privacidade = STATUS_TA_PRIVATE
|
|
ta.editing_locked = False
|
|
ta.save()
|
|
|
|
self.instance.results = {
|
|
'messages': {
|
|
'success': [_('Devolução efetuada com sucesso.'), ]
|
|
},
|
|
'url': reverse('sapl.materia:receber-proposicao')
|
|
}
|
|
return self.instance
|
|
|
|
|
|
class ConfirmarProposicaoForm(ProposicaoForm):
|
|
|
|
tipo_readonly = forms.CharField(
|
|
label=TipoProposicao._meta.verbose_name,
|
|
required=False, widget=widgets.TextInput(
|
|
attrs={'readonly': 'readonly'}))
|
|
|
|
autor_readonly = forms.CharField(
|
|
label=Autor._meta.verbose_name,
|
|
required=False, widget=widgets.TextInput(
|
|
attrs={'readonly': 'readonly'}))
|
|
|
|
regime_tramitacao = forms.ModelChoiceField(
|
|
required=False, queryset=RegimeTramitacao.objects.all())
|
|
|
|
gerar_protocolo = forms.ChoiceField(
|
|
required=False,
|
|
label=_(
|
|
'Gerar Protocolo na incorporação?'),
|
|
choices=YES_NO_CHOICES,
|
|
widget=widgets.RadioSelect())
|
|
|
|
numero_de_paginas = forms.IntegerField(required=False, min_value=0,
|
|
label=_('Número de Páginas'),)
|
|
|
|
class Meta:
|
|
model = Proposicao
|
|
fields = [
|
|
'data_envio',
|
|
'descricao',
|
|
'gerar_protocolo',
|
|
'numero_de_paginas'
|
|
]
|
|
widgets = {
|
|
'descricao': widgets.Textarea(
|
|
attrs={'readonly': 'readonly', 'rows': 4}),
|
|
'data_envio': widgets.DateTimeInput(
|
|
attrs={'readonly': 'readonly'}),
|
|
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
self.proposicao_incorporacao_obrigatoria = \
|
|
sapl.base.models.AppConfig.attr(
|
|
'proposicao_incorporacao_obrigatoria')
|
|
|
|
if self.proposicao_incorporacao_obrigatoria != 'C':
|
|
if 'gerar_protocolo' in self._meta.fields:
|
|
self._meta.fields.remove('gerar_protocolo')
|
|
else:
|
|
if 'gerar_protocolo' not in self._meta.fields:
|
|
self._meta.fields.append('gerar_protocolo')
|
|
|
|
if self.proposicao_incorporacao_obrigatoria == 'N':
|
|
if 'numero_de_paginas' in self._meta.fields:
|
|
self._meta.fields.remove('numero_de_paginas')
|
|
else:
|
|
if 'numero_de_paginas' not in self._meta.fields:
|
|
self._meta.fields.append('numero_de_paginas')
|
|
|
|
self.instance = kwargs.get('instance', None)
|
|
if not self.instance:
|
|
raise ValueError(_('Erro na Busca por proposição a incorporar'))
|
|
|
|
if self.instance.tipo.content_type.model_class() == TipoDocumento:
|
|
if 'numero_de_paginas' in self._meta.fields:
|
|
self._meta.fields.remove('numero_de_paginas')
|
|
if 'gerar_protocolo' in self._meta.fields:
|
|
self._meta.fields.remove('gerar_protocolo')
|
|
if 'regime_tramitacao' in self._meta.fields:
|
|
self._meta.fields.remove('regime_tramitacao')
|
|
|
|
# esta chamada isola o __init__ de ProposicaoForm
|
|
super(ProposicaoForm, self).__init__(*args, **kwargs)
|
|
|
|
fields = [
|
|
Fieldset(
|
|
_('Dados Básicos'),
|
|
to_column(('tipo_readonly', 4)),
|
|
to_column(('data_envio', 3)),
|
|
to_column(('autor_readonly', 5)),
|
|
to_column(('descricao', 12)))]
|
|
|
|
fields.append(
|
|
Fieldset(_('Vinculado a Matéria Legislativa'),
|
|
to_column(('tipo_materia', 3)),
|
|
to_column(('numero_materia', 2)),
|
|
to_column(('ano_materia', 2)),
|
|
to_column(
|
|
(Alert(_('O responsável pela incorporação pode '
|
|
'alterar a anexação. Limpar os campos '
|
|
'de Vinculação gera um %s independente '
|
|
'sem anexação se for possível para esta '
|
|
'Proposição. Não sendo, a rotina de incorporação '
|
|
'não permitirá estes campos serem vazios.'
|
|
) % self.instance.tipo.content_type,
|
|
css_class="alert-info",
|
|
dismiss=False), 5)),
|
|
to_column(
|
|
(Alert('',
|
|
css_class="ementa_materia hidden alert-info",
|
|
dismiss=False), 12))))
|
|
|
|
itens_incorporacao = []
|
|
if self.instance.tipo.content_type.model_class() == \
|
|
TipoMateriaLegislativa:
|
|
itens_incorporacao = [to_column(('regime_tramitacao', 4))]
|
|
|
|
if self.proposicao_incorporacao_obrigatoria == 'C':
|
|
itens_incorporacao.append(to_column((InlineRadios(
|
|
'gerar_protocolo'), 4)))
|
|
|
|
if self.proposicao_incorporacao_obrigatoria != 'N':
|
|
itens_incorporacao.append(to_column(('numero_de_paginas', 4)))
|
|
|
|
itens_incorporacao.append(
|
|
to_column(
|
|
(form_actions(label=_('Incorporar'),
|
|
name='incorporar'), 12)
|
|
)
|
|
)
|
|
|
|
fields.append(
|
|
Fieldset(_('Registro de Incorporação'), *itens_incorporacao))
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(*fields)
|
|
|
|
self.fields['tipo_readonly'].initial = self.instance.tipo.descricao
|
|
self.fields['autor_readonly'].initial = str(self.instance.autor)
|
|
|
|
if self.instance.materia_de_vinculo:
|
|
self.fields[
|
|
'tipo_materia'
|
|
].initial = self.instance.materia_de_vinculo.tipo
|
|
self.fields[
|
|
'numero_materia'
|
|
].initial = self.instance.materia_de_vinculo.numero
|
|
self.fields[
|
|
'ano_materia'
|
|
].initial = self.instance.materia_de_vinculo.ano
|
|
|
|
if self.proposicao_incorporacao_obrigatoria == 'C':
|
|
self.fields['gerar_protocolo'].initial = True
|
|
|
|
def clean(self):
|
|
super(ConfirmarProposicaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
numeracao = sapl.base.models.AppConfig.attr('sequencia_numeracao')
|
|
|
|
if not numeracao:
|
|
raise ValidationError("A sequência de numeração (por ano ou geral)"
|
|
" não foi configurada para a aplicação em "
|
|
"tabelas auxiliares")
|
|
|
|
cd = ProposicaoForm.clean(self)
|
|
|
|
if self.instance.tipo.content_type.model_class() ==\
|
|
TipoMateriaLegislativa:
|
|
if 'regime_tramitacao' not in cd or\
|
|
not cd['regime_tramitacao']:
|
|
raise ValidationError(
|
|
_('Regime de Tramitação deve ser informado.'))
|
|
|
|
elif self.instance.tipo.content_type.model_class(
|
|
) == TipoDocumento and not cd['materia_de_vinculo']:
|
|
|
|
raise ValidationError(
|
|
_('Documentos não podem ser incorporados sem definir '
|
|
'para qual Matéria Legislativa ele se destina.'))
|
|
|
|
return cd
|
|
|
|
@transaction.atomic
|
|
def save(self, commit=False):
|
|
# TODO Implementar workflow entre protocolo e autores
|
|
cd = self.cleaned_data
|
|
|
|
self.instance.justificativa_devolucao = ''
|
|
self.instance.data_devolucao = None
|
|
self.instance.data_recebimento = timezone.now()
|
|
self.instance.materia_de_vinculo = cd['materia_de_vinculo']
|
|
|
|
if self.instance.texto_articulado.exists():
|
|
ta = self.instance.texto_articulado.first()
|
|
ta.privacidade = STATUS_TA_IMMUTABLE_PUBLIC
|
|
ta.editing_locked = True
|
|
ta.save()
|
|
|
|
self.instance.save()
|
|
|
|
"""
|
|
TipoProposicao possui conteúdo genérico para a modelegam de tipos
|
|
relacionados e, a esta modelagem, qual o objeto que está associado.
|
|
Porem, cada registro a ser gerado pode possuir uma estrutura diferente,
|
|
é os casos básicos já implementados,
|
|
TipoDocumento e TipoMateriaLegislativa, que são modelos utilizados
|
|
em DocumentoAcessorio e MateriaLegislativa geradas,
|
|
por sua vez a partir de uma Proposição.
|
|
Portanto para estas duas e para outras implementações que possam surgir
|
|
possuindo com matéria prima uma Proposição, dada sua estrutura,
|
|
deverá contar também com uma implementação particular aqui no código
|
|
abaixo.
|
|
"""
|
|
self.instance.results = {
|
|
'messages': {
|
|
'success': [_('Proposição incorporada com sucesso'), ]
|
|
},
|
|
'url': reverse('sapl.materia:receber-proposicao')
|
|
}
|
|
proposicao = self.instance
|
|
conteudo_gerado = None
|
|
|
|
if self.instance.tipo.content_type.model_class(
|
|
) == TipoMateriaLegislativa:
|
|
|
|
numeracao = None
|
|
try:
|
|
numeracao = sapl.base.models.AppConfig.objects.last(
|
|
).sequencia_numeracao
|
|
except AttributeError:
|
|
pass
|
|
|
|
tipo = self.instance.tipo.tipo_conteudo_related
|
|
if tipo.sequencia_numeracao:
|
|
numeracao = tipo.sequencia_numeracao
|
|
ano = timezone.now().year
|
|
if numeracao == 'A':
|
|
numero = MateriaLegislativa.objects.filter(
|
|
ano=ano, tipo=tipo).aggregate(Max('numero'))
|
|
elif numeracao == 'L':
|
|
legislatura = Legislatura.objects.filter(
|
|
data_inicio__year__lte=ano,
|
|
data_fim__year__gte=ano).first()
|
|
data_inicio = legislatura.data_inicio
|
|
data_fim = legislatura.data_fim
|
|
numero = MateriaLegislativa.objects.filter(
|
|
data_apresentacao__gte=data_inicio,
|
|
data_apresentacao__lte=data_fim,
|
|
tipo=tipo).aggregate(
|
|
Max('numero'))
|
|
elif numeracao == 'U':
|
|
numero = MateriaLegislativa.objects.filter(tipo=tipo).aggregate(Max('numero'))
|
|
|
|
if numeracao is None:
|
|
numero['numero__max'] = 0
|
|
|
|
max_numero = numero['numero__max'] + 1 if numero['numero__max'] else 1
|
|
|
|
# dados básicos
|
|
materia = MateriaLegislativa()
|
|
materia.numero = max_numero
|
|
materia.tipo = tipo
|
|
materia.ementa = proposicao.descricao
|
|
materia.ano = ano
|
|
materia.data_apresentacao = timezone.now()
|
|
materia.em_tramitacao = True
|
|
materia.regime_tramitacao = cd['regime_tramitacao']
|
|
|
|
if proposicao.texto_original:
|
|
materia.texto_original = File(
|
|
proposicao.texto_original,
|
|
os.path.basename(proposicao.texto_original.path))
|
|
|
|
materia.save()
|
|
conteudo_gerado = materia
|
|
|
|
if proposicao.texto_articulado.exists():
|
|
ta = proposicao.texto_articulado.first()
|
|
ta_materia = ta.clone_for(materia)
|
|
ta_materia.editing_locked = True
|
|
ta_materia.privacidade = STATUS_TA_IMMUTABLE_PUBLIC
|
|
ta_materia.save()
|
|
|
|
self.instance.results['messages']['success'].append(_(
|
|
'Matéria Legislativa registrada com sucesso (%s)'
|
|
) % str(materia))
|
|
|
|
# autoria
|
|
autoria = Autoria()
|
|
autoria.autor = proposicao.autor
|
|
autoria.materia = materia
|
|
autoria.primeiro_autor = True
|
|
autoria.save()
|
|
|
|
self.instance.results['messages']['success'].append(_(
|
|
'Autoria registrada para (%s)'
|
|
) % str(autoria.autor))
|
|
|
|
# Matéria de vinlculo
|
|
if proposicao.materia_de_vinculo:
|
|
anexada = Anexada()
|
|
anexada.materia_principal = proposicao.materia_de_vinculo
|
|
anexada.materia_anexada = materia
|
|
anexada.data_anexacao = timezone.now()
|
|
anexada.save()
|
|
|
|
self.instance.results['messages']['success'].append(_(
|
|
'Matéria anexada a (%s)'
|
|
) % str(anexada.materia_principal))
|
|
|
|
self.instance.results['url'] = reverse(
|
|
'sapl.materia:materialegislativa_detail',
|
|
kwargs={'pk': materia.pk})
|
|
|
|
elif self.instance.tipo.content_type.model_class() == TipoDocumento:
|
|
|
|
# dados básicos
|
|
doc = DocumentoAcessorio()
|
|
doc.materia = proposicao.materia_de_vinculo
|
|
doc.autor = str(proposicao.autor)
|
|
doc.tipo = proposicao.tipo.tipo_conteudo_related
|
|
|
|
doc.ementa = proposicao.descricao
|
|
""" FIXME verificar questão de nome e data de documento,
|
|
doc acessório. Possivelmente pode possuir data anterior a
|
|
data de envio e/ou recebimento dada a incorporação.
|
|
"""
|
|
doc.nome = str(proposicao.tipo.tipo_conteudo_related)[:30]
|
|
doc.data = proposicao.data_envio
|
|
|
|
doc.arquivo = proposicao.texto_original = File(
|
|
proposicao.texto_original,
|
|
os.path.basename(proposicao.texto_original.path))
|
|
doc.save()
|
|
conteudo_gerado = doc
|
|
|
|
self.instance.results['messages']['success'].append(_(
|
|
'Documento Acessório registrado com sucesso e anexado (%s)'
|
|
) % str(doc.materia))
|
|
|
|
self.instance.results['url'] = reverse(
|
|
'sapl.materia:documentoacessorio_detail',
|
|
kwargs={'pk': doc.pk})
|
|
|
|
proposicao.conteudo_gerado_related = conteudo_gerado
|
|
proposicao.save()
|
|
|
|
if self.instance.tipo.content_type.model_class() == TipoDocumento:
|
|
return self.instance
|
|
|
|
# Nunca gerar protocolo
|
|
if self.proposicao_incorporacao_obrigatoria == 'N':
|
|
return self.instance
|
|
|
|
# ocorre se proposicao_incorporacao_obrigatoria == 'C' (condicional)
|
|
# and gerar_protocolo == False
|
|
if 'gerar_protocolo' not in cd or cd['gerar_protocolo'] == 'False':
|
|
return self.instance
|
|
|
|
# resta a opção proposicao_incorporacao_obrigatoria == 'C'
|
|
# and gerar_protocolo == True
|
|
# ou, proposicao_incorporacao_obrigatoria == 'O'
|
|
# que são idênticas.
|
|
|
|
"""
|
|
apesar de TipoProposicao estar com conteudo e tipo conteudo genérico,
|
|
aqui na incorporação de proposições, para gerar protocolo, cada caso
|
|
possível de conteudo em tipo de proposição deverá ser tratado
|
|
isoladamente justamente por Protocolo não estar generalizado com
|
|
GenericForeignKey
|
|
"""
|
|
|
|
numeracao = sapl.base.models.AppConfig.attr('sequencia_numeracao')
|
|
if numeracao == 'A':
|
|
nm = Protocolo.objects.filter(
|
|
ano=timezone.now().year).aggregate(Max('numero'))
|
|
elif numeracao == 'U':
|
|
nm = Protocolo.objects.all().aggregate(Max('numero'))
|
|
|
|
protocolo = Protocolo()
|
|
protocolo.numero = (nm['numero__max'] + 1) if nm['numero__max'] else 1
|
|
protocolo.ano = timezone.now().year
|
|
protocolo.data = timezone.now()
|
|
protocolo.hora = timezone.now().time()
|
|
|
|
# TODO transformar campo timestamp em auto_now_add
|
|
protocolo.timestamp = timezone.now()
|
|
protocolo.tipo_protocolo = '1'
|
|
|
|
protocolo.interessado = str(proposicao.autor)
|
|
protocolo.autor = proposicao.autor
|
|
protocolo.assunto_ementa = proposicao.descricao
|
|
protocolo.numero_paginas = cd['numero_de_paginas']
|
|
protocolo.anulado = False
|
|
|
|
if self.instance.tipo.content_type.model_class(
|
|
) == TipoMateriaLegislativa:
|
|
protocolo.tipo_materia = proposicao.tipo.tipo_conteudo_related
|
|
protocolo.tipo_processo = '1'
|
|
elif self.instance.tipo.content_type.model_class() == TipoDocumento:
|
|
protocolo.tipo_documento = proposicao.tipo.tipo_conteudo_related
|
|
protocolo.tipo_processo = '0'
|
|
|
|
protocolo.save()
|
|
|
|
self.instance.results['messages']['success'].append(_(
|
|
'Protocolo realizado com sucesso'))
|
|
|
|
# FIXME qdo protocoloadm estiver homologado, verifique a necessidade
|
|
# de redirecionamento para o protocolo.
|
|
# complete e libere código abaixo para tal.
|
|
|
|
"""
|
|
self.instance.results['url'] = reverse(
|
|
'sapl.protocoloadm:...',
|
|
kwargs={'pk': protocolo.pk})
|
|
"""
|
|
conteudo_gerado.numero_protocolo = protocolo.numero
|
|
conteudo_gerado.save()
|
|
|
|
return self.instance
|
|
|
|
|
|
class MateriaAssuntoForm(ModelForm):
|
|
|
|
class Meta:
|
|
model = MateriaAssunto
|
|
fields = ['materia', 'assunto']
|
|
|
|
widgets = {'materia': forms.HiddenInput()}
|
|
|
|
|
|
class EtiquetaPesquisaForm(forms.Form):
|
|
tipo_materia = forms.ModelChoiceField(
|
|
label=TipoMateriaLegislativa._meta.verbose_name,
|
|
queryset=TipoMateriaLegislativa.objects.all(),
|
|
required=False,
|
|
empty_label='Selecione')
|
|
|
|
data_inicial = forms.DateField(
|
|
label='Data Inicial',
|
|
required=False,
|
|
widget=forms.DateInput(format='%d/%m/%Y')
|
|
)
|
|
|
|
data_final = forms.DateField(
|
|
label='Data Final',
|
|
required=False,
|
|
widget=forms.DateInput(format='%d/%m/%Y')
|
|
)
|
|
|
|
processo_inicial = forms.IntegerField(
|
|
label='Processo Inicial',
|
|
required=False)
|
|
|
|
processo_final = forms.IntegerField(
|
|
label='Processo Final',
|
|
required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(EtiquetaPesquisaForm, self).__init__(*args, **kwargs)
|
|
|
|
row1 = to_row(
|
|
[('tipo_materia', 6),
|
|
('data_inicial', 3),
|
|
('data_final', 3)])
|
|
|
|
row2 = to_row(
|
|
[('processo_inicial', 6),
|
|
('processo_final', 6)])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
('Formulário de Etiqueta'),
|
|
row1, row2,
|
|
form_actions(label='Pesquisar')
|
|
)
|
|
)
|
|
|
|
def clean(self):
|
|
super(EtiquetaPesquisaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
# Verifica se algum campo de data foi preenchido
|
|
if cleaned_data['data_inicial'] or cleaned_data['data_final']:
|
|
# Então verifica se o usuário preencheu o Incial e mas não
|
|
# preencheu o Final, ou vice-versa
|
|
if (not cleaned_data['data_inicial'] or
|
|
not cleaned_data['data_final']):
|
|
raise ValidationError(_(
|
|
'Caso pesquise por data, os campos de Data Incial e ' +
|
|
'Data Final devem ser preenchidos obrigatoriamente'))
|
|
# Caso tenha preenchido, verifica se a data final é maior que
|
|
# a inicial
|
|
elif cleaned_data['data_final'] < cleaned_data['data_inicial']:
|
|
raise ValidationError(_(
|
|
'A Data Final não pode ser menor que a Data Inicial'))
|
|
|
|
# O mesmo processo anterior é feito com o processo
|
|
if (cleaned_data['processo_inicial'] or
|
|
cleaned_data['processo_final']):
|
|
if (not cleaned_data['processo_inicial'] or
|
|
not cleaned_data['processo_final']):
|
|
raise ValidationError(_(
|
|
'Caso pesquise por número de processo, os campos de ' +
|
|
'Processo Inicial e Processo Final ' +
|
|
'devem ser preenchidos obrigatoriamente'))
|
|
elif (cleaned_data['processo_final'] <
|
|
cleaned_data['processo_inicial']):
|
|
raise ValidationError(_(
|
|
'O processo final não pode ser menor que o inicial'))
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class FichaPesquisaForm(forms.Form):
|
|
tipo_materia = forms.ModelChoiceField(
|
|
label=TipoMateriaLegislativa._meta.verbose_name,
|
|
queryset=TipoMateriaLegislativa.objects.all(),
|
|
empty_label='Selecione')
|
|
|
|
data_inicial = forms.DateField(
|
|
label='Data Inicial',
|
|
widget=forms.DateInput(format='%d/%m/%Y')
|
|
)
|
|
|
|
data_final = forms.DateField(
|
|
label='Data Final',
|
|
widget=forms.DateInput(format='%d/%m/%Y')
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(FichaPesquisaForm, self).__init__(*args, **kwargs)
|
|
|
|
row1 = to_row(
|
|
[('tipo_materia', 6),
|
|
('data_inicial', 3),
|
|
('data_final', 3)])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
('Formulário de Ficha'),
|
|
row1,
|
|
form_actions(label='Pesquisar')
|
|
)
|
|
)
|
|
|
|
def clean(self):
|
|
super(FichaPesquisaForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
cleaned_data = self.cleaned_data
|
|
|
|
if not self.is_valid():
|
|
return cleaned_data
|
|
|
|
if cleaned_data['data_final'] < cleaned_data['data_inicial']:
|
|
raise ValidationError(_(
|
|
'A Data Final não pode ser menor que a Data Inicial'))
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class FichaSelecionaForm(forms.Form):
|
|
materia = forms.ModelChoiceField(
|
|
widget=forms.RadioSelect,
|
|
queryset=MateriaLegislativa.objects.all(),
|
|
label='')
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(FichaSelecionaForm, self).__init__(*args, **kwargs)
|
|
|
|
row1 = to_row(
|
|
[('materia', 12)])
|
|
|
|
self.helper = FormHelper()
|
|
self.helper.layout = Layout(
|
|
Fieldset(
|
|
('Selecione a ficha que deseja imprimir'),
|
|
row1,
|
|
form_actions(label='Gerar Impresso')
|
|
)
|
|
)
|
|
|