mirror of https://github.com/interlegis/sigi.git
Felipe Vieira
13 years ago
54 changed files with 2168 additions and 167 deletions
@ -0,0 +1,14 @@ |
|||
form .aligned label { |
|||
float: none; |
|||
width: 100%; |
|||
} |
|||
form .aligned ul { |
|||
margin-left: 0px; |
|||
padding-left: 0px; |
|||
} |
|||
form .aligned ul li { |
|||
list-style: none; |
|||
} |
|||
form .form-row.data_visita_inicio { |
|||
float: left; |
|||
} |
@ -0,0 +1,27 @@ |
|||
div.ui-field-contain input.ui-input-text, div.ui-field-contain textarea.ui-input-text, div.ui-field-contain .ui-input-search { |
|||
width: 97%; |
|||
display: inline-block; |
|||
} |
|||
div.ui-field-contain.phone input.ui-input-text { |
|||
width: 65%; |
|||
display: inline-block; |
|||
} |
|||
div.ui-field-contain.phone .ui-select { |
|||
width: 30%; |
|||
float: left; |
|||
margin: -0.5em 0; |
|||
} |
|||
div.ui-field-contain.phone .ui-select .ui-btn-text { |
|||
text: left; |
|||
padding-left: 0.2em; |
|||
} |
|||
|
|||
div.ui-field-contain.phone .ui-select .ui-btn { |
|||
margin: 0.5em 10px 0.5em 0px; |
|||
} |
|||
|
|||
div.ui-field-contain.phone .ui-select .ui-btn-inner { |
|||
padding-left: 15px; |
|||
} |
|||
|
|||
|
@ -0,0 +1,26 @@ |
|||
|
|||
/* Destacando a ultima categoria visitada */ |
|||
.ui-btn-last-c { |
|||
border: 1px solid #155678; |
|||
background: #4596CE; |
|||
font-weight: bold; |
|||
cursor: pointer; |
|||
text-shadow: 0 -1px 1px #145072; |
|||
text-decoration: none; |
|||
background-image: -webkit-gradient(linear,left top,left bottom,from(#85bae4),to(#5393c5)); |
|||
background-image: -webkit-linear-gradient(#85bae4,#5393c5); |
|||
background-image: -moz-linear-gradient(#85bae4,#5393c5); |
|||
background-image: -ms-linear-gradient(#85bae4,#5393c5); |
|||
background-image: -o-linear-gradient(#85bae4,#5393c5); |
|||
background-image: linear-gradient(#85bae4,#5393c5); |
|||
font-family: Helvetica,Arial,sans-serif; |
|||
} |
|||
|
|||
.ui-btn-last-c a.ui-link-inherit { |
|||
color: white; |
|||
} |
|||
|
|||
/* Definindo as categorias que foram lidas */ |
|||
.ui-li-heading-read { |
|||
font-weight: normal !important; |
|||
} |
@ -0,0 +1,13 @@ |
|||
.ui-field-contain input.ui-input-text, .ui-field-contain textarea.ui-input-text, .ui-field-contain .ui-input-search { |
|||
width: 97%; |
|||
display: inline-block; |
|||
} |
|||
|
|||
.ui-field-contain ul { |
|||
-webkit-padding-start: 0; |
|||
} |
|||
|
|||
span.errors { |
|||
display: block; |
|||
color: red; |
|||
} |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 7.3 KiB |
@ -0,0 +1,97 @@ |
|||
// cntabiliza a quantidade de requests
|
|||
// ajax para nao desabilitar o loader
|
|||
// antes da hora
|
|||
var nun_ajax = 0; |
|||
|
|||
$('#page').live('pageinit', function(event){ |
|||
// variaveis globais para as requisicoes ajax
|
|||
$.ajaxSetup({ |
|||
url: $(location).attr('href'), |
|||
cache: false, |
|||
type: 'POST', |
|||
beforeSend: function() { |
|||
nun_ajax++; |
|||
$('#working').show(); |
|||
}, |
|||
success: function(data) { |
|||
nun_ajax--; |
|||
if (nun_ajax == 0) |
|||
$('#working').hide(); |
|||
|
|||
//Retirando o span existente
|
|||
$("span.errors").html(""); |
|||
if (data.mensagem == "erro") { |
|||
for (var campo in data.erros) { |
|||
$("#"+ campo + " span").html(data.erros[campo].join('\n')) |
|||
} |
|||
} |
|||
}, |
|||
error: function(msg) { |
|||
nun_ajax--; |
|||
if (nun_ajax == 0) |
|||
$('#working').hide(); |
|||
$("#open-dialog").click(); |
|||
} |
|||
}); |
|||
|
|||
// remove a resposta vazia da interface
|
|||
$("div.ui-radio span.ui-btn-text:contains('---------')").parentsUntil("ul").hide(); |
|||
|
|||
// para todo input do from registra um evento
|
|||
// ao modificar o campo
|
|||
$("div.ui-field-contain textarea, div.ui-field-contain input, div.ui-field-contain select").change(function () { |
|||
// mostra ou esconde uma pergunta dependente
|
|||
var id_to_open = [] |
|||
var id_to_close = [] |
|||
$('input[name=' + $(this).attr('name') + ']').each(function () { |
|||
schema = $(this); |
|||
schema_to_open = schema.attr('schema_to_open'); |
|||
if (schema_to_open) { |
|||
if (schema.is(':checked')) |
|||
id_to_open.push(schema_to_open) |
|||
else |
|||
id_to_close.push(schema_to_open) |
|||
} |
|||
}); |
|||
|
|||
for (var i in id_to_close) { |
|||
id = id_to_close[i] |
|||
// Evita apagar uma pergunta caso ela possa
|
|||
// ser exibida por outra questão
|
|||
if (id_to_open.indexOf(id_to_close[i]) == -1) { |
|||
// limpa o valor para não salva-lo
|
|||
// no submit do form
|
|||
$("#" + id + " input").val(''); |
|||
$("#" + id).slideUp(); |
|||
} |
|||
} |
|||
|
|||
// Exibe as perguntas que devem estar disponiveis
|
|||
for (var i in id_to_open) { |
|||
id = id_to_open[i] |
|||
$("#" + id).slideDown(); |
|||
} |
|||
|
|||
$.ajax({ |
|||
data: $('#diagnostico').serializeArray() |
|||
}); |
|||
|
|||
}); |
|||
|
|||
$('input[schema_to_open]').each(function () { |
|||
schema = $(this); |
|||
schema_to_open = $("#" + schema.attr('schema_to_open')); |
|||
schema_to_open.hide(); |
|||
}); |
|||
|
|||
$('input[schema_to_open]:checked').each(function () { |
|||
schema = $(this); |
|||
schema_to_open = $("#" + schema.attr('schema_to_open')); |
|||
schema_to_open.show(); |
|||
}); |
|||
|
|||
// se carregou o js sem erros mostra as perguntas
|
|||
$("#waiting").hide(); |
|||
$("#working").hide(); |
|||
$("#form").show(); |
|||
}); |
@ -0,0 +1,12 @@ |
|||
PIL==1.1.7 |
|||
Django==1.2 |
|||
django-auth-ldap==1.0.12 |
|||
django-autoslug==1.4.1 |
|||
django-extensions==0.7.1 |
|||
django-treemenus==0.8.7 |
|||
eav-django==1.3.4 |
|||
html5lib==0.90 |
|||
pisa==3.0.33 |
|||
python-ldap==2.4.4 |
|||
reportlab==2.5 |
|||
wsgiref==0.1.2 |
@ -0,0 +1,79 @@ |
|||
#!bin/bash |
|||
|
|||
############################################################# |
|||
## Arquivo: setup.sh ## |
|||
## ## |
|||
## Esse arquivo foi criado para automatizar a instalação ## |
|||
## do projeto SIGI. ## |
|||
## ## |
|||
## Autor: Gilson Filho <contato@gilsondev.com> ## |
|||
## Data: 23 de Novembro de 2011 ## |
|||
## Versão: 1.0 ## |
|||
## ## |
|||
############################################################# |
|||
|
|||
# Definindo o nome do arquivo que contem as informações das dependências |
|||
requirements="requirements.txt" |
|||
|
|||
# Verifica se o easy_install e o pip está instalado |
|||
easy_install=`find /usr/bin/ -name easy_install` |
|||
pip=`find /usr/bin/ -name pip` |
|||
git=`find /usr/bin/ -name git` |
|||
|
|||
if [ ! -f $easy_install ] || [ ! -f $pip ]; then |
|||
echo "O aplicativo pip é obrigatório. Favor instalar para continuar a configuração do SIGI." |
|||
sleep 5 |
|||
exit |
|||
else |
|||
# Executando o arquivo requirements.txt |
|||
if [ -f $requirements ]; then |
|||
echo |
|||
echo "Instalando os módulos contidos no arquivo $requirements ..." |
|||
echo |
|||
sleep 2 |
|||
pip install -r $requirements |
|||
|
|||
# Verifica se o git está instalado |
|||
if [ ! -f $git]; then |
|||
echo |
|||
echo "O aplicativo git não está instalado. Caso contrário, faça o checkout diretamente." |
|||
sleep 5 |
|||
exit |
|||
else |
|||
# Faz o checkout do projeto e instala o módulo |
|||
echo |
|||
echo "Fazendo o checkout do projeto..." |
|||
echo |
|||
sleep 2 |
|||
git clone git://github.com/jacobian/django-googlecharts.git |
|||
|
|||
echo |
|||
echo "Iniciando a instalacao..." |
|||
echo |
|||
sleep 2 |
|||
cd django-googlecharts |
|||
python setup.py install |
|||
|
|||
# Instalando o django-geraldo |
|||
echo |
|||
echo "Fazendo o checkout do projeto django-geraldo..." |
|||
echo |
|||
sleep 2 |
|||
git clone https://github.com/marinho/geraldo.git |
|||
|
|||
echo |
|||
echo "Instalando o django-geraldo..." |
|||
echo |
|||
cd geraldo |
|||
python setup.py install |
|||
cp -Rvf reporting geraldo /usr/local/lib/python2.7/site-packages |
|||
fi |
|||
else |
|||
echo |
|||
echo "O arquivo requirements.txt não existe. Verifique se está na mesma pasta do arquivo de instalação do SIGI." |
|||
sleep 5 |
|||
exit |
|||
fi |
|||
fi |
|||
|
|||
|
@ -1,32 +1,94 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from datetime import datetime |
|||
from django.contrib import admin |
|||
from eav.admin import BaseEntityAdmin, BaseSchemaAdmin |
|||
from sigi.apps.diagnosticos.models import Diagnostico, Pergunta, Escolha, Equipe, Anexo |
|||
from sigi.apps.diagnosticos.models import Diagnostico, Pergunta, Escolha, Equipe, Anexo, Categoria |
|||
from sigi.apps.diagnosticos.forms import DiagnosticoForm |
|||
|
|||
|
|||
""" |
|||
Actions do Admin |
|||
""" |
|||
def publicar_diagnostico(self, request, queryset): |
|||
for registro in queryset: |
|||
diagnostico = Diagnostico.objects.get(pk=registro.id) |
|||
diagnostico.publicado = True |
|||
diagnostico.data_publicacao= datetime.now() |
|||
diagnostico.save() |
|||
|
|||
# Enviando o email avisando que o diagnóstico foi publicado |
|||
diagnostico.email_diagnostico_publicado(diagnostico.responsavel.email_pessoal, request.get_host()) |
|||
self.message_user(request, "Diagnóstico(s) publicado(s) com sucesso!") |
|||
publicar_diagnostico.short_description = u""" |
|||
Definir diagnósticos como publicado""" |
|||
|
|||
|
|||
def despublicar_diagnostico(self, request, queryset): |
|||
queryset.update(publicado=False) |
|||
despublicar_diagnostico.short_description = u""" |
|||
Definir diagnósticos como não publicado""" |
|||
|
|||
|
|||
class EquipeInline(admin.TabularInline): |
|||
model = Equipe |
|||
extra = 4 |
|||
|
|||
class AnexosInline(admin.TabularInline): |
|||
model = Anexo |
|||
extra = 2 |
|||
exclude = ['data_pub',] |
|||
exclude = ['data_pub', ] |
|||
|
|||
|
|||
class AnexoAdmin(admin.ModelAdmin): |
|||
date_hierarchy = 'data_pub' |
|||
exclude = ['data_pub',] |
|||
exclude = ['data_pub', ] |
|||
list_display = ('arquivo', 'descricao', 'data_pub', 'diagnostico') |
|||
raw_id_fields = ('diagnostico',) |
|||
search_fields = ('descricao', 'diagnostico__id', 'arquivo', |
|||
'diagnostico__casa_legislativa__nome') |
|||
|
|||
|
|||
class DiagnosticoAdmin(BaseEntityAdmin): |
|||
form = DiagnosticoForm |
|||
actions = [publicar_diagnostico, despublicar_diagnostico] |
|||
inlines = (EquipeInline, AnexosInline) |
|||
search_fields = ('casa_legislativa__nome', 'responsavel',) |
|||
list_display = ('casa_legislativa', 'data_visita_inicio', 'data_visita_fim', 'responsavel', 'publicado') |
|||
list_filter = ('publicado', 'data_publicacao', 'data_visita_inicio', 'data_visita_fim') |
|||
raw_id_fields = ('casa_legislativa',) |
|||
|
|||
eav_fieldsets = [ |
|||
(u'00. Identificação do Diagnóstico', {'fields': ('responsavel', 'data_visita_inicio', 'data_visita_fim',)}), |
|||
(u'01. Identificação da Casa Legislativa', {'fields': ('casa_legislativa',)}), |
|||
(u'02. Identificação de Competências da Casa Legislativa', {'fields': ()}) |
|||
] |
|||
|
|||
# popula o eav fieldsets ordenando as categorias e as perguntas |
|||
# para serem exibidas no admin |
|||
for categoria in Categoria.objects.all(): |
|||
# ordena as perguntas pelo title e utiliza o name no fieldset |
|||
perguntas_by_title = [(p.title, p.name) for p in categoria.perguntas.all()] |
|||
perguntas = [pergunta[1] for pergunta in sorted(perguntas_by_title)] |
|||
|
|||
eav_fieldsets.append((categoria, { |
|||
'fields': tuple(perguntas), |
|||
'classes': ['collapse'] |
|||
})) |
|||
|
|||
|
|||
class PerguntaAdmin (BaseSchemaAdmin): |
|||
search_fields = ('title', 'help_text', 'name',) |
|||
list_display = ('title', 'categoria', 'datatype', 'help_text', 'required') |
|||
list_filter = ('datatype', 'categoria', 'required') |
|||
|
|||
|
|||
class EscolhaAdmin(admin.ModelAdmin): |
|||
search_fields = ('title',) |
|||
list_display = ('title', 'schema', 'schema_to_open') |
|||
raw_id_fields = ('schema', 'schema_to_open') |
|||
ordering = ('schema', 'title') |
|||
|
|||
admin.site.register(Diagnostico, DiagnosticoAdmin) |
|||
admin.site.register(Pergunta, BaseSchemaAdmin) |
|||
admin.site.register(Escolha) |
|||
admin.site.register(Pergunta, PerguntaAdmin) |
|||
admin.site.register(Escolha, EscolhaAdmin) |
|||
admin.site.register(Anexo, AnexoAdmin) |
|||
admin.site.register(Categoria) |
|||
|
@ -0,0 +1,23 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
from django.template import RequestContext |
|||
from django.shortcuts import render_to_response |
|||
from sigi.apps.diagnosticos.models import Diagnostico |
|||
|
|||
def validate_diagnostico(func): |
|||
def decorator(request, id_diagnostico, *args, **kwargs): |
|||
""" Retorna 404 caso o diagnostico esteja publicado |
|||
ou o usuario nao seja um membro da equipe |
|||
""" |
|||
try: |
|||
diagnostico = Diagnostico.objects.filter(publicado=False).get(pk=id_diagnostico) |
|||
if (request.user.servidor in diagnostico.membros): |
|||
# continua o processamento normal da view |
|||
return func(request, id_diagnostico, *args, **kwargs) |
|||
except Diagnostico.DoesNotExist: |
|||
pass |
|||
|
|||
# renderiza a pagina de 404 |
|||
context = RequestContext(request, {}) |
|||
return render_to_response('mobile/404.html', context) |
|||
return decorator |
File diff suppressed because one or more lines are too long
@ -1,5 +1,148 @@ |
|||
from models import Diagnostico |
|||
# -*- coding: utf8 -*- |
|||
|
|||
from copy import deepcopy |
|||
from django import forms |
|||
from django.forms.forms import BoundField |
|||
from django.forms import (BooleanField, CharField, DateField, |
|||
FloatField, ModelChoiceField, Textarea, |
|||
ModelMultipleChoiceField) |
|||
from django.contrib.contenttypes.generic import generic_inlineformset_factory |
|||
from sigi.apps.casas.models import CasaLegislativa, Funcionario |
|||
from sigi.apps.contatos.models import Telefone |
|||
from sigi.apps.diagnosticos.models import Diagnostico |
|||
from sigi.apps.diagnosticos.widgets import EavCheckboxSelectMultiple, EavRadioSelect |
|||
from eav.forms import BaseDynamicEntityForm |
|||
from eav.fields import RangeField |
|||
|
|||
class DiagnosticoForm(BaseDynamicEntityForm): |
|||
"""Classe responsável por contruir o formulário, |
|||
vinculando ao modelo Diagnostico |
|||
""" |
|||
model = Diagnostico |
|||
|
|||
|
|||
class DiagnosticoMobileForm(BaseDynamicEntityForm): |
|||
"""Classe responsável por construir o formulário |
|||
para ser usado no ambiente mobile, a partir do |
|||
do modelo Diagnostico, como também organizar sua |
|||
estrutura via categorias. |
|||
""" |
|||
|
|||
FIELD_CLASSES = { |
|||
'text': CharField, |
|||
'float': FloatField, |
|||
'date': DateField, |
|||
'bool': BooleanField, |
|||
'one': ModelChoiceField, |
|||
'many': ModelMultipleChoiceField, |
|||
'range': RangeField, |
|||
} |
|||
|
|||
FIELD_EXTRA = { |
|||
'one': {'widget': EavRadioSelect}, |
|||
'many': {'widget': EavCheckboxSelectMultiple}, |
|||
} |
|||
|
|||
FIELD_WIDGET = { |
|||
'consideracoes_gerais' : {'widget': Textarea}, |
|||
'descreva_5_cursos_prioritarios_para_treinamento_de_parlamentares_da_camara_municipal' : {'widget': Textarea}, |
|||
'descreva_5_cursos_prioritarios_para_treinamento_de_servidores_da_camara_municipal' : {'widget': Textarea}, |
|||
'sugestoes_para_a_area_de_capacitacao' : {'widget': Textarea}, |
|||
'sugestoes_para_a_area_de_comunicacao' : {'widget': Textarea}, |
|||
'sugestoes_para_a_area_de_informacao' : {'widget': Textarea}, |
|||
'sugestoes_para_a_area_de_ti' : {'widget': Textarea}, |
|||
} |
|||
class Meta: |
|||
model = Diagnostico |
|||
|
|||
def __init__(self, data=None, category=None, *args, **kwargs): |
|||
super(BaseDynamicEntityForm, self).__init__(data, *args, **kwargs) |
|||
self._build_dynamics_fields(category) |
|||
|
|||
def __iter__(self): |
|||
# ordena os campos do formulario usando o atributo label |
|||
fields_by_label = [(field.label, name, field) for name, field in self.fields.items()] |
|||
for label, name, field in sorted(fields_by_label): |
|||
yield BoundField(self, field, name) |
|||
|
|||
def _build_dynamics_fields(self, category): |
|||
"""Método da classe ``BaseDynamicEntityForm`` sobrescrita, |
|||
para que as perguntas sejam agrupadas dentro das suas |
|||
categorias. |
|||
* category = ID da Categoria |
|||
""" |
|||
# Caso seja as duas primeiras categorias, utilize |
|||
# os campos do modelo |
|||
if int(category) in (0, 1, ): |
|||
self.fields = deepcopy(self.base_fields) |
|||
else: |
|||
self.fields = dict() |
|||
|
|||
# Se determinada pergunta é da categoria pesquisada, |
|||
# então, gere o campo no formulário. |
|||
for schema in self.instance.get_schemata(): |
|||
|
|||
if not schema.categoria_id == int(category): |
|||
continue |
|||
|
|||
defaults = { |
|||
'label': schema.title, |
|||
'required': schema.required, |
|||
'help_text': schema.help_text, |
|||
} |
|||
|
|||
datatype = schema.datatype |
|||
if datatype == schema.TYPE_MANY: |
|||
choices = getattr(self.instance, schema.name) |
|||
defaults.update({'queryset': schema.get_choices(), |
|||
'initial': [x.pk for x in choices]}) |
|||
elif datatype == schema.TYPE_ONE: |
|||
choice = getattr(self.instance, schema.name) |
|||
defaults.update({'queryset': schema.get_choices(), |
|||
'initial': choice.pk if choice else None, |
|||
# if schema is required remove --------- from ui |
|||
'empty_label': None if schema.required else u"---------"}) |
|||
|
|||
extra = self.FIELD_EXTRA.get(datatype, {}) |
|||
extra.update(self.FIELD_WIDGET.get(schema.name, {})) |
|||
if hasattr(extra, '__call__'): |
|||
extra = extra(schema) |
|||
defaults.update(extra) |
|||
|
|||
MappedField = self.FIELD_CLASSES[datatype] |
|||
self.fields[schema.name] = MappedField(**defaults) |
|||
|
|||
# fill initial data (if attribute was already defined) |
|||
value = getattr(self.instance, schema.name) |
|||
if value and not datatype in (schema.TYPE_ONE, schema.TYPE_MANY): # choices are already done above |
|||
self.initial[schema.name] = value |
|||
|
|||
|
|||
class CasaLegislativaMobileForm(forms.ModelForm): |
|||
class Meta: |
|||
model = CasaLegislativa |
|||
fields = ('cnpj', 'logradouro', 'bairro', 'cep', 'email', 'pagina_web') |
|||
|
|||
class TelefoneMobileForm(forms.ModelForm): |
|||
pass |
|||
class Meta: |
|||
model = Telefone |
|||
fields = ('numero', 'tipo') |
|||
|
|||
class FuncionariosMobileForm(forms.ModelForm): |
|||
TelefoneFormSet = generic_inlineformset_factory(Telefone, TelefoneMobileForm, extra=1, can_delete=False) |
|||
|
|||
def __init__(self, data=None, prefix=None, instance=None, *args, **kwargs): |
|||
super(FuncionariosMobileForm, self).__init__(data, prefix=prefix, instance=instance, *args, **kwargs) |
|||
self.telefones = self.TelefoneFormSet(data, prefix=prefix, instance=instance) |
|||
|
|||
def is_valid(self): |
|||
return self.telefones.is_valid() and super(FuncionariosMobileForm, self).is_valid() |
|||
|
|||
def save(self, commit=True): |
|||
self.telefones.save(commit) |
|||
return super(FuncionariosMobileForm, self).save(commit) |
|||
|
|||
class Meta: |
|||
model = Funcionario |
|||
fields = ('nome', 'email', 'cargo', 'funcao', 'tempo_de_servico') |
|||
|
@ -0,0 +1,15 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
from django.test import TestCase |
|||
|
|||
|
|||
class DiagnosticosViewsTest(TestCase): |
|||
"""Testes feitos para verificar o funcionamento |
|||
do view de diagnósticos. |
|||
""" |
|||
|
|||
def test_diagnostico_list_success(self): |
|||
|
|||
response = self.client.get('/sigi/mobile/diagnosticos') |
|||
self.assertEquals(200, response.status_code) |
|||
self.assertTemplateUsed(response, 'diagnosticos/diagnosticos_list.html') |
@ -0,0 +1,35 @@ |
|||
# -*- coding: utf8 -*- |
|||
from django.conf.urls.defaults import patterns, url |
|||
|
|||
LOGIN_REDIRECT_URL = '/sigi/mobile/diagnosticos/login' |
|||
|
|||
urlpatterns = patterns('', |
|||
# Lista de Diagnósticos |
|||
url(r'^$', 'sigi.apps.diagnosticos.views.lista', name='lista_diagnosticos'), |
|||
|
|||
# Login do Diagnóstico |
|||
url(r'^login/$', 'django.contrib.auth.views.login', {'template_name': |
|||
'diagnosticos/diagnosticos_login.html'}, name='login'), |
|||
|
|||
# Logout do Diagnóstico |
|||
url(r'^logout/$', 'django.contrib.auth.views.logout', |
|||
{'next_page': LOGIN_REDIRECT_URL}, name='logout'), |
|||
|
|||
# Lista de Categorias |
|||
url(r'^(?P<id_diagnostico>\d+)/categorias/$', 'sigi.apps.diagnosticos.views.categorias', name='lista_categorias'), |
|||
|
|||
# Detalhes da Categoria da Casa Legislativa |
|||
url(r'^(?P<id_diagnostico>\d+)/categorias/1/$', |
|||
'sigi.apps.diagnosticos.views.categoria_casa_legislativa', |
|||
name='detalhes_categoria_casa_legislativa'), |
|||
|
|||
# Detalhes da Categoria de Contatos |
|||
url(r'^(?P<id_diagnostico>\d+)/categorias/2/$', |
|||
'sigi.apps.diagnosticos.views.categoria_contatos', |
|||
name='detalhes_categoria_contatos'), |
|||
|
|||
# Detalhes de Categorias Dinamicas |
|||
url(r'^(?P<id_diagnostico>\d+)/categorias/(?P<id_categoria>\d+)/$', |
|||
'sigi.apps.diagnosticos.views.categoria_detalhes', |
|||
name='detalhes_categoria'), |
|||
) |
@ -0,0 +1,187 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
from django.http import HttpResponse |
|||
from django.utils import simplejson |
|||
from django.shortcuts import render_to_response |
|||
from django.template import RequestContext |
|||
from django.views.decorators.cache import never_cache |
|||
|
|||
from sigi.apps.diagnosticos.urls import LOGIN_REDIRECT_URL |
|||
from sigi.apps.utils.decorators import login_required |
|||
from sigi.apps.diagnosticos.decorators import validate_diagnostico |
|||
from sigi.apps.diagnosticos.models import Diagnostico, Categoria |
|||
from sigi.apps.casas.models import Funcionario |
|||
from sigi.apps.diagnosticos.forms import (DiagnosticoMobileForm, |
|||
CasaLegislativaMobileForm, FuncionariosMobileForm) |
|||
|
|||
|
|||
@never_cache |
|||
@login_required(login_url=LOGIN_REDIRECT_URL) |
|||
def lista(request): |
|||
"""Consulta os diagnosticos do servidor logado, |
|||
que contenham o status de não publicado. |
|||
""" |
|||
servidor = request.user.servidor |
|||
diagnosticos = servidor.diagnosticos |
|||
context = RequestContext(request, {'diagnosticos': diagnosticos}) |
|||
return render_to_response('diagnosticos/diagnosticos_list.html', context) |
|||
|
|||
|
|||
@never_cache |
|||
@login_required(login_url=LOGIN_REDIRECT_URL) |
|||
@validate_diagnostico |
|||
def categorias(request, id_diagnostico): |
|||
"""Consulta as categorias do diagnostico selecionado |
|||
a partir da sua identificação |
|||
""" |
|||
categorias = Categoria.objects.all() |
|||
diagnostico = Diagnostico.objects.get(pk=id_diagnostico) |
|||
|
|||
# Estilizando a lista de categorias para que ajude a identificar |
|||
# qual categoria foi a ultima a ser usada, como também as outras |
|||
# que ainda não foram acessadas |
|||
ultima_categoria = request.session.get('ultima_categoria', 0) |
|||
|
|||
context = RequestContext(request, {'categorias': categorias, |
|||
'diagnostico': diagnostico, 'ultima_categoria': ultima_categoria}) |
|||
return render_to_response('diagnosticos/diagnosticos_categorias_list.html', |
|||
context) |
|||
|
|||
|
|||
@never_cache |
|||
@login_required(login_url=LOGIN_REDIRECT_URL) |
|||
@validate_diagnostico |
|||
def categoria_detalhes(request, id_diagnostico, id_categoria): |
|||
"""Captura as perguntas da categoria |
|||
selecionada. Durante o preenchimento das perguntas, o camada |
|||
template do projeto, vai requisitar a inserção dos campos via |
|||
AJAX a cada mudança de pergunta |
|||
|
|||
Caso alguma inserção não passe na validação do formulário em |
|||
questão, será enviado as mensagens de erro no formato JSON, |
|||
para que a camada de template do projeto trate-as de forma adequada. |
|||
""" |
|||
|
|||
# Grava na sessão a categoria atual, para destacar que |
|||
# era foi a última visitada. |
|||
request.session['ultima_categoria'] = int(id_categoria) |
|||
|
|||
try: |
|||
categoria = Categoria.objects.get(pk=id_categoria) |
|||
except Categoria.DoesNotExist: |
|||
context = RequestContext(request) |
|||
return render_to_response('mobile/404.html', context) |
|||
|
|||
diagnostico = Diagnostico.objects.filter(publicado=False).get(pk=id_diagnostico) |
|||
|
|||
if request.method == "POST": |
|||
form = DiagnosticoMobileForm(request.POST, |
|||
instance=diagnostico, category=id_categoria) |
|||
if form.is_valid(): |
|||
form.save() |
|||
resposta = { |
|||
'mensagem': 'sucesso' |
|||
} |
|||
else: |
|||
# Montando a estrutura das mensagens de erro no formato JSON |
|||
resposta = { |
|||
'mensagem': 'erro', |
|||
'erros': form.errors |
|||
} |
|||
json = simplejson.dumps(resposta) |
|||
return HttpResponse(json, mimetype="application/json") |
|||
else: |
|||
form = DiagnosticoMobileForm(instance=diagnostico, |
|||
category=id_categoria) |
|||
|
|||
context = RequestContext(request, {'form': form, 'categoria': categoria, |
|||
'diagnostico': diagnostico}) |
|||
return render_to_response('diagnosticos/diagnosticos_categorias_form.html', |
|||
context) |
|||
|
|||
|
|||
@never_cache |
|||
@login_required(login_url=LOGIN_REDIRECT_URL) |
|||
@validate_diagnostico |
|||
def categoria_casa_legislativa(request, id_diagnostico): |
|||
|
|||
# Grava na sessão a categoria atual, para destacar que |
|||
# era foi a última visitada. |
|||
request.session['ultima_categoria'] = 1 |
|||
|
|||
diagnostico = Diagnostico.objects.get(pk=id_diagnostico) |
|||
casa_legislativa = diagnostico.casa_legislativa |
|||
|
|||
if request.method == "POST": |
|||
form = CasaLegislativaMobileForm(request.POST, |
|||
instance=casa_legislativa) |
|||
if form.is_valid(): |
|||
form.save() |
|||
resposta = { |
|||
'mensagem': 'sucesso' |
|||
} |
|||
else: |
|||
# Montando a estrutura das mensagens de erro no formato JSON |
|||
resposta = { |
|||
'mensagem': 'erro', |
|||
'erros': form.errors |
|||
} |
|||
json = simplejson.dumps(resposta) |
|||
return HttpResponse(json, mimetype="application/json") |
|||
else: |
|||
form = CasaLegislativaMobileForm(instance=casa_legislativa) |
|||
|
|||
context = RequestContext(request, {'form': form, |
|||
'diagnostico': diagnostico, 'casa_legislativa': casa_legislativa}) |
|||
return render_to_response( |
|||
'diagnosticos/diagnosticos_categoria_casa_legislativa_form.html', |
|||
context) |
|||
|
|||
|
|||
@never_cache |
|||
@login_required(login_url=LOGIN_REDIRECT_URL) |
|||
@validate_diagnostico |
|||
def categoria_contatos(request, id_diagnostico): |
|||
|
|||
# Grava na sessão a categoria atual, para destacar que |
|||
# era foi a última visitada. |
|||
request.session['ultima_categoria'] = 2 |
|||
|
|||
diagnostico = Diagnostico.objects.get(pk=id_diagnostico) |
|||
casa_legislativa = diagnostico.casa_legislativa |
|||
|
|||
funcionarios = [casa_legislativa.funcionario_set.get_or_create(setor=n) |
|||
for n, l in Funcionario.SETOR_CHOICES] |
|||
|
|||
if request.method == "POST": |
|||
forms = [FuncionariosMobileForm( |
|||
request.POST, prefix=f.setor, instance=f) for f, c in funcionarios] |
|||
|
|||
resposta = { |
|||
'mensagem': 'sucesso', |
|||
'erros' : {} |
|||
} |
|||
|
|||
# valida e salva um formulario por vez |
|||
for form in forms: |
|||
if form.is_valid(): |
|||
form.save() |
|||
else: |
|||
# Montando a estrutura das mensagens de erro no formato JSON |
|||
resposta['mensagem'] = 'erro' |
|||
resposta['erros'].update(form.errors) |
|||
for form_telefones in form.telefones.forms: |
|||
for key, value in form_telefones.errors.iteritems(): |
|||
key = form_telefones.prefix + "-" + key |
|||
resposta['erros'][key] = value |
|||
|
|||
json = simplejson.dumps(resposta) |
|||
return HttpResponse(json, mimetype="application/json") |
|||
else: |
|||
forms = [FuncionariosMobileForm(prefix=f.setor, instance=f) |
|||
for f, c in funcionarios] |
|||
|
|||
context = RequestContext(request, {'forms': forms, |
|||
'diagnostico': diagnostico, 'casa_legislativa': casa_legislativa}) |
|||
return render_to_response('diagnosticos/diagnosticos_categoria_contatos_form.html', |
|||
context) |
@ -0,0 +1,61 @@ |
|||
from itertools import chain |
|||
from django.forms.widgets import CheckboxInput, CheckboxSelectMultiple, RadioSelect, RadioFieldRenderer, RadioInput |
|||
from django.utils.html import conditional_escape |
|||
from django.utils.encoding import force_unicode |
|||
from django.utils.safestring import mark_safe |
|||
from sigi.apps.diagnosticos.models import Escolha |
|||
|
|||
class EavCheckboxSelectMultiple(CheckboxSelectMultiple): |
|||
def render(self, name, value, attrs=None, choices=()): |
|||
if value is None: value = [] |
|||
final_attrs = self.build_attrs(attrs, name=name) |
|||
output = [u'<ul>'] |
|||
str_values = set([force_unicode(v) for v in value]) |
|||
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): |
|||
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i)) |
|||
label_for = u' for="%s"' % final_attrs['id'] |
|||
|
|||
# Caso exista uma pergunta para abrir |
|||
# adiciona um atripbuto no checkbox |
|||
schema_to_open = Escolha.objects.get(pk=option_value).schema_to_open |
|||
if schema_to_open: |
|||
final_attrs['schema_to_open'] = schema_to_open.name |
|||
|
|||
cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) |
|||
option_value = force_unicode(option_value) |
|||
rendered_cb = cb.render(name, option_value) |
|||
option_label = conditional_escape(force_unicode(option_label)) |
|||
output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label)) |
|||
output.append(u'</ul>') |
|||
return mark_safe(u'\n'.join(output)) |
|||
|
|||
class EavRadioFieldRenderer(RadioFieldRenderer): |
|||
def __iter__(self): |
|||
for i, choice in enumerate(self.choices): |
|||
final_attrs = self.attrs.copy() |
|||
|
|||
# Caso exista uma pergunta para abrir |
|||
# adiciona um atripbuto no checkbox |
|||
if choice[0]: |
|||
schema_to_open = Escolha.objects.get(pk=choice[0]).schema_to_open |
|||
if schema_to_open: |
|||
final_attrs['schema_to_open'] = schema_to_open.name |
|||
|
|||
yield RadioInput(self.name, self.value, final_attrs, choice, i) |
|||
|
|||
def __getitem__(self, idx): |
|||
choice = self.choices[idx] |
|||
|
|||
final_attrs = self.attrs.copy() |
|||
|
|||
# Caso exista uma pergunta para abrir |
|||
# adiciona um atripbuto no checkbox |
|||
schema_to_open = Escolha.objects.get(pk=self.value).schema_to_open |
|||
if schema_to_open: |
|||
final_attrs['schema_to_open'] = schema_to_open.name |
|||
|
|||
return RadioInput(self.name, self.value,final_attrs, choice, idx) |
|||
|
|||
class EavRadioSelect(RadioSelect): |
|||
renderer = EavRadioFieldRenderer |
|||
|
@ -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 |
@ -0,0 +1,233 @@ |
|||
# 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: 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() |
|||
|
@ -0,0 +1,93 @@ |
|||
# 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: |
|||
user = User.objects.create_user(username, email, username) |
|||
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." |
@ -0,0 +1,16 @@ |
|||
from django.contrib.admin.widgets import AdminFileWidget |
|||
from django.utils.translation import ugettext as _ |
|||
from django.utils.safestring import mark_safe |
|||
|
|||
class AdminImageWidget(AdminFileWidget): |
|||
def render(self, name, value, attrs=None): |
|||
output = [] |
|||
if value and getattr(value, "url", None): |
|||
image_url = value.url |
|||
file_name=str(value) |
|||
output.append( |
|||
u''' <a href="%s" target="_blank"><img src="%s" width="100" |
|||
height="100" alt="%s"/></a> <br/> %s''' % \ |
|||
(image_url, image_url, file_name, _('Change:'))) |
|||
output.append(super(AdminFileWidget, self).render(name, value, attrs)) |
|||
return mark_safe(u''.join(output)) |
@ -0,0 +1,71 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
""" |
|||
Script baseado no arquivo decorators.py do django 1.3. |
|||
Ele foi copiado para usar o decorador ``login_required`` |
|||
que possui o argumento ``login_url``, responsável por |
|||
redirecionar ao template de login desejado. |
|||
|
|||
No ato de atualizar o framework, esse script torna-se |
|||
obsoleto. |
|||
""" |
|||
|
|||
import urlparse |
|||
try: |
|||
from functools import wraps |
|||
except ImportError: |
|||
from django.utils.functional import wraps # Python 2.4 fallback. |
|||
|
|||
from django.conf import settings |
|||
from django.contrib.auth import REDIRECT_FIELD_NAME |
|||
from django.utils.decorators import available_attrs |
|||
|
|||
|
|||
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): |
|||
""" |
|||
Decorator for views that checks that the user passes the given test, |
|||
redirecting to the log-in page if necessary. The test should be a callable |
|||
that takes the user object and returns True if the user passes. |
|||
""" |
|||
|
|||
def decorator(view_func): |
|||
@wraps(view_func, assigned=available_attrs(view_func)) |
|||
def _wrapped_view(request, *args, **kwargs): |
|||
if test_func(request.user): |
|||
return view_func(request, *args, **kwargs) |
|||
path = request.build_absolute_uri() |
|||
# If the login url is the same scheme and net location then just |
|||
# use the path as the "next" url. |
|||
login_scheme, login_netloc = urlparse.urlparse(login_url or |
|||
settings.LOGIN_URL)[:2] |
|||
current_scheme, current_netloc = urlparse.urlparse(path)[:2] |
|||
if ((not login_scheme or login_scheme == current_scheme) and |
|||
(not login_netloc or login_netloc == current_netloc)): |
|||
path = request.get_full_path() |
|||
from django.contrib.auth.views import redirect_to_login |
|||
return redirect_to_login(path, login_url, redirect_field_name) |
|||
return _wrapped_view |
|||
return decorator |
|||
|
|||
|
|||
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None): |
|||
""" |
|||
Decorator for views that checks that the user is logged in, redirecting |
|||
to the log-in page if necessary. |
|||
""" |
|||
actual_decorator = user_passes_test( |
|||
lambda u: u.is_authenticated(), |
|||
login_url=login_url, |
|||
redirect_field_name=redirect_field_name |
|||
) |
|||
if function: |
|||
return actual_decorator(function) |
|||
return actual_decorator |
|||
|
|||
|
|||
def permission_required(perm, login_url=None): |
|||
""" |
|||
Decorator for views that checks whether a user has a particular permission |
|||
enabled, redirecting to the log-in page if necessary. |
|||
""" |
|||
return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url) |
@ -0,0 +1,33 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
from django.template.loader import render_to_string |
|||
from django.core.mail import EmailMessage |
|||
from django.conf import settings |
|||
|
|||
|
|||
def enviar_email(from_email, subject, template, tags): |
|||
"""Envia o email para o destinatário definido, a partir do template |
|||
definido para ser renderizado. Os argumentos são: |
|||
* from_email - Email do remetente |
|||
* subject - Assunto da Mensagem |
|||
* template - Template que será usado para gerar o corpo |
|||
da mensagem |
|||
* tags - Variáveis de contexto para ser renderizado no |
|||
template. |
|||
""" |
|||
if from_email is None: |
|||
raise ValueError("Insira o email do remetente.") |
|||
elif subject is None: |
|||
raise ValueError("Insira o assunto da mensagem.") |
|||
elif template is None: |
|||
raise ValueError(u"Template da mensagem não encontrado") |
|||
elif tags is None: |
|||
raise ValueError("Insira o conteúdo da mensagem.") |
|||
|
|||
# Gerando a mensagem |
|||
mensagem = render_to_string(template, tags) |
|||
|
|||
# Enviando a mensagem |
|||
email = EmailMessage(settings.EMAIL_SUBJECT_PREFIX + " " + subject, mensagem, |
|||
from_email, [from_email]) |
|||
email.send() |
@ -0,0 +1,42 @@ |
|||
# -*- coding: utf8 -*- |
|||
|
|||
|
|||
def valida_data(data_inicio, data_final): |
|||
"""Função responsável por validar se o intervalo das |
|||
datas estão erradas, ou seja, se a data de início está |
|||
maior ou igual a data final. |
|||
|
|||
Caso seja maior ou igual retornará ``True``, caso contrário |
|||
retornará ``False``. |
|||
""" |
|||
if data_inicio >= data_final: |
|||
return True |
|||
else: |
|||
return False |
|||
|
|||
|
|||
def valida_periodo_data(di01, df01, di02, df02): |
|||
"""Função responsável por validar dois períodos de datas. |
|||
Isso é usado para verificar se determinado servidor exerceu |
|||
mais de uma função dentro de determinados períodos descritos |
|||
abaixo: |
|||
|
|||
1 - A segunda função não pode ter exercido ao mesmo tempo que |
|||
a primeira função. Exemplo: |
|||
|
|||
Primeiro Função: 01/05/2011 -- 01/11/2011 |
|||
Segundo Função: 01/05/2011 -- 01/11/2011 |
|||
|
|||
2 - A segunda função não pode ter exercido, dentro do período |
|||
da primeira função. Exemplo: |
|||
|
|||
Primeira Função: 01/05/2011 -- 01/11/2011 |
|||
Segunda Função: 02/05/2011 -- 30/10/2011 |
|||
""" |
|||
# Verificando a primeira situação |
|||
if di01 == di02 and df01 == df02: |
|||
return True |
|||
elif ((di01 >= di02) or (di02 <= df01)) and df01 <= df02: |
|||
return True |
|||
else: |
|||
return False |
File diff suppressed because one or more lines are too long
@ -0,0 +1,19 @@ |
|||
BEGIN; |
|||
|
|||
-- retirando null de algumas colunas |
|||
ALTER TABLE "contatos_telefone" ALTER COLUMN nota DROP NOT NULL; |
|||
ALTER TABLE "contatos_telefone" ALTER COLUMN codigo_area DROP NOT NULL; |
|||
|
|||
-- migrando dados de presidente da CasaLegislativa para Funcionarios |
|||
INSERT INTO casas_funcionario (casa_legislativa_id, cargo, setor, nome, nota, email) |
|||
SELECT id, 'Presidente', 'presidencia', presidente, '', '' FROM casas_casalegislativa; |
|||
|
|||
-- migrando dados de telefones da CasaLegislativa para model generic Telefone |
|||
INSERT INTO contatos_telefone (numero, tipo, content_type_id, object_id, codigo_area, nota) |
|||
SELECT telefone, 'F', 12, id, '', '' FROM casas_casalegislativa; |
|||
|
|||
-- deletando colunas fazer deois de estabilizar a versao |
|||
-- ALTER TABLE "casas_casalegislativa" DROP COLUMN presidente; |
|||
-- ALTER TABLE "casas_casalegislativa" DROP COLUMN telefone; |
|||
-- ALTER TABLE "contatos_telefone" DROP COLUMN codigo_area; |
|||
COMMIT; |
@ -0,0 +1,7 @@ |
|||
BEGIN; |
|||
|
|||
-- deletando colunas da CasaLegislativa |
|||
ALTER TABLE "diagnosticos_diagnostico" ADD COLUMN "responsavel_id" integer NOT NULL REFERENCES "servidores_servidor" ("id"); |
|||
ALTER TABLE "diagnosticos_equipe" DROP COLUMN "is_chefe"; |
|||
|
|||
COMMIT; |
@ -0,0 +1,6 @@ |
|||
{% extends 'admin/change_form.html' %} |
|||
|
|||
{% block extrastyle %} |
|||
{{ block.super }} |
|||
<link rel="stylesheet" type="text/css" href="{{MEDIA_URL}}css/admin/diagnosticos/diagnostico/change_form.css"> |
|||
{% endblock %} |
@ -0,0 +1,27 @@ |
|||
{% extends 'admin/change_form.html' %} |
|||
|
|||
{% block form_top %} |
|||
{% if adminform.form.instance.user %} |
|||
<fieldset class="module aligned"> |
|||
<h2>Dados do servidor LDAP</h2> |
|||
<div class="form-row"> |
|||
<div> |
|||
<label>Primeiro Nome:</label> |
|||
<p>{{adminform.form.instance.user.first_name}}</p> |
|||
</div> |
|||
</div> |
|||
<div class="form-row"> |
|||
<div> |
|||
<label>Último Nome:</label> |
|||
<p>{{adminform.form.instance.user.last_name}}</p> |
|||
</div> |
|||
</div> |
|||
<div class="form-row"> |
|||
<div> |
|||
<label>Email Principal:</label> |
|||
<p>{{adminform.form.instance.user.email}}</p> |
|||
</div> |
|||
</div> |
|||
</fieldset> |
|||
{% endif %} |
|||
{% endblock %} |
@ -0,0 +1,54 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="pt-BR"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
{% block titulo %} |
|||
<title>SIGI - Diagnósticos</title> |
|||
{% endblock titulo %} |
|||
{% block media %} |
|||
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" /> |
|||
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> |
|||
<script language=javascript> |
|||
$(document).bind("mobileinit", function () { |
|||
$.mobile.ajaxEnabled = false; |
|||
$.mobile.loadingMessage = 'salvando'; |
|||
}); |
|||
</script> |
|||
<script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script> |
|||
<script src="{{MEDIA_URL}}js/diagnosticos/diagnosticos_categorias_form.js"></script> |
|||
{% endblock media %} |
|||
</head> |
|||
<body> |
|||
<div data-role="page" id="page" class="type-interior"> |
|||
<div data-role="header" data-position="fixed"> |
|||
<img id="working" src="{{MEDIA_URL}}images/loader.gif" class="ui-btn-right"/> |
|||
{% block cabecalho %}{% endblock cabecalho %} |
|||
</div> <!-- header --> |
|||
<div data-role="content" class="content-primary"> |
|||
{% block corpo %}{% endblock corpo %} |
|||
</div><!-- content --> |
|||
<div data-role="footer"> |
|||
<div data-role="navbar"> |
|||
<ul> |
|||
{% block rodape %} |
|||
<li><a href="{% url lista_diagnosticos %}" data-icon="home">Home</a></li> |
|||
{% endblock rodape %} |
|||
</ul> |
|||
</div> |
|||
</div> <!-- footer --> |
|||
</div> <!-- page --> |
|||
|
|||
<a id='open-dialog' href="#dialog" data-rel="dialog" data-transition="pop" style='display:none;'></a> |
|||
<div data-role="page" id="dialog"> |
|||
<div data-role="header"> |
|||
<h1>Ops! Não foi possivel salvar os dados.</h1> |
|||
</div> |
|||
<div data-role="content" id="text"> |
|||
Algum erro ocorreu ao salvar os dados do diagnóstico, |
|||
verifique a sua conectividade e/ou entre em contato |
|||
com a equipe técnica o mais rápido possível. |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,49 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block media %} |
|||
{{ block.super }} |
|||
<link rel="stylesheet" href="{{MEDIA_URL}}css/diagnosticos/diagnosticos_categoria_model_form.css" /> |
|||
{% endblock %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>01. Identificação da Camara Municipal</h1> |
|||
<a href="{% url lista_categorias diagnostico.id %}?c=1" data-icon="arrow-l" |
|||
data-direction="reverse" data-theme="c" class="ui-btn-left">Voltar</a> |
|||
{% endblock cabecalho %} |
|||
|
|||
{% block corpo %} |
|||
{% if form %} |
|||
<div id="waiting"> |
|||
<!-- Exibe as perguntas apos o carregamento completo do javascript --> |
|||
<h2>Aguarde carregando perguntas para essa categoria...</h2> |
|||
</div> |
|||
<div id="form" style="display:none;"> |
|||
<div data-role="fieldcontain"> |
|||
<label class="attr">Município - UF</label> |
|||
{{ casa_legislativa.municipio }} |
|||
</div> |
|||
<div data-role="fieldcontain"> |
|||
<label class="attr">Nome</label> |
|||
{{ casa_legislativa.nome }} |
|||
</div> |
|||
<form id="diagnostico" action="." method="post"> |
|||
{% for field in form %} |
|||
<div data-role="fieldcontain"> |
|||
<label class="attr" for="{{ field.name }}">{{ field.label }}</label> |
|||
{{ field }} |
|||
<span class="errors"></span> |
|||
</div> |
|||
{% endfor %} |
|||
</form> |
|||
</div> |
|||
{% else %} |
|||
<h2>Nenhuma existem perguntas para essa categoria.</h2> |
|||
{% endif %} |
|||
{% endblock corpo %} |
|||
|
|||
{% block rodape %} |
|||
<ul> |
|||
<li><a href="{% url lista_categorias diagnostico.id %}" data-icon="grid" class="ui-state-persist ui-btn-active">Listar</a></li> |
|||
<li><a href="{% url lista_diagnosticos %}" data-icon="home">Home</a></li> |
|||
</ul> |
|||
{% endblock rodape %} |
@ -0,0 +1,52 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block media %} |
|||
{{ block.super }} |
|||
<link rel="stylesheet" href="{{MEDIA_URL}}css/diagnosticos/diagnosticos_categoria_model_form.css" /> |
|||
{% endblock %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>02. Identificação de Competências</h1> |
|||
<a href="{% url lista_categorias diagnostico.id %}?c=2" data-icon="arrow-l" |
|||
data-direction="reverse" data-theme="c" class="ui-btn-left">Voltar</a> |
|||
{% endblock cabecalho %} |
|||
|
|||
{% block corpo %} |
|||
<div id="waiting"> |
|||
<!-- Exibe as perguntas apos o carregamento completo do javascript --> |
|||
<h2>Aguarde carregando perguntas para essa categoria...</h2> |
|||
</div> |
|||
<div id="form" style="display:none;"> |
|||
<form id="diagnostico" action="." method="post"> |
|||
{% for form in forms %} |
|||
<h3>{{ form.instance.get_setor_display }}</h3> |
|||
{% for field in form %} |
|||
<div data-role="fieldcontain"> |
|||
<label class="attr" for="{{ field.name }}">{{ field.label }}</label> |
|||
{{ field }} |
|||
<span class="errors"></span> |
|||
</div> |
|||
{% endfor %} |
|||
<h4>Telefones</h4> |
|||
{% for form in form.telefones.forms %} |
|||
<div class="phone" data-role="fieldcontain"> |
|||
{{ form.tipo }} {{ form.numero}} |
|||
{% for field in form.hidden_fields %} |
|||
{{ field }} |
|||
<span class="errors"></span> |
|||
{% endfor %} |
|||
</div> |
|||
{% endfor %} |
|||
{{ form.telefones.management_form }} |
|||
<hr/> |
|||
{% endfor %} |
|||
</form> |
|||
</div> |
|||
{% endblock corpo %} |
|||
|
|||
{% block rodape %} |
|||
<ul> |
|||
<li><a href="{% url lista_categorias diagnostico.id %}" data-icon="grid" class="ui-state-persist">Listar</a></li> |
|||
<li><a href="{% url lista_diagnosticos %}" data-icon="home">Home</a></li> |
|||
</ul> |
|||
{% endblock rodape %} |
@ -0,0 +1,43 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block media %} |
|||
{{ block.super }} |
|||
<link rel="stylesheet" href="{{MEDIA_URL}}css/diagnosticos/diagnosticos_categorias_form.css" /> |
|||
{% endblock %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>{{ categoria.nome }}</h1> |
|||
<a href="{% url lista_categorias diagnostico.id %}" data-icon="arrow-l" |
|||
data-direction="reverse" data-theme="c" class="ui-btn-left">Voltar</a> |
|||
{% endblock cabecalho %} |
|||
|
|||
{% block corpo %} |
|||
{% if form %} |
|||
<div id="waiting"> |
|||
<!-- Exibe as perguntas apos o carregamento completo do javascript --> |
|||
<h2>Aguarde carregando perguntas para essa categoria...</h2> |
|||
</div> |
|||
<div id="form" style="display:none;"> |
|||
<form id="diagnostico" action="." method="post"> |
|||
{% for field in form %} |
|||
<div data-role="fieldcontain" id="{{ field.name }}"> |
|||
<label for="{{ field.name }}">{{ field.label }}</label> |
|||
{{ field }} |
|||
<span class="errors"></span> |
|||
</div> |
|||
{% endfor %} |
|||
</form> |
|||
</div> |
|||
{% else %} |
|||
<h2>Nenhuma existem perguntas para essa categoria.</h2> |
|||
{% endif %} |
|||
{% endblock corpo %} |
|||
<ul> |
|||
{% block rodape %} |
|||
{{ block.super }} |
|||
<li><a href="{% url lista_categorias diagnostico.id %}" data-icon="grid" class="ui-state-persist">Listar</a></li> |
|||
<li><a href="{% url logout %}" data-icon="delete">Sair</a></li> |
|||
{% endblock rodape %} |
|||
</ul> |
|||
|
|||
|
@ -0,0 +1,63 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>Categorias</h1> |
|||
<a href="{% url lista_diagnosticos %}" data-icon="arrow-l" data-direction="reverse" data-theme="c" class="ui-btn-left">Voltar</a> |
|||
{% endblock cabecalho %} |
|||
|
|||
{% block media %} |
|||
{{ block.super }} |
|||
<link href="{{ MEDIA_URL }}css/diagnosticos/diagnosticos_categorias.css" rel="stylesheet" /> |
|||
{% endblock media %} |
|||
|
|||
{% block corpo %} |
|||
{% if categorias %} |
|||
<ul data-role="listview"> |
|||
{% if ultima_categoria == 1 %} |
|||
<li class="ui-btn-last-c"> |
|||
{% else %} |
|||
<li> |
|||
{% endif %} |
|||
<a href="{% url detalhes_categoria_casa_legislativa diagnostico.id %}"> |
|||
<h4 class="ui-li-heading-read">01. Identificação da Casa Legislativa</h4> |
|||
</a> |
|||
</li> |
|||
{% if ultima_categoria == 2 %} |
|||
<li class="ui-btn-last-c"> |
|||
{% else %} |
|||
<li> |
|||
{% endif %} |
|||
<a href="{% url detalhes_categoria_contatos diagnostico.id %}"> |
|||
{% if diagnostico.contatos_respondidos %} |
|||
<h4 class="ui-li-heading-read">02. Identificação de Competências</h4> |
|||
{% else %} |
|||
<h4>02. Identificação de Competências</h4> |
|||
{% endif %} |
|||
</a> |
|||
</li> |
|||
{% for categoria in categorias %} |
|||
{% if ultima_categoria == categoria.id %} |
|||
<li class="ui-btn-last-c"> |
|||
{% else %} |
|||
<li> |
|||
{% endif %} |
|||
<a href="{% url detalhes_categoria diagnostico.id categoria.id %}"> |
|||
{% if categoria in diagnostico.categorias_respondidas %} |
|||
<h4 class="ui-li-heading-read">{{ categoria.nome }}</h4> |
|||
{% else %} |
|||
<h4>{{ categoria.nome }}</h4> |
|||
{% endif %} |
|||
</a> |
|||
</li> |
|||
{% endfor %} |
|||
</ul> |
|||
{% else %} |
|||
<h2>Nenhuma categoria existente.</h2> |
|||
{% endif %} |
|||
{% endblock corpo %} |
|||
<ul> |
|||
{% block rodape %} |
|||
{{ block.super }} |
|||
<li><a href="{% url logout %}" data-icon="delete">Sair</a></li> |
|||
{% endblock rodape %} |
|||
</ul> |
@ -0,0 +1,26 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>Diagnósticos</h1> |
|||
<a href="{% url logout %}" data-icon="delete" class="ui-btn-left">Sair</a> |
|||
{% endblock cabecalho %} |
|||
|
|||
{% block corpo %} |
|||
{% if diagnosticos %} |
|||
<ul data-role="listview"> |
|||
{% for diagnostico in diagnosticos %} |
|||
<li> |
|||
<a href="{% url lista_categorias diagnostico.id %}"> |
|||
<h4>{{ diagnostico.casa_legislativa.nome }}</h4> |
|||
<p><strong>Data:</strong> {{ diagnostico.data_visita_inicio|date:"d/m/Y" }} à {{ diagnostico.data_visita_fim|date:"d/m/Y" }} </p> |
|||
<p><strong>Responsável:</strong> {{ diagnostico.responsavel.nome_completo }}</p> |
|||
</a> |
|||
</li> |
|||
{% endfor %} |
|||
</ul> |
|||
{% else %} |
|||
<h2>Nenhum diagnóstico aberto.</h2> |
|||
{% endif %} |
|||
{% endblock corpo %} |
|||
|
|||
{% block rodape %}{% endblock rodape %} |
@ -0,0 +1,51 @@ |
|||
<!DOCTYPE HTML> |
|||
<html lang="pt-BR"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<title>SIGI - Login de Acesso</title> |
|||
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" /> |
|||
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> |
|||
<script language=javascript> |
|||
$(document).bind("mobileinit", function () { |
|||
$.mobile.ajaxEnabled = false; |
|||
$.mobile.loadingMessage = 'salvando'; |
|||
}); |
|||
</script> |
|||
<script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script> |
|||
</head> |
|||
<body> |
|||
<div data-role="header" data-theme="d"> |
|||
<img src="{{ MEDIA_URL }}images/mobile/logointerlegis_mobile.png" alt="Interlegis"/> |
|||
</div> <!-- header --> |
|||
{% if form.errors %} |
|||
<div data-role="header" data-theme="b"> |
|||
<h2>Erro ao logar</h2> |
|||
<ul> |
|||
{% for field in form %} |
|||
{% if field.errors %} |
|||
<li>{{ field.errors|striptags }}</li> |
|||
{% endif %} |
|||
{% endfor %} |
|||
</ul> |
|||
<p>Verifique se seu login e senha foram preenchidos corretamente.</p> |
|||
</div> <!-- error messages --> |
|||
{% endif %} |
|||
|
|||
<div data-role="content"> |
|||
<form action="{% url django.contrib.auth.views.login %}" method="POST"> |
|||
{% csrf_token %} |
|||
<div data-role="fieldcontain" class="ui-hide-label ui-body"> |
|||
<label for="username">Usuário:</label> |
|||
<input type="text" name="username" id="id_username" placeholder="Usuário"> |
|||
</div> |
|||
<div data-role="fieldcontain" class="ui-hide-label"> |
|||
<label for="password">Senha de Acesso:</label> |
|||
<input type="password" name="password" id="id_password" placeholder="Senha de Acesso"> |
|||
</div> |
|||
<input type="hidden" name="next" value="{% url lista_diagnosticos %}" /> |
|||
<button type="submit">Entrar</button> |
|||
</form> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,8 @@ |
|||
Foi atualizado um diagnóstico no SIGI. Os dados do diagnóstico são: |
|||
|
|||
Criador do Diagnóstico: {{ servidor }} |
|||
Dados do Diagnóstico: {{ casa_legislativa }} |
|||
Data do Diagnóstico: {{ data_diagnostico }} |
|||
Data do Relatório do Diagnóstico: {{ data_relatorio_diagnostico }} |
|||
|
|||
O seu status está como {{ status }} |
@ -0,0 +1,10 @@ |
|||
Olá {{ responsavel }} |
|||
|
|||
Foi publicado um diagnóstico no SIGI. |
|||
Os dados do diagnóstico são: |
|||
|
|||
Dados do Diagnóstico: {{ casa_legislativa }} |
|||
Data do Diagnóstico: {{ data_diagnostico }} |
|||
|
|||
Para mais detalhes, acesse: |
|||
http://{{ host }}{{ url_diagnostico }} |
@ -0,0 +1,15 @@ |
|||
{% extends "base_mobile.html" %} |
|||
|
|||
{% block cabecalho %} |
|||
<h1>Ocorreu um erro</h1> |
|||
{% endblock cabecalho %} |
|||
{% block corpo %} |
|||
<p>A página que está procurando não existe. </p> |
|||
<p>Verifique se o diagnóstico, categoria ou pergunta está cadastrado no sistema.</p> |
|||
<a href="{% url lista_diagnosticos %}" data-icon="arrow-l" |
|||
data-direction="reverse" data-role="button" data-theme="c" class="ui-btn-left">Voltar</a> |
|||
{% endblock corpo %} |
|||
|
|||
{% block rodape %} |
|||
|
|||
{% endblock rodape %} |
Loading…
Reference in new issue