diff --git a/.pydevproject b/.pydevproject
index f3f5391..a2ba8c5 100644
--- a/.pydevproject
+++ b/.pydevproject
@@ -1,5 +1,6 @@
-
+
+
@@ -34,12 +35,13 @@
- /sigi
-
+/sigi
+/sigi/sigi
+
-
\ No newline at end of file
+
diff --git a/sigi/apps/servicos/admin.py b/sigi/apps/servicos/admin.py
index b333ada..181f632 100644
--- a/sigi/apps/servicos/admin.py
+++ b/sigi/apps/servicos/admin.py
@@ -1,30 +1,148 @@
# -*- coding: utf-8 -*-
-
from django.contrib import admin
-from django.contrib.contenttypes import generic
-from sigi.apps.contatos.models import Contato
-from sigi.apps.servicos.models import Servico
-from sigi.apps.servicos.models import DominioLeg
-
-class ContatosInline(generic.GenericTabularInline):
- model = Contato
- extra = 2
- raw_id_fields = ('municipio',)
- verbose_name = 'colaborador Interlegis'
- verbose_name_plural = 'colaboradores Interlegis'
+from sigi.apps.servicos.models import Servico, LogServico, CasaAtendida, TipoServico
+#from sigi.apps.casas.models import Funcionario
+from sigi.apps.casas.admin import FuncionariosInline
+from django.http import Http404, HttpResponseRedirect
+from django.forms.models import ModelForm
+from django.utils.encoding import force_unicode
+from django.utils.translation import ugettext as _
+from django.core.urlresolvers import reverse
+from apps.casas.models import CasaLegislativa
+
+#---------------- inlines ---------------------
+class LogServicoInline(admin.StackedInline):
+ model = LogServico
+ Fieldset = ((None, {'fields': (('data', 'descricao'), 'log')}))
+ extra = 1
+# --------------- forms -----------------------
+class ServicoFormAdmin(ModelForm):
+ class Meta:
+ model = Servico
+
+ def __init__(self, *args, **kwargs):
+ super(ServicoFormAdmin, self).__init__(*args, **kwargs)
+
+ self.fields['contato_tecnico'].choices = ()
+ self.fields['contato_administrativo'].choices = ()
+
+ if self.instance.casa_legislativa_id:
+ id_casa = self.instance.casa_legislativa_id
+ elif kwargs.has_key('initial') and kwargs['initial'].has_key('id_casa'):
+ id_casa = kwargs['initial']['id_casa']
+ self.instance.casa_legislativa_id = id_casa
+ else:
+ id_casa = None
+
+ if id_casa:
+ casa = CasaAtendida.objects.get(pk=id_casa)
+ contatos = [(f.id, unicode(f)) for f in casa.funcionario_set.all()]
+ self.fields['contato_tecnico'].choices = contatos
+ self.fields['contato_administrativo'].choices = contatos
+
+#---------------- admins ----------------------
+class TipoServicoAdmin(admin.ModelAdmin):
+ list_display = ('id', 'sigla', 'nome', )
+ ordering = ['id']
+
class ServicoAdmin(admin.ModelAdmin):
- date_hierarchy = 'data_inicio'
- inlines = (ContatosInline,)
- list_display = ('id', 'titulo', 'tipo', 'convenio', 'situacao')
- list_filter = ('tipo','situacao', 'avaliacao')
- raw_id_fields = ('convenio',)
- search_fields = ('titulo', 'tipo', 'descricao')
-class DominiolegAdmin(admin.ModelAdmin):
- model = DominioLeg
- date_hierarchy = 'data_preenchimento'
- list_display = ('id', 'dominio', 'contato_administrativo', 'contato_tecnico', 'data_preenchimento', 'data_recebimento', 'data_atendimento',)
- search_fields = ('dominio',)
+ form = ServicoFormAdmin
+ list_display = ('casa_legislativa', 'tipo_servico', 'hospedagem_interlegis', 'data_ativacao', 'data_desativacao',)
+ fieldsets = (( None, {
+ 'fields': ('casa_legislativa', 'data_ativacao',)
+ }),
+ ( 'Serviço', {
+ 'fields': ('tipo_servico', ('url', 'hospedagem_interlegis'), ('nome_servidor', 'porta_servico', 'senha_inicial'),)
+ }),
+ ( 'Contatos', {
+ 'fields': ('contato_tecnico', 'contato_administrativo',)
+ }),
+ ( 'Alterações', {
+ 'fields': ('data_alteracao', 'data_desativacao', 'motivo_desativacao',)
+ }))
+ readonly_fields = ('casa_legislativa', 'data_ativacao', 'data_alteracao')
+
+ inlines = (LogServicoInline,)
+
+ def add_view(self, request, form_url='', extra_context=None):
+ id_casa = request.GET.get('id_casa', None)
+
+ if not id_casa:
+ raise Http404
+
+ return super(ServicoAdmin, self).add_view(request, form_url, extra_context=extra_context)
+
+ def response_add(self, request, obj):
+ opts = obj._meta
+ msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
+
+ if request.POST.has_key("_addanother"):
+ self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
+ return HttpResponseRedirect(request.path + '?id_casa=%s' % (obj.casa_legislativa.id,))
+ elif request.POST.has_key("_save"):
+ self.message_user(request, msg)
+ return HttpResponseRedirect(reverse('admin:servicos_casaatendida_change', args=[obj.casa_legislativa.id]))
+
+ return super(ServicoAdmin, self).response_add(request, obj)
+
+ def response_change(self, request, obj):
+ opts = obj._meta
+ msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)}
+
+ if request.POST.has_key("_addanother"):
+ self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name)))
+ return HttpResponseRedirect("../add/?id_casa=%s" % (obj.casa_legislativa.id,))
+ elif request.POST.has_key("_save"):
+ self.message_user(request, msg)
+ return HttpResponseRedirect(reverse('admin:servicos_casaatendida_change', args=[obj.casa_legislativa.id]))
+
+ return super(ServicoAdmin, self).response_change(request, obj)
+
+ def save_form(self, request, form, change):
+ obj = super( ServicoAdmin, self).save_form(request, form, change)
+
+ if not change:
+ id_casa = request.GET.get('id_casa', None)
+
+ if not id_casa:
+ raise Http404
+
+ obj.casa_legislativa = CasaAtendida.objects.get(pk=id_casa)
+
+ return obj
+
+class ContatosInline(FuncionariosInline):
+ can_delete = False # Equipe do SEIT não pode excluir pessoas de contato
+
+class CasaAtendidaAdmin(admin.ModelAdmin):
+ actions = None
+ list_display = ('codigo_interlegis', 'nome', 'servicos',)
+ ordering = ['nome']
+ fieldsets = (
+ ('Casa legislativa', {
+ 'fields': (('codigo_interlegis', 'nome'), ('logradouro', 'bairro', 'municipio', 'cep'), ('email', 'pagina_web'))
+ })
+ ,)
+ readonly_fields = ('nome', 'logradouro', 'bairro', 'municipio', 'cep')
+ inlines = (ContatosInline,)
+ list_filter = ('tipo', 'municipio')
+ search_fields = ('search_text','cnpj', 'bairro', 'logradouro',
+ 'cep', 'municipio__nome', 'municipio__uf__nome',
+ 'municipio__codigo_ibge', 'pagina_web', 'observacoes')
+
+ def change_view(self, request, object_id, extra_context=None):
+ # Se a Casa ainda não é atendida, gerar o código interlegis para ela
+ # Assim ela passa a ser uma casa atendida
+ casa = CasaLegislativa.objects.get(id=object_id)
+
+ if casa.codigo_interlegis == '':
+ casa.gerarCodigoInterlegis()
+
+ return super(CasaAtendidaAdmin, self).change_view(request, object_id, extra_context=extra_context)
+
+ def has_add_permission(self, request):
+ return False # Nunca é permitido inserir uma nova Casa Legislativa por aqui
-admin.site.register(DominioLeg, DominiolegAdmin)
-admin.site.register(Servico, ServicoAdmin)
\ No newline at end of file
+ def has_delete_permission(self, request, obj=None):
+ return False # Nunca deletar casas por aqui
\ No newline at end of file
diff --git a/sigi/apps/servicos/fixtures/initial_data.json b/sigi/apps/servicos/fixtures/initial_data.json
new file mode 100644
index 0000000..4671d13
--- /dev/null
+++ b/sigi/apps/servicos/fixtures/initial_data.json
@@ -0,0 +1 @@
+[{"pk": 1, "model": "servicos.tiposervico", "fields": {"template_email_altera": "Seu Portal Modelo foi alterado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha \u00e9 {senha}. Altere sua senha no primeiro acesso.", "sigla": "PM", "template_email_ativa": "Seu Portal Modelo foi ativado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha inicial \u00e9 {senha}. Altere sua senha no primeiro acesso.", "template_email_desativa": "Seu Portal Modelo foi desativado com sucesso. O endere\u00e7o de acesso era {url}.\r\nO motivo do cancelamento foi: {motivo}", "nome": "Portal Modelo"}}, {"pk": 2, "model": "servicos.tiposervico", "fields": {"template_email_altera": "Seu SAPL foi alterado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha \u00e9 {senha}. Altere sua senha no primeiro acesso.", "sigla": "SAPL", "template_email_ativa": "Seu SAPL foi ativado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha inicial \u00e9 {senha}. Altere sua senha no primeiro acesso.", "template_email_desativa": "Seu SAPL foi desativado com sucesso. O endere\u00e7o de acesso era {url}.\r\nO motivo do cancelamento foi: {motivo}", "nome": "Hospedagem SAPL"}}, {"pk": 3, "model": "servicos.tiposervico", "fields": {"template_email_altera": "Seu SAAP foi alterado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha \u00e9 {senha}. Altere sua senha no primeiro acesso.", "sigla": "SAAP", "template_email_ativa": "Seu SAAP foi ativado com sucesso. O endere\u00e7o de acesso \u00e9 {url} e a senha inicial \u00e9 {senha}. Altere sua senha no primeiro acesso.", "template_email_desativa": "Seu SAAP foi desativado com sucesso. O endere\u00e7o de acesso era {url}.\r\nO motivo do cancelamento foi: {motivo}", "nome": "Hospedagem SAAP"}}]
\ No newline at end of file
diff --git a/sigi/apps/servicos/models.py b/sigi/apps/servicos/models.py
index 706bdb1..4172283 100644
--- a/sigi/apps/servicos/models.py
+++ b/sigi/apps/servicos/models.py
@@ -1,78 +1,117 @@
# -*- coding: utf-8 -*-
from django.db import models
-from django.contrib.contenttypes import generic
-from sigi.apps.casas.models import CasaLegislativa
+from sigi.apps.casas.models import CasaLegislativa, Funcionario
from datetime import date
+from django.core.mail import send_mail
+from sigi.settings import DEFAULT_FROM_EMAIL
-class Servico(models.Model):
- SITUACAO_CHOICES = (
- ('P', 'Pendente'),
- ('A', 'Em andamento'),
- ('E', 'Executado'),
- ('D', 'Demanda'),
- ('C', 'Cancelado'),
- )
- AVALIACAO_CHOICES = (
- (4, 'Ótimo'),
- (3, 'Bom'),
- (2, 'Regular'),
- (1, 'Ruim'),
- )
- titulo = models.CharField('título', max_length=60)
- tipo = models.CharField(max_length=30)
- descricao = models.TextField(u'descrição')
- convenio = models.ForeignKey('convenios.Convenio', verbose_name='Convênio')
- colaboradores = generic.GenericRelation('contatos.Contato')
- data_inicio = models.DateField(
- u'início',
- blank=True,
- null=True,
- help_text = 'Início da realização do serviço.',
- )
- data_fim = models.DateField(
- 'fim',
- blank=True,
- null=True,
- help_text = 'Fim da realização do serviço.',
- )
- situacao = models.CharField(
- u'situação',
- max_length=1,
- choices=SITUACAO_CHOICES
- )
- avaliacao = models.PositiveSmallIntegerField(
- u'avaliação',
- choices=AVALIACAO_CHOICES,
- blank=True,
- null=True,
- help_text='Avaliação que o serviço obteve, quando aplicável.'
- )
+class TipoServico(models.Model):
+ email_help = '''Use:
+ {url} para incluir a URL do serviço,
+ {senha} para incluir a senha inicial do serviço'''
+ nome = models.CharField('Nome', max_length=60)
+ sigla = models.CharField('Sigla', max_length='12')
+ template_email_ativa = models.TextField('Template de email de ativação', help_text = email_help, blank=True)
+ template_email_altera = models.TextField('Template de email de alteração', help_text = email_help, blank=True)
+ template_email_desativa = models.TextField('Template de email de desativação', help_text = email_help + '
{motivo} para incluir o motivo da desativação do serviço', blank=True)
class Meta:
- verbose_name = 'serviço'
- verbose_name_plural = 'serviços'
-
+ verbose_name = 'Tipo de serviço'
+ verbose_name_plural = 'Tipos de serviço'
+
def __unicode__(self):
- return str(self.titulo)
+ return self.nome;
-class DominioLeg(models.Model):
- casa_legislativa = models.OneToOneField(CasaLegislativa)
- dominio = models.URLField('Domínio', verify_exists=False)
- contato_administrativo = models.CharField('Contato administrativo', max_length=60)
- telefone_administrativo = models.CharField('Telefone administrativo', max_length=10, help_text='Somente números: ddaaaannnn.')
- email_administrativo = models.EmailField('e-mail')
- contato_tecnico = models.CharField('Contato técnico', max_length=60)
- telefone_tecnico = models.CharField('Telefone administrativo', max_length=10, help_text='Somente números: ddaaaannnn.')
- email_tecnico = models.EmailField('e-mail')
- data_preenchimento = models.DateField('Data de preenchimento', default=date.today)
- data_recebimento = models.DateField('Data de recebimento', null=True, blank=True)
- data_atendimento = models.DateField('Data de atendimento', null=True, blank=True)
+class Servico(models.Model):
+ casa_legislativa = models.ForeignKey(CasaLegislativa, verbose_name='Casa legislativa')
+ tipo_servico = models.ForeignKey(TipoServico, verbose_name='Tipo de serviço')
+ contato_tecnico = models.ForeignKey(Funcionario, verbose_name='Contato técnico', related_name='contato_tecnico')
+ contato_administrativo = models.ForeignKey(Funcionario, verbose_name='Contato administrativo', related_name='contato_administrativo')
+ url = models.URLField('URL do serviço', verify_exists=False, blank=True)
+ hospedagem_interlegis = models.BooleanField('Hospedagem no Interlegis?')
+ nome_servidor = models.CharField('Hospedado em', max_length=60, blank=True, help_text='Se hospedado no Interlegis, informe o nome do servidor.
Senão, informe o nome do provedor de serviços.')
+ porta_servico = models.PositiveSmallIntegerField('Porta de serviço (instância)', blank=True, null=True)
+ senha_inicial = models.CharField('Senha inicial', max_length=33, blank=True)
+ data_ativacao = models.DateField('Data de ativação', default=date.today)
+ data_alteracao = models.DateField('Data da última alteração', blank=True, null=True, auto_now=True)
+ data_desativacao = models.DateField('Data de desativação', blank=True, null=True)
+ motivo_desativacao = models.TextField('Motivo da desativação', blank=True)
- class Meta:
- verbose_name = 'Registro de domínio .leg.br'
- verbose_name_plural = 'Registros de domínios .leg.br'
+ def __unicode__(self):
+ return "%s (%s)" % (self.tipo_servico.nome, 'ativo' if self.data_desativacao is None else 'Desativado')
+
+ def save(self, *args, **kwargs):
+ # Reter o objeto original para verificar mudanças
+
+ if self.id is not None:
+ original = Servico.objects.get(id=self.id)
+
+ if self.id is None:
+ # Novo serviço, email de ativação
+ subject = 'INTERLEGIS - Ativação de serviço %s' % (self.tipo_servico.nome,)
+ body = self.tipo_servico.template_email_ativa
+ elif self.data_desativacao is not None and original.data_desativacao is None:
+ # Serviço foi desativado. Email de desativação
+ subject = 'INTERLEGIS - Desativação de serviço %s' % (self.tipo_servico.nome,)
+ body = self.tipo_servico.template_email_desativa
+ elif (self.tipo_servico != original.tipo_servico or
+ self.contato_tecnico != original.contato_tecnico or
+ self.url != original.url or
+ self.nome_servidor != original.nome_servidor or
+ self.senha_inicial != original.senha_inicial):
+ # Serviço foi alterado
+ subject = 'INTERLEGIS - Alteração de serviço %s' % (self.tipo_servico.nome,)
+ body = self.tipo_servico.template_email_altera
+ else:
+ # Salvar o Servico
+ super(Servico, self).save(*args, **kwargs)
+ return # sem enviar email
+
+ # Prepara e envia o email
+ body = body.replace('{url}', self.url) \
+ .replace('{senha}', self.senha_inicial) \
+ .replace('{motivo}', self.motivo_desativacao)
+
+# send_mail(subject, body, DEFAULT_FROM_EMAIL, \
+# (self.contato_tecnico.email,), fail_silently=False)
+ # Salvar o Servico
+ super(Servico, self).save(*args, **kwargs)
+
+ return
+
+class LogServico(models.Model):
+ servico = models.ForeignKey(Servico, verbose_name='Serviço')
+ descricao = models.CharField('Breve descrição da ação', max_length=60)
+ data = models.DateField('Data da ação', default=date.today)
+ log = models.TextField('Log da ação')
+
def __unicode__(self):
- return str(self.dominio)
+ return "%s (%s)" % (self.descricao, self.data)
+ class Meta:
+ verbose_name = 'Log do serviço'
+ verbose_name_plural = 'Logs do serviço'
+
+class CasaAtendidaManager(models.Manager):
+ def get_query_set(self):
+ qs = super(CasaAtendidaManager, self).get_query_set()
+ qs = qs.exclude(codigo_interlegis='')
+ return qs
+
+class CasaAtendida(CasaLegislativa):
+ class Meta:
+ proxy = True
+ verbose_name_plural = 'Casas atendidas'
+
+ objects = CasaAtendidaManager()
+ @property
+ def servicos(self):
+ qs = Servico.objects.filter(casa_legislativa=self.id)
+ result = []
+
+ for servico in qs:
+ result.append(unicode(servico))
+
+ return ", ".join(result)
\ No newline at end of file
diff --git a/sigi/sites.py b/sigi/sites.py
index c5041bb..b3ffeac 100644
--- a/sigi/sites.py
+++ b/sigi/sites.py
@@ -14,7 +14,8 @@ from sigi.apps.inventario.admin import (Fornecedor, FornecedorAdmin, Fabricante,
EquipamentoAdmin, TipoEquipamento,
TipoEquipamentoAdmin, ModeloEquipamento,
ModeloEquipamentoAdmin, Bem, BemAdmin)
-from sigi.apps.servicos.admin import Servico, ServicoAdmin, DominioLeg, DominiolegAdmin
+from sigi.apps.servicos.admin import (TipoServico, TipoServicoAdmin, CasaAtendida,
+ CasaAtendidaAdmin, Servico, ServicoAdmin)
from sigi.apps.mesas.admin import (Legislatura, LegislaturaAdmin, Coligacao,
ColigacaoAdmin, ComposicaoColigacao,
ComposicaoColigacaoAdmin, SessaoLegislativa,
@@ -75,8 +76,9 @@ default.register(Equipamento, EquipamentoAdmin)
default.register(Bem, BemAdmin)
# sigi.apps.servicos
+default.register(TipoServico, TipoServicoAdmin)
default.register(Servico, ServicoAdmin)
-default.register(DominioLeg, DominiolegAdmin)
+default.register(CasaAtendida, CasaAtendidaAdmin)
# sigi.apps.mesas
default.register(Legislatura, LegislaturaAdmin)
diff --git a/sigi/templates/admin/servicos/casaatendida/change_form.html b/sigi/templates/admin/servicos/casaatendida/change_form.html
new file mode 100644
index 0000000..7b55bf5
--- /dev/null
+++ b/sigi/templates/admin/servicos/casaatendida/change_form.html
@@ -0,0 +1,42 @@
+{% extends "admin/change_form.html" %}
+{% load i18n admin_modify adminmedia %}
+
+{% block after_related_objects %}
+{{ block.super }}
+
+{% endblock %}
\ No newline at end of file
diff --git a/sigi/templates/admin/servicos/casaatendida/change_list.html b/sigi/templates/admin/servicos/casaatendida/change_list.html
new file mode 100644
index 0000000..49c451f
--- /dev/null
+++ b/sigi/templates/admin/servicos/casaatendida/change_list.html
@@ -0,0 +1,26 @@
+{% extends "admin/change_list.html" %}
+{% load adminmedia admin_list i18n %}
+
+{% block extrahead %}
+{{ block.super }}
+
+
+{% endblock %}
+
+{% block object-tools %}
+
+
+{% endblock %}
diff --git a/sigi/urls.py b/sigi/urls.py
index ec38f1e..7645913 100644
--- a/sigi/urls.py
+++ b/sigi/urls.py
@@ -87,7 +87,8 @@ urlpatterns = patterns(
(r'^sigi/api/diagnosticos/$',
'sigi.apps.diagnosticos.views.grafico_api'),
# automatic interface based on admin
- (r'^sigi/(.*)', sites.default.root),
+ #(r'^sigi/(.*)', sites.default.root),
+ (r'^sigi/', include(sites.default.urls)),
)
if settings.DEBUG: