diff --git a/sigi/apps/contatos/fixtures/initial_data.json b/sigi/apps/contatos/fixtures/initial_data.txt similarity index 100% rename from sigi/apps/contatos/fixtures/initial_data.json rename to sigi/apps/contatos/fixtures/initial_data.txt diff --git a/sigi/apps/servidores/__init__.py b/sigi/apps/servidores/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sigi/apps/servidores/admin.py b/sigi/apps/servidores/admin.py new file mode 100644 index 0000000..362d436 --- /dev/null +++ b/sigi/apps/servidores/admin.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +from django.contrib import admin +from django.contrib.contenttypes import generic + +from sigi.apps.utils.admin_widgets import AdminImageWidget +from sigi.apps.servidores.models import Servidor, Funcao, Licenca, Ferias +from sigi.apps.contatos.models import Endereco, Telefone +from sigi.apps.servidores.forms import FeriasForm, LicencaForm, FuncaoForm + +class FuncaoAdmin(admin.ModelAdmin): + form = FuncaoForm + list_display = ('servidor', 'funcao', 'cargo','inicio_funcao', 'fim_funcao') + list_filter = ('inicio_funcao', 'fim_funcao') + search_fields = ('funcao', 'cargo', 'descricao', + 'servidor__nome_completo', 'servidor__obs', 'servidor__apontamentos', + 'servidor__user__email', 'servidor__user__first_name', + 'servidor__user__last_name', 'servidor__user__username') + +class FeriasAdmin(admin.ModelAdmin): + form = FeriasForm + list_display = ('servidor', 'inicio_ferias', 'fim_ferias') + list_filter = ('inicio_ferias', 'fim_ferias') + search_fields = ('obs', + 'servidor__nome_completo', 'servidor__email_pessoal', + 'servidor__user__email', 'servidor__user__username') + +class LicencaAdmin(admin.ModelAdmin): + form = LicencaForm + list_display = ('servidor', 'inicio_licenca', 'fim_licenca') + list_filter = ('servidor', 'inicio_licenca', 'fim_licenca') + search_fields = ('obs', + 'servidor__nome_completo', 'servidor__email_pessoal', + 'servidor__user__email', 'servidor__user__username') + +class EnderecoInline(generic.GenericStackedInline): + model = Endereco + extra = 0 + raw_id_fields = ('municipio',) + +class TelefonesInline(generic.GenericTabularInline): + extra = 1 + model = Telefone + +class ServidorAdmin(admin.ModelAdmin): + def is_active(self, servidor): + return servidor.user.is_active + is_active.admin_order_field = 'user__is_active' + is_active.boolean = True + is_active.short_description = 'ativo' + + list_display = ('nome_completo', 'is_active', 'foto', 'servico', ) + list_filter = ('user', 'sexo', 'servico',) + search_fields = ('nome_completo', 'obs', 'apontamentos', + 'user__email', 'user__first_name', + 'user__last_name', 'user__username') + 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', 'data_nomeacao', 'ato_numero', 'ato_exoneracao') + }), + ('Lotação', { + 'fields': ('servico', 'turno', 'de_fora'), + }), + (u'Observações', { + 'fields': ('apontamentos', 'obs'), + }), + ) + + def lookup_allowed(self, lookup, value): + return super(ServidorAdmin, self).lookup_allowed(lookup, value) or \ + lookup in ['user__is_active__exact'] + + def formfield_for_dbfield(self, db_field, **kwargs): + if db_field.name == 'foto': + request = kwargs.pop("request", None) + kwargs['widget'] = AdminImageWidget + return db_field.formfield(**kwargs) + return super(ServidorAdmin,self).formfield_for_dbfield(db_field, **kwargs) + +admin.site.register(Servidor, ServidorAdmin) +admin.site.register(Funcao, FuncaoAdmin) +admin.site.register(Ferias, FeriasAdmin) +admin.site.register(Licenca, LicencaAdmin) diff --git a/sigi/apps/servidores/forms.py b/sigi/apps/servidores/forms.py new file mode 100644 index 0000000..f87cebc --- /dev/null +++ b/sigi/apps/servidores/forms.py @@ -0,0 +1,60 @@ +# -*- coding: utf8 -*- + +from django import forms + +from sigi.apps.utils.validators import valida_data, valida_periodo_data + +from sigi.apps.servidores.models import Ferias, Licenca, Funcao, Servidor + + +class FeriasForm(forms.ModelForm): + class Meta: + model = Ferias + + def clean(self): + data = self.cleaned_data + if valida_data(data.get('inicio_ferias'), data.get('fim_ferias')): + raise forms.ValidationError(u"""A data de início deve ser menor + que a data final. Verifique novamente""") + return data + + +class LicencaForm(forms.ModelForm): + class Meta: + model = Licenca + + def clean(self): + data = self.cleaned_data + if valida_data(data.get('inicio_licenca'), data.get('fim_licenca')): + raise forms.ValidationError(u"""A data de início deve ser menor + que a data final. Verifique novamente""") + return data + + +class FuncaoForm(forms.ModelForm): + class Meta: + model = Funcao + + def clean(self): + data = self.cleaned_data + if valida_data(data.get('inicio_funcao'), data.get('fim_funcao')): + raise forms.ValidationError(u"""A data de início deve ser menor + que a data final. Verifique + novamente""") + + # Verifica na função anterior, se o seu período é igual + # ou está entre o período da função atual. + servidor = Servidor.objects.get(nome_completo=data.get('servidor')) + if len(servidor.funcao_set.all()): + if len(servidor.funcao_set.all()) > 1: + funcao_anterior = servidor.funcao_set.all()[1] + elif len(servidor.funcao_set.all()) == 1: + funcao_anterior = servidor.funcao_set.all()[0] + + if valida_periodo_data(funcao_anterior.inicio_funcao, + funcao_anterior.fim_funcao, data.get('inicio_funcao'), + data.get('fim_funcao')): + raise forms.ValidationError(u"""Você não pode exercer + uma função no mesmo período que a anterior, como também, + não pode ser entre o período da mesma.""") + return data diff --git a/sigi/apps/servidores/management/__init__.py b/sigi/apps/servidores/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sigi/apps/servidores/management/commands/__init__.py b/sigi/apps/servidores/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sigi/apps/servidores/management/commands/migra.py b/sigi/apps/servidores/management/commands/migra.py new file mode 100644 index 0000000..ba505ad --- /dev/null +++ b/sigi/apps/servidores/management/commands/migra.py @@ -0,0 +1,236 @@ +# coding= utf-8 +import sys +import csv +import re +from datetime import datetime +from django.core.management.base import BaseCommand, CommandError +from django.contrib.auth.models import User +from sigi.apps.servidores.models import Servidor, Servico, Subsecretaria, Funcao, Ferias, Licenca +from sigi.apps.contatos.models import Municipio + +#Funcao.objects.all().delete() +#Ferias.objects.all().delete() +#Licenca.objects.all().delete() +#for u in User.objects.filter(date_joined__gte=datetime(2011, 12, 9, 10, 58, 49, 83734)).all(): +# u.servidor_set.all().delete() +# u.delete() + +class MigrationError(Exception): + pass + +class Command(BaseCommand): + help = 'Migra usuários do antigo Sistema de RH' + + def to_date(self, data): + return datetime.strptime(data, "%Y-%m-%d 00:00:00") + + def handle(self, *args, **options): + reader = csv.reader(open("/tmp/pessoal.csv"), delimiter=',', quotechar="\"") + + BRASILIA = Municipio.objects.get(codigo_ibge=5300108) + + # Read the column names from the first line of the file + fields = reader.next() + for row in reader: + # cria um dict com a primeira e a linha atual + pessoa = zip(fields, row) + p = {} + for (name, value) in pessoa: + p[name] = value.strip() + + user = None + if not p['email']: + username = '' + email = '' + elif not ('@interlegis' in p['email']): + username = p['email'].split('@')[0].strip().lower() + email = '' + else: + username = p['email'].split('@')[0].strip().lower() + email = username + '@interlegis.gov.br' + + # buscar usuário e servidor da linha atual + try: + # procuro o usuario por email do interlegis + if email: + try: user = User.objects.get(email=email) + except User.DoesNotExist: + email = username + '@interlegis.leg.br' + try: user = User.objects.get(email=email) + except User.DoesNotExist: pass + + if not user and username: + try: user = User.objects.get(username=username) + except User.DoesNotExist: + try: user = User.objects.get(username=username + "__") + except User.DoesNotExist: pass + + if not user: + if not username: + raise MigrationError + + if not email: + # cria um username a partir do email sem + # colidir com os usuarios ldap + username = username + '__' + + names = p['nome_completo'].split(' ') + first_name = names[0] + last_name = " ".join(names[1:]) + + user = User.objects.create( + username = username, + email = email, + first_name = first_name, + last_name = last_name[:30], + is_active= False + ) + + servidor = user.servidor + except Servidor.DoesNotExist: + servidor = Servidor.objects.create( + user=user, + nome_completo= "%s %s" % (user.first_name, user.last_name) + ) + except MigrationError, e: + print ", ".join(row) + continue + + # mapeando dados simples + servidor.nome_completo = p['nome_completo'] + servidor.cpf = p['cpf'] + servidor.rg = p['identidade'] + servidor.apelido = p['username'] + servidor.matricula = p['matricula'] + servidor.ato_exoneracao = p['ato_exoneracao'] + servidor.ato_numero = p['ato_numero'] + servidor.ramal = p['ramal'] + + if p['email'] and not '@interlegis' in p['email']: + servidor.email_pessoal= p['email'] + + if p['inativo']=="-1": + servidor.user.is_active = False + else: + servidor.user.is_active = True + servidor.user.save() + + if p['de_fora']=="-1": + servidor.de_fora = True + else: + servidor.de_fora = False + + if p['sexo'].upper() == 'M': + servidor.sexo = 'M' + elif p['sexo'].upper() == 'F': + servidor.sexo = 'F' + + if p['turno']=="1": + servidor.turno = 'M' + elif p['turno']=="2": + servidor.turno = 'T' + elif p['turno']=="3": + servidor.turno = 'N' + + if p['aniversario']: + servidor.data_nascimento = self.to_date(p['aniversario']) + + if p['data_nomeacao']: + servidor.data_nomeacao = self.to_date(p['data_nomeacao']) + + if p['secretaria_sigla']: + if ' - ' in p['secretaria_nome']: + secretaria_nome = p['secretaria_nome'].split(' - ')[1] + else: + secretaria_nome = p['secretaria_nome'] + + secretaria = Subsecretaria.objects.get_or_create( + sigla = p['secretaria_sigla'], + nome = secretaria_nome + )[0] + + if ' - ' in p['servico_nome']: + servico_nome = p['servico_nome'].split(' - ')[1] + else: + servico_nome = p['servico_nome'] + + servico = Servico.objects.get_or_create( + sigla = p['servico_sigla'], + nome = servico_nome + )[0] + + servico.subsecretaria = secretaria + servico.save() + servidor.servico = servico + + if p['telefone']: + try: + t = servidor.telefones.get(numero=p['telefone']) + except: + t = servidor.telefones.create(numero=p['telefone']) + t.tipo = 'F' + t.save() + + if p['celular']: + try: + t = servidor.telefones.get(numero=p['celular']) + except: + t = servidor.telefones.create(numero=p['celular']) + t.tipo = 'M' + t.save() + + if p['endereco']: + try: + e = servidor.endereco.get(logradouro=p['endereco']) + except: + e = servidor.endereco.create(logradouro=p['endereco']) + e.municipio = BRASILIA + e.bairro = p['cidade'] # bizarro mas é isso mesmo + e.cep = re.sub("\D", "", p['cep']) + e.save() + + servidor.apontamentos = p['apontamentos'] + servidor.obs = p['obs'] + + if p['cargo'] or p['funcao']: + funcao = servidor.funcao_set.get_or_create( + funcao = p['funcao'], + cargo = p['cargo'], + )[0] + + if p['data_bap_entrada']: + funcao.data_bap_entrada = self.to_date(p['data_bap_entrada']) + + if p['data_bap_saida']: + funcao.data_bap_saida = self.to_date(p['data_bap_saida']) + + if p['data_entrada']: + funcao.inicio_funcao = self.to_date(p['data_entrada']) + + if p['data_saida']: + funcao.fim_funcao = self.to_date(p['data_saida']) + + funcao.bap_entrada = p['bap_entrada'] + funcao.bap_saida = p['bap_saida'] + funcao.save() + + if re.search(r'estagi.ri[o|a]',p['cargo'],re.I): + #TODO inserir dados de estagio + pass + + if p['inicio_ferias'] and p['final_ferias']: + servidor.ferias_set.get_or_create( + inicio_ferias = self.to_date(p['inicio_ferias']), + fim_ferias = self.to_date(p['final_ferias']), + obs = p['obs_ferias'] + ) + + if p['inicio_licenca'] and p['fim_licenca']: + servidor.licenca_set.get_or_create( + inicio_licenca = self.to_date(p['inicio_licenca']), + fim_licenca = self.to_date(p['fim_licenca']), + obs = p['obs_licenca'] + ) + + servidor.save() + diff --git a/sigi/apps/servidores/management/commands/sync_ldap.py b/sigi/apps/servidores/management/commands/sync_ldap.py new file mode 100644 index 0000000..9e5b391 --- /dev/null +++ b/sigi/apps/servidores/management/commands/sync_ldap.py @@ -0,0 +1,100 @@ +# coding= utf-8 +import ldap +from django.core.management.base import BaseCommand, CommandError +from django.contrib.auth.models import User, Group +from sigi.settings import * +from sigi.apps.servidores.models import Servidor + +class Command(BaseCommand): + help = 'Sincroniza Usuários e Servidores com o LDAP' + + def handle(self, *args, **options): + self.sync_groups() + self.sync_users() + + def get_ldap_groups(self): + filter = "(&(objectclass=Group))" + values = ['cn',] + l = ldap.initialize(AUTH_LDAP_SERVER_URI) + l.protocol_version = ldap.VERSION3 + l.simple_bind_s(AUTH_LDAP_BIND_DN.encode('utf-8'),AUTH_LDAP_BIND_PASSWORD) + result_id = l.search(AUTH_LDAP_GROUP, ldap.SCOPE_SUBTREE, filter, values) + result_type, result_data = l.result(result_id, 1) + l.unbind() + return result_data + + def get_ldap_users(self): + filter = "(&(objectclass=user))" + values = ['sAMAccountName', 'userPrincipalName', 'givenName', 'sn', 'cn' ] + l = ldap.initialize(AUTH_LDAP_SERVER_URI) + l.protocol_version = ldap.VERSION3 + l.simple_bind_s(AUTH_LDAP_BIND_DN.encode('utf-8'),AUTH_LDAP_BIND_PASSWORD) + result_id = l.search(AUTH_LDAP_USER.encode('utf-8'), ldap.SCOPE_SUBTREE, filter, values) + result_type, result_data = l.result(result_id, 1) + l.unbind() + return result_data + + def sync_groups(self): + ldap_groups = self.get_ldap_groups() + for ldap_group in ldap_groups: + try: group_name = ldap_group[1]['cn'][0] + except: pass + else: + try: group = Group.objects.get(name=group_name) + except Group.DoesNotExist: + group = Group(name=group_name) + group.save() + print "Group '%s' created." % group_name + print "Groups are synchronized." + + def sync_users(self): + ldap_users = self.get_ldap_users() + for ldap_user in ldap_users: + try: username = ldap_user[1]['sAMAccountName'][0] + except: pass + else: + try: email = ldap_user[1]['userPrincipalName'][0] + except: email = '' + try: first_name = ldap_user[1]['givenName'][0] + except: first_name = username + try: last_name = ldap_user[1]['sn'][0][:30] + except: last_name = '' + try: user = User.objects.get(username=username) + except User.DoesNotExist: + try: + user = User.objects.get(email=email) + user.username = username + except User.DoesNotExist: + user = User.objects.create_user( + username = username, + email = email + ) + user.first_name = first_name + user.last_name = last_name + print "User '%s' created." % username + try: nome_completo = ldap_user[1]['cn'][0] + except: nome_completo = '' + try: + servidor = user.servidor + if not servidor.nome_completo == nome_completo.decode('utf8'): + servidor.nome_completo = nome_completo + print "Servidor '%s' updated." % nome_completo + except Servidor.DoesNotExist: + try: servidor = Servidor.objects.get(nome_completo=nome_completo) + except Servidor.DoesNotExist: + servidor = user.servidor_set.create(nome_completo=nome_completo) + print "Servidor '%s' created." % nome_completo + else: + if not user.email == email.decode('utf8'): + user.email = email + print "User '%s' email updated." % username + if not user.first_name == first_name.decode('utf8'): + user.first_name = first_name + print "User '%s' first name updated." % username + if not user.last_name == last_name.decode('utf8'): + user.last_name = last_name + print "User '%s' last name updated." % username + servidor.user = user + servidor.save() + user.save() + print "Users are synchronized." diff --git a/sigi/apps/servidores/models.py b/sigi/apps/servidores/models.py new file mode 100644 index 0000000..6e8bae2 --- /dev/null +++ b/sigi/apps/servidores/models.py @@ -0,0 +1,223 @@ +# -*- coding: utf-8 -*- +from django.db import models +from django.db.models.signals import post_save +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=250, null=True) + sigla = models.CharField(max_length=10, null=True) + # servidor responsavel por dirigir a Subsecretaria + responsavel = models.ForeignKey('servidores.Servidor', related_name='diretor', null=True) + + class Meta: + ordering = ('nome',) + + def __unicode__(self): + 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=250, null=True) + sigla = models.CharField(max_length=10, null=True) + subsecretaria = models.ForeignKey(Subsecretaria, null=True) + # servidor responsavel por chefiar o serviço + responsavel = models.ForeignKey('servidores.Servidor', related_name='chefe', null=True) + + class Meta: + ordering = ('nome',) + verbose_name = 'serviço' + verbose_name_plural = 'serviços' + + def __unicode__(self): + 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) + user.is_active__filter = True + nome_completo = models.CharField(max_length=128) + nome_completo.alphabetic_filter = 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', + height_field='foto_altura', + blank=True + ) + foto_largura = models.SmallIntegerField(editable=False, null=True) + foto_altura = models.SmallIntegerField(editable=False, null=True) + sexo = models.CharField( + max_length=1, + choices=SEXO_CHOICES, + blank=True, + null=True, + ) + data_nascimento = models.DateField( + 'data de nascimento', + blank=True, + null=True, + ) + servico = models.ForeignKey('servidores.Servico', blank=True, null=True) + matricula = models.CharField(u'matrícula', max_length=25, blank=True, null=True) + turno= models.CharField( + max_length=1, + choices=TURNO_CHOICES, + blank=True, + null=True, + ) + de_fora = models.BooleanField(default=False) + 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) + ato_numero = 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) + rg = models.CharField('RG', max_length=25, blank=True, null=True) + obs = models.TextField(u'observação', blank=True, null=True) + apontamentos = models.TextField(u'apontamentos', blank=True, null=True) + + # Informações de contato + email_pessoal = models.EmailField('email pessoal', blank=True, null=True) + endereco = generic.GenericRelation('contatos.Endereco') + telefones = generic.GenericRelation('contatos.Telefone') + ramal = models.CharField(max_length=25, blank=True, null=True) + + class Meta: + ordering = ('nome_completo',) + verbose_name_plural = 'servidores' + + def is_chefe(self): + """ Verifica se o servidor é chefe ou diretor + """ + pass + + def data_entrada(self): + """ Verifica a data de entrada da função mais antiga + """ + pass + + def data_saida(self): + """ Verifica a data de saída da função mais recente + de um servidor desativado + + Caso o usuário esteja ativo retorna None + """ + pass + + @property + def diagnosticos(self): + """ Retorna todos os diagnosticos que este servidor + participa, isto é, como responsavel ou parte da equipe + """ + diagnosticos = set(self.diagnostico_set.filter(publicado=True).all()) + + for equipe in self.equipe_set.all(): + diagnosticos.add(equipe.diagnostico) + + return list(diagnosticos) + + def __unicode__(self): + return self.nome_completo + +# Soluçao alternativa para extender o usuário do django +# Acessa do servidor de um objeto user criando um profile +# baseado nos dados do LDAP +User.servidor = property(lambda user: Servidor.objects.get(user=user)) + +# Sinal para ao criar um usuário criar um servidor +# baseado no nome contino no LDAP +def create_user_profile(sender, instance, created, **kwargs): + if created: + Servidor.objects.create( + user=instance, + nome_completo= "%s %s" % (instance.first_name, instance.last_name) + ) + +post_save.connect(create_user_profile, sender=User) + +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=250, null=True) + cargo = models.CharField(max_length=250, null=True) + inicio_funcao = models.DateField(u'início da função', null=True) + fim_funcao = models.DateField(u'fim da função', blank=True, null=True) + descricao = models.TextField(u'descrição', blank=True, null=True) + + bap_entrada = models.CharField('BAP de entrada',max_length=50, blank=True, null=True) + data_bap_entrada = models.DateField('data BAP de entrada', blank=True, null=True) + + bap_saida = models.CharField(u'BAP de saída',max_length=50, blank=True, null=True) + data_bap_saida = models.DateField(u'data BAP de saída', blank=True, null=True) + + class Meta: + verbose_name = u'função' + verbose_name_plural = u'funções' + + def __unicode__(self): + return str(self.id) + + +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') + obs = models.TextField(u'observação', blank=True, null=True) + + class Meta: + 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') + obs = models.TextField(u'observação', blank=True, null=True) + + class Meta: + 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) diff --git a/sigi/apps/servidores/views.py b/sigi/apps/servidores/views.py new file mode 100644 index 0000000..bef9289 --- /dev/null +++ b/sigi/apps/servidores/views.py @@ -0,0 +1,33 @@ +# -*- coding: utf8 -*- + +import new +from django.template import RequestContext +from django.shortcuts import render_to_response, get_object_or_404, redirect +from django.db.models import Avg, Max, Min, Count +from sigi.apps.servidores.models import Servidor, Funcao +from sigi.shortcuts import render_to_pdf + +def servidores_por_funcao(request): + report = Funcao.objects.values('funcao').annotate(funcao__count=Count('funcao')).order_by('funcao__count') + total = Funcao.objects.count() + + context = RequestContext(request, { + 'pagesize':'A4', + 'report': report, + 'total': total + }) + + return render_to_pdf('servidores/servidores_por_funcao.html', context) + +def servidores_por_cargo(request): + report = Funcao.objects.values('cargo').annotate(cargo__count=Count('cargo')).order_by('cargo__count') + total = Funcao.objects.count() + + context = RequestContext(request, { + 'pagesize':'A4', + 'report': report, + 'total': total + }) + + return render_to_pdf('servidores/servidores_por_cargo.html', context) + diff --git a/sigi/settings.py b/sigi/settings.py index 6ba1248..eac5743 100644 --- a/sigi/settings.py +++ b/sigi/settings.py @@ -39,6 +39,7 @@ INSTALLED_APPS = ( # Local apps 'sigi.apps.contatos', + 'sigi.apps.servidores', ) MIDDLEWARE_CLASSES = (