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 -*- |
# -*- coding: utf-8 -*- |
||||
|
from datetime import datetime |
||||
from django.contrib import admin |
from django.contrib import admin |
||||
from eav.admin import BaseEntityAdmin, BaseSchemaAdmin |
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 |
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): |
class EquipeInline(admin.TabularInline): |
||||
model = Equipe |
model = Equipe |
||||
extra = 4 |
|
||||
|
|
||||
class AnexosInline(admin.TabularInline): |
class AnexosInline(admin.TabularInline): |
||||
model = Anexo |
model = Anexo |
||||
extra = 2 |
extra = 2 |
||||
exclude = ['data_pub',] |
exclude = ['data_pub', ] |
||||
|
|
||||
|
|
||||
class AnexoAdmin(admin.ModelAdmin): |
class AnexoAdmin(admin.ModelAdmin): |
||||
date_hierarchy = 'data_pub' |
date_hierarchy = 'data_pub' |
||||
exclude = ['data_pub',] |
exclude = ['data_pub', ] |
||||
list_display = ('arquivo', 'descricao', 'data_pub', 'diagnostico') |
list_display = ('arquivo', 'descricao', 'data_pub', 'diagnostico') |
||||
raw_id_fields = ('diagnostico',) |
raw_id_fields = ('diagnostico',) |
||||
search_fields = ('descricao', 'diagnostico__id', 'arquivo', |
search_fields = ('descricao', 'diagnostico__id', 'arquivo', |
||||
'diagnostico__casa_legislativa__nome') |
'diagnostico__casa_legislativa__nome') |
||||
|
|
||||
|
|
||||
class DiagnosticoAdmin(BaseEntityAdmin): |
class DiagnosticoAdmin(BaseEntityAdmin): |
||||
form = DiagnosticoForm |
form = DiagnosticoForm |
||||
|
actions = [publicar_diagnostico, despublicar_diagnostico] |
||||
inlines = (EquipeInline, AnexosInline) |
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',) |
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(Diagnostico, DiagnosticoAdmin) |
||||
admin.site.register(Pergunta, BaseSchemaAdmin) |
admin.site.register(Pergunta, PerguntaAdmin) |
||||
admin.site.register(Escolha) |
admin.site.register(Escolha, EscolhaAdmin) |
||||
admin.site.register(Anexo, AnexoAdmin) |
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.forms import BaseDynamicEntityForm |
||||
|
from eav.fields import RangeField |
||||
|
|
||||
class DiagnosticoForm(BaseDynamicEntityForm): |
class DiagnosticoForm(BaseDynamicEntityForm): |
||||
|
"""Classe responsável por contruir o formulário, |
||||
|
vinculando ao modelo Diagnostico |
||||
|
""" |
||||
model = 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