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.
624 lines
22 KiB
624 lines
22 KiB
import logging
|
|
|
|
import django_filters
|
|
from crispy_forms.layout import Fieldset, Layout
|
|
from django import forms
|
|
from django.contrib.contenttypes.models import ContentType
|
|
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 import timezone
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from sapl.base.models import Autor, TipoAutor
|
|
from sapl.comissoes.models import (Comissao, Composicao, DocumentoAcessorio,
|
|
Participacao, Periodo, Reuniao)
|
|
from sapl.crispy_layout_mixin import SaplFormHelper, form_actions, to_row
|
|
from sapl.materia.models import MateriaEmTramitacao, PautaReuniao
|
|
from sapl.parlamentares.models import Legislatura, Mandato, Parlamentar
|
|
from sapl.utils import (FileFieldCheckMixin, FilterOverridesMetaMixin,
|
|
validar_arquivo)
|
|
|
|
|
|
class ComposicaoForm(forms.ModelForm):
|
|
comissao = forms.CharField(
|
|
required=False, label="Comissao", widget=forms.HiddenInput()
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Meta:
|
|
model = Composicao
|
|
exclude = []
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(ComposicaoForm, self).__init__(**kwargs)
|
|
self.fields["comissao"].widget.attrs["disabled"] = "disabled"
|
|
|
|
def clean(self):
|
|
data = super().clean()
|
|
data["comissao"] = self.initial["comissao"]
|
|
comissao_pk = self.initial["comissao"].id
|
|
|
|
if not self.is_valid():
|
|
return data
|
|
|
|
periodo = data["periodo"]
|
|
|
|
if periodo.data_fim:
|
|
intersecao_periodo = Composicao.objects.filter(
|
|
Q(
|
|
periodo__data_inicio__lte=periodo.data_fim,
|
|
periodo__data_fim__gte=periodo.data_fim,
|
|
)
|
|
| Q(
|
|
periodo__data_inicio__gte=periodo.data_inicio,
|
|
periodo__data_fim__lte=periodo.data_inicio,
|
|
),
|
|
comissao_id=comissao_pk,
|
|
)
|
|
else:
|
|
intersecao_periodo = Composicao.objects.filter(
|
|
Q(
|
|
periodo__data_inicio__gte=periodo.data_inicio,
|
|
periodo__data_fim__lte=periodo.data_inicio,
|
|
),
|
|
comissao_id=comissao_pk,
|
|
)
|
|
|
|
if intersecao_periodo:
|
|
if periodo.data_fim:
|
|
self.logger.warning(
|
|
"O período informado ({} a {}) choca com períodos já cadastrados para esta comissão".format(
|
|
periodo.data_inicio, periodo.data_fim
|
|
)
|
|
)
|
|
else:
|
|
self.logger.warning(
|
|
"O período informado ({} - ) choca com períodos já cadastrados para esta comissão".format(
|
|
periodo.data_inicio
|
|
)
|
|
)
|
|
raise ValidationError(
|
|
"O período informado choca com períodos já cadastrados para esta comissão"
|
|
)
|
|
|
|
return data
|
|
|
|
|
|
class PeriodoForm(forms.ModelForm):
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Meta:
|
|
model = Periodo
|
|
exclude = []
|
|
|
|
def clean(self):
|
|
cleaned_data = super(PeriodoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return cleaned_data
|
|
|
|
data_inicio = cleaned_data["data_inicio"]
|
|
data_fim = cleaned_data["data_fim"]
|
|
|
|
if data_fim and data_fim < data_inicio:
|
|
self.logger.warning(
|
|
"A Data Final ({}) é menor que "
|
|
"a Data Inicial({}).".format(data_fim, data_inicio)
|
|
)
|
|
raise ValidationError(
|
|
"A Data Final não pode ser menor que " "a Data Inicial"
|
|
)
|
|
|
|
# Evita NoneType exception se não preenchida a data_fim
|
|
if not data_fim:
|
|
data_fim = data_inicio
|
|
|
|
legislatura = Legislatura.objects.filter(
|
|
data_inicio__lte=data_inicio,
|
|
data_fim__gte=data_fim,
|
|
)
|
|
|
|
if not legislatura:
|
|
self.logger.warning(
|
|
"O período informado ({} a {})"
|
|
"não está contido em uma única "
|
|
"legislatura existente".format(data_inicio, data_fim)
|
|
)
|
|
raise ValidationError(
|
|
"O período informado "
|
|
"deve estar contido em uma única "
|
|
"legislatura existente"
|
|
)
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class ParticipacaoCreateForm(forms.ModelForm):
|
|
logger = logging.getLogger(__name__)
|
|
parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput())
|
|
|
|
class Meta:
|
|
model = Participacao
|
|
fields = "__all__"
|
|
exclude = ["composicao"]
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(ParticipacaoCreateForm, self).__init__(**kwargs)
|
|
|
|
if self.instance:
|
|
comissao = kwargs["initial"]
|
|
comissao_pk = int(comissao["parent_pk"])
|
|
composicao = Composicao.objects.get(id=comissao_pk)
|
|
participantes = composicao.participacao_set.all()
|
|
id_part = [p.parlamentar.id for p in participantes]
|
|
else:
|
|
id_part = []
|
|
|
|
qs = self.create_participacao()
|
|
|
|
parlamentares = (
|
|
Mandato.objects.filter(qs, parlamentar__ativo=True)
|
|
.prefetch_related("parlamentar")
|
|
.values_list("parlamentar", flat=True)
|
|
.distinct()
|
|
)
|
|
qs = (
|
|
Parlamentar.objects.filter(id__in=parlamentares)
|
|
.distinct()
|
|
.exclude(id__in=id_part)
|
|
)
|
|
eligible = self.verifica()
|
|
result = list(set(qs) & set(eligible))
|
|
if result == eligible:
|
|
self.fields["parlamentar"].queryset = qs
|
|
else:
|
|
ids = [e.id for e in eligible]
|
|
qs = Parlamentar.objects.filter(id__in=ids)
|
|
self.fields["parlamentar"].queryset = qs
|
|
|
|
def clean(self):
|
|
cleaned_data = super(ParticipacaoCreateForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return cleaned_data
|
|
|
|
data_designacao = cleaned_data["data_designacao"]
|
|
data_desligamento = cleaned_data["data_desligamento"]
|
|
|
|
if data_desligamento and data_designacao > data_desligamento:
|
|
self.logger.warning(
|
|
"Data de designação ({}) superior "
|
|
"à data de desligamento ({})".format(data_designacao, data_desligamento)
|
|
)
|
|
raise ValidationError(
|
|
_("Data de designação não pode ser superior " "à data de desligamento")
|
|
)
|
|
|
|
composicao = Composicao.objects.get(id=self.initial["parent_pk"])
|
|
cargos_unicos = [
|
|
c.cargo.nome for c in composicao.participacao_set.filter(cargo__unico=True)
|
|
]
|
|
|
|
if cleaned_data["cargo"].nome in cargos_unicos:
|
|
msg = _("Este cargo é único para esta Comissão.")
|
|
self.logger.warning(
|
|
"Este cargo ({}) é único para esta Comissão.".format(
|
|
cleaned_data["cargo"].nome
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
return cleaned_data
|
|
|
|
def create_participacao(self):
|
|
composicao = Composicao.objects.get(id=self.initial["parent_pk"])
|
|
data_inicio_comissao = composicao.periodo.data_inicio
|
|
data_fim_comissao = (
|
|
composicao.periodo.data_fim
|
|
if composicao.periodo.data_fim
|
|
else timezone.now()
|
|
)
|
|
q1 = Q(
|
|
data_fim_mandato__isnull=False, data_fim_mandato__gte=data_inicio_comissao
|
|
)
|
|
q2 = Q(data_inicio_mandato__gte=data_inicio_comissao) & Q(
|
|
data_inicio_mandato__lte=data_fim_comissao
|
|
)
|
|
q3 = Q(
|
|
data_fim_mandato__isnull=True, data_inicio_mandato__lte=data_inicio_comissao
|
|
)
|
|
qs = q1 | q2 | q3
|
|
return qs
|
|
|
|
def verifica(self):
|
|
composicao = Composicao.objects.get(id=self.initial["parent_pk"])
|
|
participantes = composicao.participacao_set.all()
|
|
participantes_id = [p.parlamentar.id for p in participantes]
|
|
parlamentares = (
|
|
Parlamentar.objects.all()
|
|
.exclude(id__in=participantes_id)
|
|
.order_by("nome_completo")
|
|
)
|
|
parlamentares = [p for p in parlamentares if p.ativo]
|
|
|
|
lista = []
|
|
|
|
for p in parlamentares:
|
|
mandatos = p.mandato_set.all()
|
|
for m in mandatos:
|
|
data_inicio = m.data_inicio_mandato
|
|
data_fim = m.data_fim_mandato
|
|
comp_data_inicio = composicao.periodo.data_inicio
|
|
comp_data_fim = composicao.periodo.data_fim
|
|
if (
|
|
(data_fim and data_fim >= comp_data_inicio)
|
|
or (
|
|
data_inicio >= comp_data_inicio and data_inicio <= comp_data_fim
|
|
)
|
|
or (data_fim is None and data_inicio <= comp_data_inicio)
|
|
):
|
|
lista.append(p)
|
|
|
|
lista = list(set(lista))
|
|
|
|
return lista
|
|
|
|
|
|
class ParticipacaoEditForm(forms.ModelForm):
|
|
logger = logging.getLogger(__name__)
|
|
parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput())
|
|
nome_parlamentar = forms.CharField(required=False, label="Parlamentar")
|
|
|
|
class Meta:
|
|
model = Participacao
|
|
fields = [
|
|
"nome_parlamentar",
|
|
"parlamentar",
|
|
"cargo",
|
|
"titular",
|
|
"data_designacao",
|
|
"data_desligamento",
|
|
"motivo_desligamento",
|
|
"observacao",
|
|
]
|
|
widgets = {
|
|
"parlamentar": forms.HiddenInput(),
|
|
}
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(ParticipacaoEditForm, self).__init__(**kwargs)
|
|
self.initial["nome_parlamentar"] = Parlamentar.objects.get(
|
|
id=self.initial["parlamentar"]
|
|
).nome_parlamentar
|
|
self.fields["nome_parlamentar"].widget.attrs["disabled"] = "disabled"
|
|
|
|
def clean(self):
|
|
cleaned_data = super(ParticipacaoEditForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return cleaned_data
|
|
|
|
data_designacao = cleaned_data["data_designacao"]
|
|
data_desligamento = cleaned_data["data_desligamento"]
|
|
|
|
if data_desligamento and data_designacao > data_desligamento:
|
|
self.logger.warning(
|
|
"Data de designação ({}) superior "
|
|
"à data de desligamento ({})".format(data_designacao, data_desligamento)
|
|
)
|
|
raise ValidationError(
|
|
_("Data de designação não pode ser superior " "à data de desligamento")
|
|
)
|
|
|
|
composicao_id = self.instance.composicao_id
|
|
|
|
composicao = Composicao.objects.get(id=composicao_id)
|
|
cargos_unicos = [
|
|
c.cargo.nome
|
|
for c in composicao.participacao_set.filter(cargo__unico=True).exclude(
|
|
id=self.instance.pk
|
|
)
|
|
]
|
|
|
|
if cleaned_data["cargo"].nome in cargos_unicos:
|
|
msg = _("Este cargo é único para esta Comissão.")
|
|
self.logger.warning(
|
|
"Este cargo ({}) é único para esta Comissão (id={}).".format(
|
|
cleaned_data["cargo"].nome, composicao_id
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class ComissaoForm(forms.ModelForm):
|
|
logger = logging.getLogger(__name__)
|
|
|
|
class Meta:
|
|
model = Comissao
|
|
fields = "__all__"
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(ComissaoForm, self).__init__(**kwargs)
|
|
inst = self.instance
|
|
if inst.pk:
|
|
if inst.tipo.natureza == "P":
|
|
self.fields["apelido_temp"].widget.attrs["disabled"] = "disabled"
|
|
self.fields["data_instalacao_temp"].widget.attrs[
|
|
"disabled"
|
|
] = "disabled"
|
|
self.fields["data_final_prevista_temp"].widget.attrs[
|
|
"disabled"
|
|
] = "disabled"
|
|
self.fields["data_prorrogada_temp"].widget.attrs[
|
|
"disabled"
|
|
] = "disabled"
|
|
self.fields["data_fim_comissao"].widget.attrs["disabled"] = "disabled"
|
|
|
|
def clean(self):
|
|
super(ComissaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
if len(self.cleaned_data["nome"]) > 100:
|
|
msg = _(
|
|
"Nome da Comissão informado ({}) tem mais de 50 caracteres.".format(
|
|
self.cleaned_data["nome"]
|
|
)
|
|
)
|
|
self.logger.warning("Nome da Comissão deve ter no máximo 50 caracteres.")
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_extincao"]
|
|
and self.cleaned_data["data_extincao"] < self.cleaned_data["data_criacao"]
|
|
):
|
|
msg = _("Data de extinção não pode ser menor que a de criação")
|
|
self.logger.warning(
|
|
"Data de extinção ({}) não pode ser menor que a de criação ({}).".format(
|
|
self.cleaned_data["data_extincao"],
|
|
self.cleaned_data["data_criacao"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_final_prevista_temp"]
|
|
and self.cleaned_data["data_final_prevista_temp"]
|
|
< self.cleaned_data["data_criacao"]
|
|
):
|
|
msg = _("Data Prevista para Término não pode ser menor que a de criação")
|
|
self.logger.warning(
|
|
"Data Prevista para Término ({}) não pode ser menor que a de criação ({}).".format(
|
|
self.cleaned_data["data_final_prevista_temp"],
|
|
self.cleaned_data["data_criacao"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_prorrogada_temp"]
|
|
and self.cleaned_data["data_prorrogada_temp"]
|
|
< self.cleaned_data["data_criacao"]
|
|
):
|
|
msg = _("Data Novo Prazo não pode ser menor que a de criação")
|
|
self.logger.warning(
|
|
"Data Novo Prazo ({}) não pode ser menor que a de criação ({}).".format(
|
|
self.cleaned_data["data_prorrogada_temp"],
|
|
self.cleaned_data["data_criacao"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_instalacao_temp"]
|
|
and self.cleaned_data["data_instalacao_temp"]
|
|
< self.cleaned_data["data_criacao"]
|
|
):
|
|
msg = _("Data de Instalação não pode ser menor que a de criação")
|
|
self.logger.warning(
|
|
"Data de Instalação ({}) não pode ser menor que a de criação ({}).".format(
|
|
self.cleaned_data["data_instalacao_temp"],
|
|
self.cleaned_data["data_criacao"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_final_prevista_temp"]
|
|
and self.cleaned_data["data_instalacao_temp"]
|
|
and self.cleaned_data["data_final_prevista_temp"]
|
|
< self.cleaned_data["data_instalacao_temp"]
|
|
):
|
|
msg = _(
|
|
"Data Prevista para Término não pode ser menor que a de Instalação."
|
|
)
|
|
self.logger.warning(
|
|
"Data Prevista para Término ({}) não pode ser menor que a de Instalação ({}).".format(
|
|
self.cleaned_data["data_final_prevista_temp"],
|
|
self.cleaned_data["data_instalacao_temp"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
if (
|
|
self.cleaned_data["data_prorrogada_temp"]
|
|
and self.cleaned_data["data_instalacao_temp"]
|
|
and self.cleaned_data["data_prorrogada_temp"]
|
|
< self.cleaned_data["data_instalacao_temp"]
|
|
):
|
|
msg = _("Data Novo Prazo não pode ser menor que a de Instalação.")
|
|
self.logger.warning(
|
|
"Data Novo Prazo ({}) não pode ser menor que a de Instalação ({}).".format(
|
|
self.cleaned_data["data_prorrogada_temp"],
|
|
self.cleaned_data["data_instalacao_temp"],
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
return self.cleaned_data
|
|
|
|
@transaction.atomic
|
|
def save(self, commit=True):
|
|
inst = self.instance
|
|
if not inst.pk:
|
|
comissao = super(ComissaoForm, self).save(commit)
|
|
content_type = ContentType.objects.get_for_model(Comissao)
|
|
object_id = comissao.pk
|
|
tipo = TipoAutor.objects.get(content_type=content_type)
|
|
nome = comissao.sigla + " - " + comissao.nome
|
|
Autor.objects.create(
|
|
content_type=content_type, object_id=object_id, tipo=tipo, nome=nome
|
|
)
|
|
return comissao
|
|
else:
|
|
comissao = super(ComissaoForm, self).save(commit)
|
|
return comissao
|
|
|
|
|
|
class ReuniaoForm(ModelForm):
|
|
logger = logging.getLogger(__name__)
|
|
comissao = forms.ModelChoiceField(
|
|
queryset=Comissao.objects.all(), widget=forms.HiddenInput()
|
|
)
|
|
|
|
class Meta:
|
|
model = Reuniao
|
|
exclude = ["cod_andamento_reuniao"]
|
|
|
|
def clean(self):
|
|
super(ReuniaoForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
if self.cleaned_data["hora_fim"]:
|
|
if self.cleaned_data["hora_fim"] < self.cleaned_data["hora_inicio"]:
|
|
msg = _(
|
|
"A hora de término da reunião não pode ser menor que a de início"
|
|
)
|
|
self.logger.warning(
|
|
"A hora de término da reunião ({}) não pode ser menor que a de início ({}).".format(
|
|
self.cleaned_data["hora_fim"], self.cleaned_data["hora_inicio"]
|
|
)
|
|
)
|
|
raise ValidationError(msg)
|
|
|
|
upload_pauta = self.cleaned_data.get("upload_pauta", False)
|
|
upload_ata = self.cleaned_data.get("upload_ata", False)
|
|
upload_anexo = self.cleaned_data.get("upload_anexo", False)
|
|
|
|
if upload_pauta:
|
|
validar_arquivo(upload_pauta, "Pauta da Reunião")
|
|
|
|
if upload_ata:
|
|
validar_arquivo(upload_ata, "Ata da Reunião")
|
|
|
|
if upload_anexo:
|
|
validar_arquivo(upload_anexo, "Anexo da Reunião")
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
class PautaReuniaoFilterSet(django_filters.FilterSet):
|
|
class Meta(FilterOverridesMetaMixin):
|
|
model = MateriaEmTramitacao
|
|
fields = [
|
|
"materia__tipo",
|
|
"materia__ano",
|
|
"materia__numero",
|
|
"materia__data_apresentacao",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super(PautaReuniaoFilterSet, self).__init__(*args, **kwargs)
|
|
|
|
self.filters["materia__tipo"].label = "Tipo da Matéria"
|
|
self.filters["materia__ano"].label = "Ano da Matéria"
|
|
self.filters["materia__numero"].label = "Número da Matéria"
|
|
self.filters["materia__data_apresentacao"].label = "Data (Inicial - Final)"
|
|
|
|
row1 = to_row(
|
|
[("materia__tipo", 4), ("materia__ano", 4), ("materia__numero", 4)]
|
|
)
|
|
row2 = to_row([("materia__data_apresentacao", 12)])
|
|
|
|
self.form.helper = SaplFormHelper()
|
|
self.form.helper.form_method = "GET"
|
|
self.form.helper.layout = Layout(
|
|
Fieldset(
|
|
_("Pesquisa de Matérias"), row1, row2, form_actions(label="Pesquisar")
|
|
)
|
|
)
|
|
|
|
|
|
class PautaReuniaoForm(forms.ModelForm):
|
|
class Meta:
|
|
model = PautaReuniao
|
|
exclude = ["reuniao"]
|
|
|
|
|
|
class DocumentoAcessorioCreateForm(FileFieldCheckMixin, forms.ModelForm):
|
|
parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput())
|
|
|
|
class Meta:
|
|
model = DocumentoAcessorio
|
|
exclude = ["reuniao"]
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(DocumentoAcessorioCreateForm, self).__init__(**kwargs)
|
|
|
|
if self.instance:
|
|
reuniao = Reuniao.objects.get(id=self.initial["parent_pk"])
|
|
comissao = reuniao.comissao
|
|
comissao_pk = comissao.id
|
|
documentos = reuniao.documentoacessorio_set.all()
|
|
return self.create_documentoacessorio()
|
|
|
|
def create_documentoacessorio(self):
|
|
reuniao = Reuniao.objects.get(id=self.initial["parent_pk"])
|
|
|
|
def clean(self):
|
|
super(DocumentoAcessorioCreateForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
arquivo = self.cleaned_data.get("arquivo")
|
|
|
|
if arquivo:
|
|
validar_arquivo(arquivo, "Texto Integral")
|
|
# else:
|
|
# ## TODO: definir arquivo no form e preservar o nome do campo
|
|
# ## que gerou a mensagem de erro.
|
|
# ## arquivo = forms.FileField(required=True, label="Texto Integral")
|
|
# nome_arquivo = self.fields['arquivo'].label
|
|
# raise ValidationError(f'Favor anexar arquivo em {nome_arquivo}')
|
|
|
|
return self.cleaned_data
|
|
|
|
|
|
class DocumentoAcessorioEditForm(FileFieldCheckMixin, forms.ModelForm):
|
|
parent_pk = forms.CharField(required=False) # widget=forms.HiddenInput())
|
|
|
|
class Meta:
|
|
model = DocumentoAcessorio
|
|
fields = ["nome", "data", "autor", "ementa", "indexacao", "arquivo"]
|
|
|
|
def __init__(self, user=None, **kwargs):
|
|
super(DocumentoAcessorioEditForm, self).__init__(**kwargs)
|
|
|
|
def clean(self):
|
|
super(DocumentoAcessorioEditForm, self).clean()
|
|
|
|
if not self.is_valid():
|
|
return self.cleaned_data
|
|
|
|
arquivo = self.cleaned_data.get("arquivo")
|
|
|
|
if arquivo:
|
|
validar_arquivo(arquivo, "Texto Integral")
|
|
# else:
|
|
# ## TODO: definir arquivo no form e preservar o nome do campo
|
|
# ## que gerou a mensagem de erro.
|
|
# ## arquivo = forms.FileField(required=True, label="Texto Integral")
|
|
# nome_arquivo = self.fields['arquivo'].label
|
|
# raise ValidationError(f'Favor anexar arquivo em {nome_arquivo}')
|
|
|
|
return self.cleaned_data
|
|
|