From cf0c0cc0517f4ae184502bad664efeb1c52ce4bd Mon Sep 17 00:00:00 2001 From: Gustavo274 Date: Tue, 6 Jul 2021 16:17:59 -0300 Subject: [PATCH] work in progress --- .../migrations/0036_reuniaofrente.py | 41 ++++++ sapl/parlamentares/models.py | 120 +++++++++++++++++- sapl/parlamentares/views.py | 89 ++++++++++++- 3 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 sapl/parlamentares/migrations/0036_reuniaofrente.py diff --git a/sapl/parlamentares/migrations/0036_reuniaofrente.py b/sapl/parlamentares/migrations/0036_reuniaofrente.py new file mode 100644 index 000000000..cf46a4747 --- /dev/null +++ b/sapl/parlamentares/migrations/0036_reuniaofrente.py @@ -0,0 +1,41 @@ +# Generated by Django 2.2.20 on 2021-07-06 19:24 + +from django.db import migrations, models +import django.db.models.deletion +import sapl.parlamentares.models +import sapl.utils + + +class Migration(migrations.Migration): + + dependencies = [ + ('parlamentares', '0035_auto_20210315_1522'), + ] + + operations = [ + migrations.CreateModel( + name='ReuniaoFrente', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('numero', models.PositiveIntegerField(verbose_name='Número')), + ('nome', models.CharField(max_length=150, verbose_name='Nome da Reunião')), + ('tema', models.CharField(blank=True, max_length=150, verbose_name='Tema da Reunião')), + ('data', models.DateField(verbose_name='Data')), + ('hora_inicio', models.TimeField(null=True, verbose_name='Horário de Início (hh:mm)')), + ('hora_fim', models.TimeField(blank=True, null=True, verbose_name='Horário de Término (hh:mm)')), + ('local_reuniao', models.CharField(blank=True, max_length=100, verbose_name='Local da Reunião')), + ('observacao', models.TextField(blank=True, verbose_name='Observação')), + ('url_audio', models.URLField(blank=True, max_length=150, verbose_name='URL do Arquivo de Áudio (Formatos MP3 / AAC)')), + ('url_video', models.URLField(blank=True, max_length=150, verbose_name='URL do Arquivo de Vídeo (Formatos MP4 / FLV / WebM)')), + ('upload_pauta', models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.parlamentares.models.pauta_upload_path, verbose_name='Pauta da Reunião')), + ('upload_ata', models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.parlamentares.models.ata_upload_path, verbose_name='Ata da Reunião')), + ('upload_anexo', models.FileField(blank=True, max_length=300, null=True, storage=sapl.utils.OverwriteStorage(), upload_to=sapl.parlamentares.models.anexo_upload_path, verbose_name='Anexo da Reunião')), + ('frente', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parlamentares.Frente', verbose_name='Frente Parlamentar')), + ], + options={ + 'verbose_name': 'Reunião de Frente Parlamentar', + 'verbose_name_plural': 'Reuniões de Frentes Parlamentares', + 'ordering': ('numero', 'frente'), + }, + ), + ] diff --git a/sapl/parlamentares/models.py b/sapl/parlamentares/models.py index 423481b56..1ba54ec18 100644 --- a/sapl/parlamentares/models.py +++ b/sapl/parlamentares/models.py @@ -10,8 +10,21 @@ from sapl.base.models import Autor from sapl.decorators import vigencia_atual from sapl.utils import (LISTA_DE_UFS, YES_NO_CHOICES, SaplGenericRelation, get_settings_auth_user_model, - intervalos_tem_intersecao, - restringe_tipos_de_arquivo_img, texto_upload_path) + intervalos_tem_intersecao, restringe_tipos_de_arquivo_txt, + restringe_tipos_de_arquivo_img, texto_upload_path, OverwriteStorage) + + +def pauta_upload_path(instance, filename): + + return texto_upload_path(instance, filename, subpath='pauta', pk_first=True) + + +def ata_upload_path(instance, filename): + return texto_upload_path(instance, filename, subpath='ata', pk_first=True) + + +def anexo_upload_path(instance, filename): + return texto_upload_path(instance, filename, subpath='anexo', pk_first=True) @reversion.register() @@ -629,6 +642,109 @@ class Votante(models.Model): return self.user.username +class ReuniaoFrente(models.Model): + frente = models.ForeignKey( + Frente, + on_delete=models.CASCADE, + verbose_name=_('Frente Parlamentar')) + numero = models.PositiveIntegerField(verbose_name=_('Número')) + nome = models.CharField( + max_length=150, verbose_name=_('Nome da Reunião')) + tema = models.CharField( + max_length=150, blank=True, verbose_name=_('Tema da Reunião')) + data = models.DateField(verbose_name=_('Data')) + hora_inicio = models.TimeField( + null=True, + verbose_name=_('Horário de Início (hh:mm)')) + hora_fim = models.TimeField( + blank=True, + null=True, + verbose_name=_('Horário de Término (hh:mm)')) + local_reuniao = models.CharField( + max_length=100, blank=True, verbose_name=_('Local da Reunião')) + observacao = models.TextField( + blank=True, verbose_name=_('Observação')) + url_audio = models.URLField( + max_length=150, blank=True, + verbose_name=_('URL do Arquivo de Áudio (Formatos MP3 / AAC)')) + url_video = models.URLField( + max_length=150, blank=True, + verbose_name=_('URL do Arquivo de Vídeo (Formatos MP4 / FLV / WebM)')) + upload_pauta = models.FileField( + max_length=300, + blank=True, null=True, + upload_to=pauta_upload_path, + verbose_name=_('Pauta da Reunião'), + storage=OverwriteStorage(), + # validators=[restringe_tipos_de_arquivo_txt] + ) + upload_ata = models.FileField( + max_length=300, + blank=True, null=True, + upload_to=ata_upload_path, + verbose_name=_('Ata da Reunião'), + storage=OverwriteStorage(), + # validators=[restringe_tipos_de_arquivo_txt] + ) + upload_anexo = models.FileField( + max_length=300, + blank=True, null=True, + upload_to=anexo_upload_path, + storage=OverwriteStorage(), + verbose_name=_('Anexo da Reunião')) + + class Meta: + verbose_name = _('Reunião de Frente Parlamentar') + verbose_name_plural = _('Reuniões de Frentes Parlamentares') + ordering = ('numero', 'frente') + + def __str__(self): + return self.nome + + def delete(self, using=None, keep_parents=False): + upload_pauta = self.upload_pauta + upload_ata = self.upload_ata + upload_anexo = self.upload_anexo + + result = super().delete(using=using, keep_parents=keep_parents) + + if upload_pauta: + upload_pauta.delete(save=False) + + if upload_ata: + upload_ata.delete(save=False) + + if upload_anexo: + upload_anexo.delete(save=False) + + return result + + def save(self, force_insert=False, force_update=False, using=None, + update_fields=None): + + if not self.pk and (self.upload_pauta or self.upload_ata or + self.upload_anexo): + upload_pauta = self.upload_pauta + upload_ata = self.upload_ata + upload_anexo = self.upload_anexo + self.upload_pauta = None + self.upload_ata = None + self.upload_anexo = None + models.Model.save(self, force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields) + + self.upload_pauta = upload_pauta + self.upload_ata = upload_ata + self.upload_anexo = upload_anexo + + return models.Model.save(self, force_insert=force_insert, + force_update=force_update, + using=using, + update_fields=update_fields) + + @reversion.register() class Bloco(models.Model): ''' diff --git a/sapl/parlamentares/views.py b/sapl/parlamentares/views.py index aea6d53df..d89c139ba 100644 --- a/sapl/parlamentares/views.py +++ b/sapl/parlamentares/views.py @@ -42,7 +42,7 @@ from .models import (CargoMesa, Coligacao, ComposicaoColigacao, ComposicaoMesa, Dependente, Filiacao, Frente, Legislatura, Mandato, NivelInstrucao, Parlamentar, Partido, SessaoLegislativa, SituacaoMilitar, TipoAfastamento, TipoDependente, Votante, - Bloco, FrenteCargo, FrenteParlamentar, BlocoCargo, BlocoMembro) + Bloco, FrenteCargo, FrenteParlamentar, BlocoCargo, BlocoMembro, ReuniaoFrente) FrenteCargoCrud = CrudAux.build(FrenteCargo, 'frente_cargo') @@ -513,6 +513,93 @@ class FrenteCrud(Crud): form_class = FrenteForm +class ReuniaoFrenteCrud(MasterDetailCrud): + model = ReuniaoFrente + parent_field = 'frente' + public = [RP_LIST, RP_DETAIL, ] + + class BaseMixin(MasterDetailCrud.BaseMixin): + list_field_names = ['data', 'nome', 'tema', 'upload_ata'] + ordering = '-data' + + class DetailView(MasterDetailCrud.DetailView): + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + docs = [] + documentos = DocumentoAcessorio.objects.filter( + reuniao=self.kwargs['pk']).order_by('nome') + docs.extend(documentos) + + context['docs'] = docs + context['num_docs'] = len(docs) + + mats = [] + materias_pauta = PautaReuniao.objects.filter( + reuniao=self.kwargs['pk']) + materias_pk = [ + materia_pauta.materia.pk for materia_pauta in materias_pauta] + + context['mats'] = MateriaLegislativa.objects.filter( + pk__in=materias_pk + ).order_by('tipo', '-ano', 'numero') + context['num_mats'] = len(context['mats']) + + context['reuniao_pk'] = self.kwargs['pk'] + + return context + + class ListView(MasterDetailCrud.ListView): + logger = logging.getLogger(__name__) + paginate_by = 10 + + def take_reuniao_pk(self): + + username = self.request.user.username + try: + self.logger.debug('user=' + username + + '. Tentando obter pk da reunião.') + return int(self.request.GET['pk']) + except Exception as e: + self.logger.error( + 'user=' + username + '. Erro ao obter pk da reunião. Retornado 0. ' + str(e)) + return 0 + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + reuniao_pk = self.take_reuniao_pk() + + if reuniao_pk == 0: + ultima_reuniao = list(context['reuniao_list']) + if len(ultima_reuniao) > 0: + ultimo = ultima_reuniao[-1] + context['reuniao_pk'] = ultimo.pk + else: + context['reuniao_pk'] = 0 + else: + context['reuniao_pk'] = reuniao_pk + + context['documentoacessorio_set'] = DocumentoAcessorio.objects.filter( + reuniao__pk=context['reuniao_pk'] + ).order_by('id') + return context + + class UpdateView(MasterDetailCrud.UpdateView): + form_class = ReuniaoForm + + def get_initial(self): + return {'comissao': self.object.comissao} + + class CreateView(MasterDetailCrud.CreateView): + form_class = ReuniaoForm + + def get_initial(self): + comissao = Comissao.objects.get(id=self.kwargs['pk']) + + return {'comissao': comissao} + + class FrenteParlamentarCrud(MasterDetailCrud): model = FrenteParlamentar parent_field = 'frente'