From 1d389c32b870762215601ded88384fd797ef66c7 Mon Sep 17 00:00:00 2001 From: Felipe Vieira Date: Tue, 22 Nov 2011 16:58:31 +0000 Subject: [PATCH] documentando model para substituir dicionario de dados --- sigi/apps/__init__.py | 7 ++++ sigi/apps/casas/models.py | 23 +++++------ sigi/apps/contatos/models.py | 28 ++++++++++++++ sigi/apps/convenios/models.py | 66 ++++++++++++++++++++++---------- sigi/apps/diagnosticos/models.py | 26 ++++++++++++- sigi/apps/servidores/admin.py | 21 +++++++++- sigi/apps/servidores/models.py | 62 +++++++++++++++++++++++++++--- 7 files changed, 194 insertions(+), 39 deletions(-) diff --git a/sigi/apps/__init__.py b/sigi/apps/__init__.py index e69de29..d1c69b0 100644 --- a/sigi/apps/__init__.py +++ b/sigi/apps/__init__.py @@ -0,0 +1,7 @@ +from django.db.models.fields import Field as DefaultField + +class Field(DefaultField): + def __init__(self, verbose_name=None, name=None, db_comment=None, **kwargs): + # comment to be added in database schema + self.db_comment = db_comment + super(Field, self).__init__(verbose_name, name, **kwargs) diff --git a/sigi/apps/casas/models.py b/sigi/apps/casas/models.py index 9842749..52aab33 100644 --- a/sigi/apps/casas/models.py +++ b/sigi/apps/casas/models.py @@ -6,6 +6,12 @@ from sigi.apps.parlamentares.models import Parlamentar from sigi.apps.utils import SearchField class TipoCasaLegislativa(models.Model): + """ Modelo para representar o tipo da Casa Legislativa + + Geralmente: Câmara Municipal, Assembléia Legislativa, + Câmara Distrital ou Legislativo Federal + """ + sigla = models.CharField( max_length=5 ) @@ -14,19 +20,24 @@ class TipoCasaLegislativa(models.Model): ) def __unicode__(self): return self.nome - + class CasaLegislativa(models.Model): + """ Modelo para representar uma Casa Legislativa + """ nome = models.CharField( max_length=60, help_text='Exemplo: Câmara Municipal de Pains.' ) + + # Guarda um campo para ser usado em buscas em caixa baixa e sem acento search_text = SearchField(field_names=['nome']) tipo = models.ForeignKey(TipoCasaLegislativa, verbose_name="Tipo") cnpj = models.CharField('CNPJ', max_length=32, blank=True) observacoes = models.TextField(u'observações', blank=True) presidente = models.CharField('Presidente', max_length=150, blank=True) + # Informações de contato logradouro = models.CharField( max_length=100, help_text='Avenida, rua, praça, jardim, parque...' @@ -67,13 +78,3 @@ class CasaLegislativa(models.Model): def __unicode__(self): return self.nome - - def get_presidente_nome(self): - try: - mesa = MesaDiretora.objects.get(casa_legislativa=self) - membro = mesa.membromesadiretora_set.get( - cargo__descricao__iexact='presidente' - ) - except (MesaDiretora.DoesNotExist, MembroMesaDiretora.DoesNotExist): - return '' - return membro.parlamentar.nome_completo diff --git a/sigi/apps/contatos/models.py b/sigi/apps/contatos/models.py index 62756f6..9af4495 100644 --- a/sigi/apps/contatos/models.py +++ b/sigi/apps/contatos/models.py @@ -5,6 +5,8 @@ from django.contrib.contenttypes import generic from sigi.apps.utils import SearchField class UnidadeFederativa(models.Model): + """ Modelo que representa um estado brasileiro + """ REGIAO_CHOICES = ( ('SL', 'Sul'), ('SD', 'Sudeste'), @@ -19,6 +21,7 @@ class UnidadeFederativa(models.Model): help_text='Código do estado segundo IBGE.' ) nome = models.CharField(max_length=25) + # Campo de busca em caixa baixa sem acento search_text = SearchField(field_names=['nome']) sigla = models.CharField( max_length=2, @@ -38,22 +41,29 @@ class UnidadeFederativa(models.Model): return self.nome class Municipio(models.Model): + """ Modelo para representar as cidades brasileiras + """ codigo_ibge = models.PositiveIntegerField( u'código IBGE', primary_key=True, unique=True, help_text='Código do município segundo IBGE.' ) + + # agrupamento baseado em similaridades econômicas e sociais codigo_mesorregiao = models.PositiveIntegerField( u'código mesorregião', blank=True, null=True ) + # agrupamento baseado em similaridades econômicas e sociais codigo_microrregiao = models.PositiveIntegerField( u'código microrregião', blank=True, null=True ) + + # codio designado pelo Tribunal Superior Eleitoral codigo_tse = models.PositiveIntegerField( u'código TSE', unique=True, @@ -63,10 +73,13 @@ class Municipio(models.Model): nome = models.CharField(max_length=50) search_text = SearchField(field_names=['nome', 'uf']) uf = models.ForeignKey(UnidadeFederativa, verbose_name='UF') + # verdadeiro se o município é capital do estado is_capital = models.BooleanField('capital') populacao = models.PositiveIntegerField(u'população') populacao.list_filter_range = [10000, 100000, 1000000] is_polo = models.BooleanField(u'pólo') + + # posição geográfica do município latitude = models.DecimalField( max_digits=10, decimal_places=8, @@ -95,6 +108,8 @@ class Municipio(models.Model): (self.latitude, self.longitude) class Telefone(models.Model): + """ Modelo genérico para agrupar telefones dos modulos do sistema + """ TELEFONE_CHOICES = ( ('F', 'Fixo'), ('M', 'Móvel'), @@ -117,7 +132,10 @@ class Telefone(models.Model): choices=TELEFONE_CHOICES, ) nota = models.CharField(max_length=70, blank=True) + + # guarda o tipo do objeto (classe) vinculado a esse registro content_type = models.ForeignKey(ContentType) + # identificador do registro na classe vinculado a esse registro object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') @@ -134,6 +152,9 @@ class Telefone(models.Model): return unicode(self.numero) class Contato(models.Model): + """ Modelo generico para registrar contatos vinculados aos + modulos do sistema + """ nome = models.CharField('nome completo', max_length=60) nome.alphabetic_filter = True nota = models.CharField(max_length=70, blank=True) @@ -148,7 +169,9 @@ class Contato(models.Model): null=True, ) + # guarda o tipo do objeto (classe) vinculado a esse registro content_type = models.ForeignKey(ContentType) + # identificador do registro na classe vinculado a esse registro object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') @@ -208,6 +231,8 @@ class Endereco(models.Model): ('vila','Vila'), ('outro','Outro'), ) + + # tipo do endereço obtido no site dos correios tipo = models.CharField(max_length=15,choices=TIPO_CHOICES) logradouro = models.CharField( max_length=100, @@ -215,6 +240,7 @@ class Endereco(models.Model): logradouro.alphabetic_filter = True numero= models.CharField(max_length=15, blank=True) complemento= models.CharField(max_length=15, blank=True) + # campo de texto livre referencia = models.CharField(max_length=100, blank=True) bairro = models.CharField(max_length=100, blank=True) @@ -234,7 +260,9 @@ class Endereco(models.Model): ) municipio.uf_filter = True + # guarda o tipo do objeto (classe) vinculado a esse registro content_type = models.ForeignKey(ContentType) + # identificador do registro na classe vinculado a esse registro object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') diff --git a/sigi/apps/convenios/models.py b/sigi/apps/convenios/models.py index 6900554..2ffdd89 100644 --- a/sigi/apps/convenios/models.py +++ b/sigi/apps/convenios/models.py @@ -1,30 +1,42 @@ # -*- coding: utf-8 -*- from datetime import datetime from django.db import models -#from django.contrib.contenttypes import ContentType from django.contrib.contenttypes import generic from sigi.apps.utils import SearchField class Projeto(models.Model): + """ Modelo para representar os projetos do programa + Interlegis + """ nome = models.CharField(max_length=50) sigla = models.CharField(max_length=10) - + def __unicode__(self): return self.sigla - -class Convenio(models.Model): + +class Convenio(models.Model): + """ Modelo que representa um convênio do Interlegis + com uma Casa Legislativa. + + Uma Casa Legislativa pode não ter um convênio e sim + apenas uma adesão com o Interlegis, isto é, + não tem compromissos direto com o Interlegis apenas + um pacto de colaboração entre as partes + """ casa_legislativa = models.ForeignKey( 'casas.CasaLegislativa', verbose_name='Casa Legislativa' ) + # campo de busca em caixa baixa e sem acentos search_text = SearchField(field_names=['casa_legislativa']) casa_legislativa.convenio_uf_filter = True casa_legislativa.convenio_cl_tipo_filter = True projeto = models.ForeignKey( Projeto ) + # numero designado pelo Senado Federal para o convênio num_processo_sf = models.CharField( - 'número do processo SF', + 'número do processo SF (Senado Federal)', max_length=11, blank=True, help_text='Formato: XXXXXX/XX-X.' @@ -38,7 +50,7 @@ class Convenio(models.Model): 'Aderidas', null=True, blank=True, - ) + ) data_retorno_assinatura = models.DateField( 'Conveniadas', null=True, @@ -69,15 +81,15 @@ class Convenio(models.Model): ) data_devolucao_sem_assinatura = models.DateField( 'data de devolução por falta de assinatura', - null=True, - blank=True, - help_text=u'Data de devolução por falta de assinatura', + null=True, + blank=True, + help_text=u'Data de devolução por falta de assinatura', ) data_retorno_sem_assinatura = models.DateField( - 'data do retorno sem assinatura', - null=True, - blank=True, - help_text=u'Data do retorno do convênio sem assinatura', + 'data do retorno sem assinatura', + null=True, + blank=True, + help_text=u'Data do retorno do convênio sem assinatura', ) observacao = models.CharField( null=True, @@ -102,6 +114,10 @@ class Convenio(models.Model): return str(self.id) class EquipamentoPrevisto(models.Model): + """ Modelo utilizado para registrar os equipamentos + disponibilizados para as Casas Legislativas + (foi usado na prmeira etapa do programa) + """ convenio = models.ForeignKey(Convenio, verbose_name=u'convênio') equipamento = models.ForeignKey('inventario.Equipamento') quantidade = models.PositiveSmallIntegerField(default=1) @@ -114,7 +130,11 @@ class EquipamentoPrevisto(models.Model): return '%s %s(s)' % (self.quantidade, self.equipamento) class Anexo(models.Model): + """ Modelo para giardar os documentos gerados + no processo de convênio + """ convenio = models.ForeignKey(Convenio, verbose_name=u'convênio') + # caminho no sistema para o documento anexo arquivo = models.FileField(upload_to='apps/convenios/anexo/arquivo',) descricao = models.CharField('descrição', max_length='70') data_pub = models.DateTimeField( @@ -129,28 +149,34 @@ class Anexo(models.Model): return unicode(self.arquivo.name) class UnidadeAdministrativa(models.Model): + """ Modelo para representar uma Unidade Administrativa + que pode ser um servivo do próprio Interlegis, assim como + uma unidade do Senado Federal + """ sigla = models.CharField(max_length='10') nome = models.CharField(max_length='100') def __unicode__(self): return unicode(self.sigla) - + class Tramitacao(models.Model): + """ Modelo para registrar as vias do processo de convênio e a Unidade + responsável pelo tramite (ex. colher assinaturas do secretário do senado) + """ convenio = models.ForeignKey(Convenio, verbose_name=u'convênio') unid_admin = models.ForeignKey(UnidadeAdministrativa, verbose_name=u'Unidade Administrativa') data = models.DateField() observacao = models.CharField( - 'observação', - max_length='512', - null=True, - blank=True, + 'observação', + max_length='512', + null=True, + blank=True, ) class Meta: - verbose_name_plural = u'Tramitações' + verbose_name_plural = u'Tramitações' def __unicode__(self): return unicode(self.unid_admin) - diff --git a/sigi/apps/diagnosticos/models.py b/sigi/apps/diagnosticos/models.py index 9027345..1b26ec8 100644 --- a/sigi/apps/diagnosticos/models.py +++ b/sigi/apps/diagnosticos/models.py @@ -5,10 +5,14 @@ from sigi.apps.utils import SearchField from eav.models import BaseChoice, BaseEntity, BaseSchema, BaseAttribute class Diagnostico(BaseEntity): + """ Modelo para representar unm diagnostico realizado + em uma Casa Legislativa + """ casa_legislativa = models.ForeignKey( 'casas.CasaLegislativa', verbose_name='Casa Legislativa' ) + # campo de busca em caixa baixa e sem acento search_text = SearchField(field_names=['casa_legislativa']) casa_legislativa.convenio_uf_filter = True casa_legislativa.convenio_cl_tipo_filter = True @@ -45,35 +49,55 @@ class Diagnostico(BaseEntity): return str(self.casa_legislativa) class Categoria(models.Model): + """ Modelo para representar a categoria de uma pergunta + e sua ordem na hora de exibir no formulário + """ nome= models.CharField(max_length=50) ordem = models.PositiveSmallIntegerField(blank=True, null=True) class Pergunta(BaseSchema): - categoria = models.ForeignKey(Categoria) + """ Modelo que representa uma pergunta no questionário + e sua ordem dentro da categoria + + Uma pergunta tem o nome e o tipo da resposta + """ + categoria = models.ForeignKey(Categoria,blank=True, null=True) ordem = models.PositiveSmallIntegerField(blank=True, null=True) class Meta: verbose_name, verbose_name_plural = 'pergunta', 'perguntas' class Escolha(BaseChoice): + """ Perguntas de multiplas escolhas tem as opções + cadastradas neste modelo + """ schema = models.ForeignKey(Pergunta, related_name='choices', verbose_name='pergunta') class Meta: verbose_name, verbose_name_plural = 'escolha', 'escolhas' class Resposta(BaseAttribute): + """ Modelo para guardar as respostas das perguntas + de um diagnosico + """ schema = models.ForeignKey(Pergunta, related_name='attrs', verbose_name='pergunta') choice = models.ForeignKey(Escolha, verbose_name='escolha', blank=True, null=True) class Meta: verbose_name, verbose_name_plural = 'resposta', 'respostas' class Equipe(models.Model): + """ Modelo que representa a equipe de um diagnóstico + """ diagnostico = models.ForeignKey(Diagnostico) membro = models.ForeignKey('servidores.Servidor') + # verdadeiro se o servidor é repsonsável por chefiar a equipe is_chefe = models.BooleanField() def __unicode__(self): return str(self.id) class Anexo(models.Model): + """ Modelo para representar os documentos levantados + no processo de diagnóstico. Podem ser fotos, contratos, etc. + """ diagnostico = models.ForeignKey(Diagnostico, verbose_name=u'diagnóstico') arquivo = models.FileField(upload_to='apps/diagnostico/anexo/arquivo',) descricao = models.CharField('descrição', max_length='70') diff --git a/sigi/apps/servidores/admin.py b/sigi/apps/servidores/admin.py index e2a6f2c..4c9e5a5 100644 --- a/sigi/apps/servidores/admin.py +++ b/sigi/apps/servidores/admin.py @@ -55,7 +55,26 @@ class ServidorAdmin(admin.ModelAdmin): search_fields = ('nome_completo', 'obs', 'apontamentos', 'user__email', 'user__first_name', 'user__last_name', 'user__username') - inlines= (EnderecoInline, TelefonesInline) + raw_id_fields = ('user',) + inlines= (TelefonesInline,EnderecoInline) + fieldsets = ( + (u'Autenticação', { + 'fields': ('user',), + }), + ('Cadastro', { + 'fields': ('nome_completo', 'foto', 'email_pessoal', 'rg', 'cpf', 'sexo', 'data_nascimento', 'matricula', 'ramal') + }), + ('Origem', { + 'fields': ('turno',), + }), + (u'Observações', { + 'fields': ('apontamentos', 'obs'), + }), + #('Advanced options', { + # 'classes': ('collapse',), + # 'fields': ('enable_comments', 'registration_required', 'template_name') + #}), + ) admin.site.register(Servidor, ServidorAdmin) admin.site.register(Funcao, FuncaoAdmin) diff --git a/sigi/apps/servidores/models.py b/sigi/apps/servidores/models.py index 6e392d1..9630507 100644 --- a/sigi/apps/servidores/models.py +++ b/sigi/apps/servidores/models.py @@ -4,8 +4,12 @@ from django.contrib.contenttypes import generic from django.contrib.auth.models import User class Subsecretaria(models.Model): + """ Modelo para representação das Subsecretarias do Interlegis + """ + nome = models.CharField(max_length=50) sigla = models.CharField(max_length=10) + # servidor responsavel por dirigir a Subsecretaria responsavel = models.ForeignKey('servidores.Servidor', related_name='diretor') class Meta: @@ -15,9 +19,13 @@ class Subsecretaria(models.Model): return '%s (%s)' % (unicode(self.nome), unicode(self.sigla)) class Servico(models.Model): + """ Modelo para representação dos Serviços de uma Subsecretaria + """ + nome = models.CharField(max_length=50) sigla = models.CharField(max_length=10) subsecretaria = models.ForeignKey(Subsecretaria) + # servidor responsavel por chefiar o serviço responsavel = models.ForeignKey('servidores.Servidor', related_name='chefe') class Meta: @@ -29,19 +37,29 @@ class Servico(models.Model): return '%s (%s)' % (unicode(self.nome), unicode(self.sigla)) class Servidor(models.Model): + """ Modelo para representação de um Servidor. + + Um servidor pertence a um Serviço e uma Subsecretaria os campos + deste modelo são referente as informações básicas de cadastro. + """ + SEXO_CHOICES = ( ('M', u'Masculino'), ('F', u'Feminino'), ) + TURNO_CHOICES = ( ('M', u'Manhã'), ('T', u'Tarde'), ('N', u'Noite'), ) + + # usuario responsavel pela autenticação do servidor no sistema + user = models.ForeignKey(User, unique=True) nome_completo = models.CharField(max_length=128) nome_completo.alphabetic_filter = True - user = models.ForeignKey(User, unique=True) apelido = models.CharField(max_length=50, blank=True) + # caminho no sistema para arquivo com a imagem foto = models.ImageField( upload_to='fotos/servidores', width_field='foto_largura', @@ -61,9 +79,7 @@ class Servidor(models.Model): blank=True, null=True, ) - email = models.EmailField('e-mail', blank=True, null=True) servico = models.ForeignKey('servidores.Servico', blank=True, null=True) - is_chefe = models.BooleanField() matricula = models.CharField(u'matrícula', max_length=25, blank=True, null=True) turno= models.CharField( max_length=1, @@ -71,8 +87,6 @@ class Servidor(models.Model): blank=True, null=True, ) - data_entrada = models.DateField(u'data de entrada', blank=True, null=True) - data_saida = models.DateField(u'data de saída', blank=True, null=True) data_nomeacao = models.DateField(u'data de nomeação', blank=True, null=True) ato_exoneracao = models.CharField(u'ato de exoneração',max_length=150, blank=True, null=True) cpf = models.CharField('CPF', max_length=11, blank=True, null=True) @@ -80,7 +94,8 @@ class Servidor(models.Model): obs = models.TextField(u'observação', blank=True, null=True) apontamentos = models.TextField(u'apontamentos', blank=True, null=True) - #endereco = models.ForeignKey('contatos.Endereco', blank=True, null=True) + # Informações de contato + email_pessoal = models.EmailField('e-mail pessoal', blank=True, null=True) endereco = generic.GenericRelation('contatos.Endereco') telefones = generic.GenericRelation('contatos.Telefone') ramal = models.IntegerField('ramal', blank=True, null=True) @@ -89,10 +104,31 @@ class Servidor(models.Model): ordering = ('nome_completo',) verbose_name_plural = 'servidores' + def is_chefe(): + """ Verifica se o servidor é chefe ou diretor + """ + pass + + def data_entrada(): + """ Verifica a data de entrada da função mais antiga + """ + pass + + def data_saida(): + """ Verifica a data de saída da função mais recente + de um servidor desativado + + Caso o usuário esteja ativo retorna None + """ + pass + def __unicode__(self): return self.nome_completo class Funcao(models.Model): + """ Modelo para guardar o histórico de funções dos + servidores no Interlegis + """ servidor = models.ForeignKey(Servidor) funcao = models.CharField(max_length=50) cargo = models.CharField(max_length=50, blank=True, null=True) @@ -115,6 +151,8 @@ class Funcao(models.Model): class Licenca(models.Model): + """ Modelo que representa as licenças tiradas pelos servidores + """ servidor = models.ForeignKey(Servidor) inicio_licenca = models.DateField(u'início da licença') fim_licenca = models.DateField(u'fim da licença') @@ -124,10 +162,17 @@ class Licenca(models.Model): verbose_name = u'licença' verbose_name_plural = u'licenças' + def days(): + """ Calcula a quantidade de dias da licença + """ + pass + def __unicode__(self): return str(self.id) class Ferias(models.Model): + """ Modelo que representa as férias tiradas pelos servidores + """ servidor = models.ForeignKey(Servidor) inicio_ferias = models.DateField(u'início das férias') fim_ferias = models.DateField(u'fim das férias') @@ -137,5 +182,10 @@ class Ferias(models.Model): verbose_name = u'férias' verbose_name_plural = u'férias' + def days(): + """ Calcula a quantidade de dias das férias + """ + pass + def __unicode__(self): return str(self.id)