Sistema de Apoio ao Processo Legislativo
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.
 
 
 
 
 

233 lines
8.0 KiB

from datetime import date, timedelta
from django import forms
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models import Q
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from floppyforms.widgets import ClearableFileInput
from .models import (ComposicaoColigacao, Filiacao, Frente, Legislatura,
Mandato, Parlamentar)
class ImageThumbnailFileInput(ClearableFileInput):
template_name = 'floppyforms/image_thumbnail.html'
def validar_datas_legislatura(eleicao, inicio, fim, pk=None):
# Verifica se data de eleição < inicio < fim
if inicio >= fim or eleicao >= inicio:
msg_error = _('A data início deve ser menor que a ' +
'data fim, e a data eleição deve ser ' +
'menor que a data início')
return [False, msg_error]
# Verifica se há alguma data cadastrada no intervalo de tempo desejado
if Legislatura.objects.filter(
data_inicio__range=[inicio, fim]).exclude(pk=pk).exists()\
or Legislatura.objects.filter(
data_fim__range=[inicio, fim]).exclude(pk=pk).exists():
msg_error = _('Já existe uma legislatura neste intervalo de datas')
return [False, msg_error]
# Verifica se há alguma outra data de eleição cadastrada
if Legislatura.objects.filter(
data_eleicao=eleicao).exclude(pk=pk).exists():
msg_error = _('Esta data de eleição já foi cadastrada')
return [False, msg_error]
return [True, '']
class LegislaturaForm(ModelForm):
class Meta:
model = Legislatura
exclude = []
class LegislaturaCreateForm(LegislaturaForm):
def clean(self):
cleaned_data = self.cleaned_data
eleicao = cleaned_data['data_eleicao']
inicio = cleaned_data['data_inicio']
fim = cleaned_data['data_fim']
valida_datas = validar_datas_legislatura(eleicao, inicio, fim)
if not valida_datas[0]:
raise ValidationError(valida_datas[1])
return cleaned_data
class LegislaturaUpdateForm(LegislaturaCreateForm):
def clean(self):
cleaned_data = super(LegislaturaCreateForm, self).clean()
eleicao = cleaned_data['data_eleicao']
inicio = cleaned_data['data_inicio']
fim = cleaned_data['data_fim']
valida_datas = validar_datas_legislatura(
eleicao, inicio, fim, pk=self.instance.pk)
if not valida_datas[0]:
raise ValidationError(valida_datas[1])
return cleaned_data
class ParlamentarForm(ModelForm):
class Meta:
model = Parlamentar
exclude = []
widgets = {'fotografia': ImageThumbnailFileInput,
'biografia': forms.Textarea(
attrs={'id': 'texto-rico'})}
class ParlamentarCreateForm(ParlamentarForm):
legislatura = forms.ModelChoiceField(
label=_('Legislatura'),
required=True,
queryset=Legislatura.objects.all().order_by('-data_inicio'),
empty_label='----------',
)
data_expedicao_diploma = forms.DateField(
label=_('Expedição do Diploma'),
required=True,
)
@transaction.atomic
def save(self, commit=True):
parlamentar = super(ParlamentarCreateForm, self).save(commit)
legislatura = self.cleaned_data['legislatura']
Mandato.objects.create(
parlamentar=parlamentar,
legislatura=legislatura,
data_fim_mandato=legislatura.data_fim,
data_expedicao_diploma=self.cleaned_data['data_expedicao_diploma'])
return parlamentar
def validar_datas(data_filiacao, data_desfiliacao, parlamentar, filiacao):
# Verifica se data de desfiliacao é anterior a data de filiacao
if data_desfiliacao and data_desfiliacao < data_filiacao:
error_msg = _("A data de desfiliação não pode anterior \
à data de filiação")
return [False, error_msg]
filiacoes = parlamentar.filiacao_set.order_by('data')
if not filiacoes.exists():
return [True, '']
# data ficticia de desfiliacao
df_desfiliacao = data_desfiliacao if data_desfiliacao else date.today()
# se não puder haver filiação no mesmo dia de desfiliação, basta
# retirar os timedelta abaixo
range_livre_exigido = Q(
data__range=[data_filiacao + timedelta(days=1),
df_desfiliacao - timedelta(days=1)]) | Q(
data_desfiliacao__range=[data_filiacao + timedelta(days=1),
df_desfiliacao - timedelta(days=1)])
filiacao_em_edicao_id = filiacao.pk
error_msg = None
# filiação em edição não é a última e está sem data de desfiliação
if not data_desfiliacao and filiacao_em_edicao_id and\
filiacao_em_edicao_id != filiacoes.last().pk:
error_msg = _("Data de desfiliação do parlamentar não pode ser\
ausente, se existirem datas de filiação posteriores.")
# a filiação que está sendo inclusa não tem data de desfiliação mas
# já existe outra sem data de desfiliação
elif not data_desfiliacao and not filiacao_em_edicao_id and\
not filiacoes.last().data_desfiliacao:
error_msg = _("O parlamentar não pode se filiar a novo partido sem\
antes se desfiliar do partido anterior.")
if not error_msg:
# se a filiação é uma edição, a exclui das possibilidades
if filiacao_em_edicao_id:
filiacoes = filiacoes.exclude(pk=filiacao_em_edicao_id)
# testa a intercessão de intervalo com outra filiação
if filiacoes.filter(range_livre_exigido).exists():
error_msg = _("A data de filiação e desfiliação não podem estar\
no intervalo de outro período de filiação.")
if not error_msg:
# passou pelo teste de intervalo mas a data de filiação é maior que
# a ultima que está em aberto
if filiacoes.filter(data_desfiliacao__isnull=True,
data__lte=data_filiacao).exists():
error_msg = _("Não pode haver um registro de filiação com data de \
filiação igual ou superior a data de filiação em aberto.")
if error_msg:
return [False, error_msg]
return [True, '']
class FiliacaoForm(ModelForm):
class Meta:
model = Filiacao
fields = ['partido',
'data',
'data_desfiliacao']
def clean(self):
if self.errors:
return self.errors
filiacao = super(FiliacaoForm, self).save(commit=False)
validacao = validar_datas(self.cleaned_data['data'],
self.cleaned_data['data_desfiliacao'],
filiacao.parlamentar,
filiacao)
if not validacao[0]:
raise ValidationError(validacao[1])
return self.cleaned_data
class ComposicaoColigacaoForm(ModelForm):
class Meta:
model = ComposicaoColigacao
fields = ['partido']
def clean(self):
cleaned_data = self.cleaned_data
pk = self.initial['coligacao_id']
if (ComposicaoColigacao.objects.filter(
coligacao_id=pk,
partido=cleaned_data.get('partido')).exists()):
msg = _('Esse partido já foi cadastrado nesta coligação.')
raise ValidationError(msg)
else:
if self.errors:
return self.errors
return self.cleaned_data
class FrenteForm(ModelForm):
def __init__(self, *args, **kwargs):
super(FrenteForm, self).__init__(*args, **kwargs)
self.fields['parlamentares'].queryset = Parlamentar.objects.filter(
ativo=True).order_by('nome_completo')
self.fields['parlamentares'].label = _('Parlamentares \
(Mantenha CTRL pressionado para selecionar vários)')
class Meta:
model = Frente
fields = '__all__'