Exemplo n.º 1
0
class TipoProposicao(models.Model):
    descricao = models.CharField(max_length=50, verbose_name=_('Descrição'))

    # FIXME - para a rotina de migração - estes campos mudaram
    # retire o comentário quando resolver
    content_type = models.ForeignKey(ContentType,
                                     default=None,
                                     verbose_name=_('Definição de Tipo'))
    object_id = models.PositiveIntegerField(blank=True,
                                            null=True,
                                            default=None)
    tipo_conteudo_related = SaplGenericForeignKey(
        'content_type', 'object_id', verbose_name=_('Seleção de Tipo'))

    perfis = models.ManyToManyField(
        PerfilEstruturalTextoArticulado,
        blank=True,
        verbose_name=_('Perfis Estruturais de Textos Articulados'),
        help_text=_("""
                    Mesmo que em Configurações da Aplicação nas
                    Tabelas Auxiliares esteja definido que Proposições possam
                    utilizar Textos Articulados, ao gerar uma proposição,
                    a solução de Textos Articulados será disponibilizada se
                    o Tipo escolhido para a Proposição estiver associado a ao
                    menos um Perfil Estrutural de Texto Articulado.
                    """))

    class Meta:
        verbose_name = _('Tipo de Proposição')
        verbose_name_plural = _('Tipos de Proposições')
        unique_together = (('content_type', 'object_id'), )

    def __str__(self):
        return self.descricao
Exemplo n.º 2
0
class TipoProposicao(models.Model):
    descricao = models.CharField(
        max_length=50,
        verbose_name=_('Descrição'),
        unique=True,
        error_messages={
            'unique': _('Já existe um Tipo de Proposição com esta descrição.')
        })

    exige_assinatura_digital = models.BooleanField(
        default=True,
        verbose_name=_('Exigir Assinatura Digital'),
    )

    content_type = models.ForeignKey(ContentType,
                                     default=None,
                                     on_delete=models.PROTECT,
                                     verbose_name=_('Conversão de Meta-Tipos'),
                                     help_text=_("""
        Quando uma proposição é incorporada, ela é convertida de proposição
        para outro elemento dentro do Sapl. Existem alguns elementos que
        uma proposição pode se tornar. Defina este meta-tipo e em seguida
        escolha um Tipo Correspondente!
        """))
    object_id = models.PositiveIntegerField(blank=True,
                                            null=True,
                                            default=None)
    tipo_conteudo_related = SaplGenericForeignKey(
        'content_type', 'object_id', verbose_name=_('Tipo Correspondente'))

    tipo_autores = models.ManyToManyField(TipoAutor,
                                          blank=True,
                                          verbose_name=_('Tipos de Autores'),
                                          help_text=_("""
                    Tipo de Autores que pode enviar este tipo de Proposição.
                    """))
    perfis = models.ManyToManyField(
        PerfilEstruturalTextoArticulado,
        blank=True,
        verbose_name=_('Perfis Estruturais de Textos Articulados'),
        help_text=_("""
                    Mesmo que em Configurações da Aplicação nas
                    Tabelas Auxiliares esteja definido que Proposições possam
                    utilizar Textos Articulados, ao gerar uma proposição,
                    a solução de Textos Articulados será disponibilizada se
                    o Tipo escolhido para a Proposição estiver associado a ao
                    menos um Perfil Estrutural de Texto Articulado.
                    """))

    class Meta:
        verbose_name = _('Tipo de Proposição')
        verbose_name_plural = _('Tipos de Proposições')

    def __str__(self):
        return self.descricao
Exemplo n.º 3
0
class TipoProposicao(models.Model):
    descricao = models.CharField(
        max_length=50,
        verbose_name=_('Descrição'),
        unique=True,
        error_messages={
            'unique': _('Já existe um Tipo de Proposição com esta descrição.')
        })
    content_type = models.ForeignKey(ContentType,
                                     default=None,
                                     on_delete=models.PROTECT,
                                     verbose_name=_('Definição de Tipo'))
    object_id = models.PositiveIntegerField(blank=True,
                                            null=True,
                                            default=None)
    tipo_conteudo_related = SaplGenericForeignKey(
        'content_type', 'object_id', verbose_name=_('Seleção de Tipo'))

    perfis = models.ManyToManyField(
        PerfilEstruturalTextoArticulado,
        blank=True,
        verbose_name=_('Perfis Estruturais de Textos Articulados'),
        help_text=_("""
                    Mesmo que em Configurações da Aplicação nas
                    Tabelas Auxiliares esteja definido que Proposições possam
                    utilizar Textos Articulados, ao gerar uma proposição,
                    a solução de Textos Articulados será disponibilizada se
                    o Tipo escolhido para a Proposição estiver associado a ao
                    menos um Perfil Estrutural de Texto Articulado.
                    """))

    class Meta:
        verbose_name = _('Tipo de Proposição')
        verbose_name_plural = _('Tipos de Proposições')

    def __str__(self):
        return self.descricao
Exemplo n.º 4
0
class Proposicao(models.Model):
    autor = models.ForeignKey(Autor,
                              null=True,
                              blank=True,
                              on_delete=models.PROTECT)
    tipo = models.ForeignKey(TipoProposicao,
                             on_delete=models.PROTECT,
                             blank=False,
                             null=True,
                             verbose_name=_('Tipo'))

    # XXX data_envio was not null, but actual data said otherwise!!!
    data_envio = models.DateTimeField(blank=False,
                                      null=True,
                                      verbose_name=_('Data de Envio'))
    data_recebimento = models.DateTimeField(
        blank=True, null=True, verbose_name=_('Data de Recebimento'))
    data_devolucao = models.DateTimeField(blank=True,
                                          null=True,
                                          verbose_name=_('Data de Devolução'))

    descricao = models.TextField(verbose_name=_('Descrição'))
    justificativa_devolucao = models.CharField(
        max_length=200,
        blank=True,
        verbose_name=_('Justificativa da Devolução'))

    ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'),
                                           default=None,
                                           blank=True,
                                           null=True,
                                           choices=RANGE_ANOS)

    numero_proposicao = models.PositiveIntegerField(blank=True,
                                                    null=True,
                                                    verbose_name=_('Número'))
    """
    FIXME Campo não é necessário na modelagem e implementação atual para o
    módulo de proposições.
    E - Enviada é tratado pela condição do campo data_envio - se None n enviado
        se possui uma data, enviada
    R - Recebida é uma condição do campo data_recebimento - se None não receb.
        se possui uma data, enviada, recebida e incorporada
    I - A incorporação é automática ao ser recebida

    e ainda possui a condição de Devolvida onde o campo data_devolucao é
    direfente de None, fornecedo a informação para o usuário da data que o
    responsável devolveu bem como a justificativa da devolução.
    Essa informação fica disponível para o Autor até que ele envie novamente
    sua proposição ou resolva excluir.
    """
    # ind_enviado and ind_devolvido collapsed as char field (status)
    status = models.CharField(blank=True,
                              max_length=1,
                              choices=(('E', 'Enviada'), ('R', 'Recebida'),
                                       ('I', 'Incorporada')),
                              verbose_name=_('Status Proposição'))
    texto_original = models.FileField(
        upload_to=materia_upload_path,
        blank=True,
        null=True,
        verbose_name=_('Texto Original'),
        validators=[restringe_tipos_de_arquivo_txt])

    texto_articulado = GenericRelation(TextoArticulado,
                                       related_query_name='texto_articulado')

    # FIXME - para a rotina de migração - este campo mudou
    # retire o comentário quando resolver
    materia_de_vinculo = models.ForeignKey(MateriaLegislativa,
                                           blank=True,
                                           null=True,
                                           on_delete=models.CASCADE,
                                           verbose_name=_('Matéria anexadora'),
                                           related_name=_('proposicao_set'))

    # FIXME - para a rotina de migração - estes campos mudaram
    # retire o comentário quando resolver
    content_type = models.ForeignKey(ContentType,
                                     default=None,
                                     blank=True,
                                     null=True,
                                     verbose_name=_('Tipo de Material Gerado'))
    object_id = models.PositiveIntegerField(blank=True,
                                            null=True,
                                            default=None)
    conteudo_gerado_related = SaplGenericForeignKey(
        'content_type', 'object_id', verbose_name=_('Conteúdo Gerado'))
    """# Ao ser recebida, irá gerar uma nova matéria ou um documento acessorio
    # de uma já existente
    materia_gerada = models.ForeignKey(
        MateriaLegislativa, blank=True, null=True,
        related_name=_('materia_gerada'))
    documento_gerado = models.ForeignKey(
        DocumentoAcessorio, blank=True, null=True)"""
    @property
    def perfis(self):
        return self.tipo.perfis.all()

    @property
    def title_type(self):
        return '%s nº _____ %s' % (self.tipo,
                                   formats.date_format(
                                       self.data_envio if self.data_envio else
                                       timezone.now(), "\d\e d \d\e F \d\e Y"))

    class Meta:
        verbose_name = _('Proposição')
        verbose_name_plural = _('Proposições')
        unique_together = (('content_type', 'object_id'), )
        permissions = (
            ('detail_proposicao_enviada',
             _('Pode acessar detalhes de uma proposição enviada.')),
            ('detail_proposicao_devolvida',
             _('Pode acessar detalhes de uma proposição devolvida.')),
            ('detail_proposicao_incorporada',
             _('Pode acessar detalhes de uma proposição incorporada.')),
        )

    def __str__(self):
        if self.ano and self.numero_proposicao:
            return '%s %s/%s' % (Proposicao._meta.verbose_name,
                                 self.numero_proposicao, self.ano)
        else:
            if len(self.descricao) < 30:
                descricao = self.descricao[:28] + ' ...'
            else:
                descricao = self.descricao

            return '%s %s/%s' % (Proposicao._meta.verbose_name, self.id,
                                 descricao)

    def delete(self, using=None, keep_parents=False):
        if self.texto_original:
            self.texto_original.delete()

        return models.Model.delete(self,
                                   using=using,
                                   keep_parents=keep_parents)

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):

        if not self.pk and self.texto_original:
            texto_original = self.texto_original
            self.texto_original = None
            models.Model.save(self,
                              force_insert=force_insert,
                              force_update=force_update,
                              using=using,
                              update_fields=update_fields)
            self.texto_original = texto_original

        return models.Model.save(self,
                                 force_insert=force_insert,
                                 force_update=force_update,
                                 using=using,
                                 update_fields=update_fields)
Exemplo n.º 5
0
class Protocolo(models.Model):
    numero = models.PositiveIntegerField(
        blank=False, null=False, verbose_name=_('Número de Protocolo'))
    ano = models.PositiveSmallIntegerField(blank=False,
                                           null=False,
                                           choices=RANGE_ANOS,
                                           verbose_name=_('Ano do Protocolo'))
    data = models.DateField(null=True, blank=True,
                            verbose_name=_('Data do Protocolo'),
                            help_text=_('Informado manualmente'))
    hora = models.TimeField(null=True, blank=True,
                            verbose_name=_('Hora do Protocolo'),
                            help_text=_('Informado manualmente'))
    timestamp_data_hora_manual = models.DateTimeField(default=timezone.now)
    user_data_hora_manual = models.CharField(
        max_length=256, blank=True,
        verbose_name=_('IP'),
        help_text=_('Usuário que está realizando Protocolo e informando '
                    'data e hora manualmente.'))
    ip_data_hora_manual = models.CharField(
        max_length=256, blank=True,
        verbose_name=_('IP'),
        help_text=_('Endereço IP da estação de trabalho '
                    'do usuário que está realizando Protocolo e informando '
                    'data e hora manualmente.'))

    # Não foi utilizado auto_now_add=True em timestamp porque
    # ele usa datetime.now que não é timezone aware.
    timestamp = models.DateTimeField(
        default=timezone.now, null=True, blank=True)
    tipo_protocolo = models.PositiveIntegerField(
        blank=True, null=True, verbose_name=_('Tipo de Protocolo'))
    tipo_processo = models.PositiveIntegerField()
    interessado = models.CharField(
        max_length=200, blank=True, verbose_name=_('Interessado'))
    tipo_processo = models.PositiveIntegerField()
    email = models.EmailField(
        blank=True, verbose_name=_('Email do Interessado'))
    comprovante_automatico_enviado = models.BooleanField(
        default=False, verbose_name=_('Comprovante Automático Enviado'))
    autor = models.ForeignKey(Autor,
                              blank=True,
                              null=True,
                              on_delete=models.PROTECT)
    assunto_ementa = models.TextField(blank=True)

    tipo_documento = models.ForeignKey(
        TipoDocumentoAdministrativo,
        blank=True,
        null=True,
        on_delete=models.PROTECT,
        verbose_name=_('Tipo de Documento'))
    tipo_materia = models.ForeignKey(
        TipoMateriaLegislativa,
        blank=True,
        null=True,
        on_delete=models.PROTECT,
        verbose_name=_('Tipo de Matéria'))

    tipo_content_type = models.ForeignKey(
        ContentType, default=None, blank=True, null=True,
        verbose_name=_('Tipo de Material Gerado'),
        related_name='tipo_content_type_set',
        on_delete=PROTECT)
    tipo_object_id = models.PositiveIntegerField(
        blank=True, null=True, default=None)
    tipo_conteudo_protocolado = SaplGenericForeignKey(
        'tipo_content_type', 'tipo_object_id', verbose_name=_('Tipo do Conteúdo Protocolado'))

    conteudo_content_type = models.ForeignKey(
        ContentType, default=None, blank=True, null=True,
        verbose_name=_('Tipo de Material Gerado'),
        related_name='conteudo_content_type_set',
        on_delete=PROTECT)
    conteudo_object_id = models.PositiveIntegerField(
        blank=True, null=True, default=None)
    conteudo_protocolado = SaplGenericForeignKey(
        'conteudo_content_type', 'conteudo_object_id', verbose_name=_('Conteúdo Protocolado'))

    numero_paginas = models.PositiveIntegerField(
        blank=True, null=True, verbose_name=_('Número de Páginas'))
    observacao = models.TextField(
        blank=True, verbose_name=_('Observação'))
    anulado = models.BooleanField(default=False)
    user_anulacao = models.CharField(max_length=1000, blank=True)
    ip_anulacao = models.CharField(max_length=15, blank=True)
    justificativa_anulacao = models.CharField(
        max_length=260, blank=True, verbose_name=_('Motivo'))
    timestamp_anulacao = models.DateTimeField(blank=True, null=True)

    class Meta:
        verbose_name = _('Protocolo')
        verbose_name_plural = _('Protocolos')
        permissions = (
            ('action_anular_protocolo', _('Permissão para Anular Protocolo')),
            ('action_homologar_protocolo', _('Permissão para Homologar Protocolo')),
        )

    def __str__(self):
        return _('%(numero)s/%(ano)s') % {
            'numero': self.numero, 'ano': self.ano
        }

    @property
    def epigrafe(self):
        return '{}/{} - {}'.format(
            self.numero,
            self.ano,
            formats.date_format(
                timezone.localtime(self.timestamp),
                "DATETIME_FORMAT"
            ) if self.timestamp else
            '{} - {}'.format(
                formats.date_format(self.data, "DATE_FORMAT"),
                formats.date_format(self.hora, 'H:i')
            )
        )

    def materia_vinculada(self):
        try:
            materia = MateriaLegislativa.objects.get(
                tipo=self.tipo_materia,
                ano=self.ano,
                numero_protocolo=self.numero
            )
        except:
            return None
        return materia
Exemplo n.º 6
0
class Proposicao(CommonMixin):

    FIELDFILE_NAME = ('texto_original', )

    metadata = JSONField(verbose_name=_('Metadados'),
                         blank=True,
                         null=True,
                         default=None,
                         encoder=DjangoJSONEncoder)

    autor = models.ForeignKey(Autor,
                              null=True,
                              blank=True,
                              on_delete=models.PROTECT)
    tipo = models.ForeignKey(TipoProposicao,
                             on_delete=models.PROTECT,
                             blank=False,
                             null=True,
                             verbose_name=_('Tipo'))

    # XXX data_envio was not null, but actual data said otherwise!!!
    data_envio = models.DateTimeField(blank=False,
                                      null=True,
                                      verbose_name=_('Data de Envio'))
    data_recebimento = models.DateTimeField(
        blank=True, null=True, verbose_name=_('Data de Recebimento'))
    data_devolucao = models.DateTimeField(blank=True,
                                          null=True,
                                          verbose_name=_('Data de Devolução'))

    descricao = models.TextField(verbose_name=_('Descrição'))
    justificativa_devolucao = models.CharField(
        max_length=200,
        blank=True,
        verbose_name=_('Justificativa da Devolução'))

    ano = models.PositiveSmallIntegerField(verbose_name=_('Ano'),
                                           default=None,
                                           blank=True,
                                           null=True,
                                           choices=RANGE_ANOS)

    numero_proposicao = models.PositiveIntegerField(blank=True,
                                                    null=True,
                                                    verbose_name=_('Número'))

    numero_materia_futuro = models.PositiveIntegerField(
        blank=True, null=True, verbose_name=_('Número Matéria'))

    hash_code = models.CharField(verbose_name=_('Código do Documento'),
                                 max_length=200,
                                 blank=True)
    """
    FIXME Campo não é necessário na modelagem e implementação atual para o
    módulo de proposições.
    E - Enviada é tratado pela condição do campo data_envio - se None n enviado
        se possui uma data, enviada
    R - Recebida é uma condição do campo data_recebimento - se None não receb.
        se possui uma data, enviada, recebida e incorporada
    I - A incorporação é automática ao ser recebida

    e ainda possui a condição de Devolvida onde o campo data_devolucao é
    direfente de None, fornecedo a informação para o usuário da data que o
    responsável devolveu bem como a justificativa da devolução.
    Essa informação fica disponível para o Autor até que ele envie novamente
    sua proposição ou resolva excluir.
    """
    # ind_enviado and ind_devolvido collapsed as char field (status)
    status = models.CharField(blank=True,
                              max_length=1,
                              choices=(('E', 'Enviada'), ('R', 'Recebida'),
                                       ('I', 'Incorporada')),
                              verbose_name=_('Status Proposição'))

    texto_original = PortalFileField(
        upload_to=materia_upload_path,
        blank=True,
        null=True,
        verbose_name=_('Texto Original'),
        storage=OverwriteStorage(),
        validators=[restringe_tipos_de_arquivo_txt],
        max_length=512)

    texto_articulado = GenericRelation(TextoArticulado,
                                       related_query_name='texto_articulado')

    materia_de_vinculo = models.ForeignKey(MateriaLegislativa,
                                           blank=True,
                                           null=True,
                                           on_delete=models.CASCADE,
                                           verbose_name=_('Matéria anexadora'),
                                           related_name=_('proposicao_set'))

    proposicao_vinculada = models.ForeignKey(
        'self',
        blank=True,
        null=True,
        on_delete=models.CASCADE,
        verbose_name=_('Proposição Vinculada'),
        related_name=_('proposicao_vinculada_set'))

    content_type = models.ForeignKey(ContentType,
                                     default=None,
                                     blank=True,
                                     null=True,
                                     verbose_name=_('Tipo de Material Gerado'),
                                     on_delete=PROTECT)
    object_id = models.PositiveIntegerField(blank=True,
                                            null=True,
                                            default=None)
    conteudo_gerado_related = SaplGenericForeignKey(
        'content_type', 'object_id', verbose_name=_('Conteúdo Gerado'))

    observacao = models.TextField(blank=True, verbose_name=_('Observação'))
    cancelado = models.BooleanField(verbose_name=_('Cancelada ?'),
                                    choices=YES_NO_CHOICES,
                                    default=False)
    """# Ao ser recebida, irá gerar uma nova matéria ou um documento acessorio
    # de uma já existente
    materia_gerada = models.ForeignKey(
        MateriaLegislativa, blank=True, null=True,
        related_name=_('materia_gerada'))
    documento_gerado = models.ForeignKey(
        DocumentoAcessorio, blank=True, null=True)"""

    user = models.ForeignKey(get_settings_auth_user_model(),
                             verbose_name=_('Usuário'),
                             on_delete=models.PROTECT,
                             null=True,
                             blank=True)
    ip = models.CharField(verbose_name=_('IP'),
                          max_length=30,
                          blank=True,
                          default='')
    ultima_edicao = models.DateTimeField(
        verbose_name=_('Data e Hora da Edição'), blank=True, null=True)

    @property
    def perfis(self):
        return self.tipo.perfis.all()

    @property
    def title_type(self):
        return '%s nº _____ %s' % (self.tipo,
                                   formats.date_format(
                                       self.data_envio if self.data_envio else
                                       timezone.now(), "\d\e d \d\e F \d\e Y"))

    class Meta:
        ordering = ['-data_recebimento']
        verbose_name = _('Proposição')
        verbose_name_plural = _('Proposições')
        unique_together = (('content_type', 'object_id'), )
        permissions = (
            ('detail_proposicao_enviada',
             _('Pode acessar detalhes de uma proposição enviada.')),
            ('detail_proposicao_devolvida',
             _('Pode acessar detalhes de uma proposição devolvida.')),
            ('detail_proposicao_incorporada',
             _('Pode acessar detalhes de uma proposição incorporada.')),
        )

    def __str__(self):
        if self.ano and self.numero_proposicao:
            return '%s %s/%s' % (Proposicao._meta.verbose_name,
                                 self.numero_proposicao, self.ano)
        else:
            if len(self.descricao) < 30:
                descricao = self.descricao[:28] + ' ...'
            else:
                descricao = self.descricao

            return '%s %s/%s' % (Proposicao._meta.verbose_name, self.id,
                                 descricao)

    @property
    def epigrafe(self):
        return _('%(tipo)s nº %(numero)s de %(data)s') % {
            'tipo':
            self.tipo,
            'numero':
            self.numero_proposicao,
            'data':
            defaultfilters.date(
                self.data_envio if self.data_envio else timezone.now(),
                "d \d\e F \d\e Y")
        }

    def delete(self, using=None, keep_parents=False):
        if self.texto_original:
            self.texto_original.delete()

        return models.Model.delete(self,
                                   using=using,
                                   keep_parents=keep_parents)

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):

        if not self.pk and self.texto_original:
            texto_original = self.texto_original
            self.texto_original = None
            models.Model.save(self,
                              force_insert=force_insert,
                              force_update=force_update,
                              using=using,
                              update_fields=update_fields)
            self.texto_original = texto_original

        return models.Model.save(self,
                                 force_insert=force_insert,
                                 force_update=force_update,
                                 using=using,
                                 update_fields=update_fields)