Browse Source

Add a ocurrence panel to Ocorrencia app

producao
Sesostris Vieira 10 years ago
parent
commit
4a616cbccf
  1. 2
      sigi/apps/home/templatetags/menu_conf.yaml
  2. 83
      sigi/apps/ocorrencias/forms.py
  3. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png
  4. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_diagonals-thick_20_666666_40x40.png
  5. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_flat_10_000000_40x100.png
  6. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_100_f6f6f6_1x400.png
  7. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_100_fdf5ce_1x400.png
  8. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_65_ffffff_1x400.png
  9. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png
  10. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
  11. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
  12. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_222222_256x240.png
  13. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_228ef1_256x240.png
  14. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ef8c08_256x240.png
  15. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ffd27a_256x240.png
  16. BIN
      sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ffffff_256x240.png
  17. 7
      sigi/apps/ocorrencias/static/ocorrencias/css/jquery-ui.min.css
  18. 5
      sigi/apps/ocorrencias/static/ocorrencias/css/jquery-ui.theme.min.css
  19. BIN
      sigi/apps/ocorrencias/static/ocorrencias/images/lid.png
  20. BIN
      sigi/apps/ocorrencias/static/ocorrencias/images/mm.png
  21. 13
      sigi/apps/ocorrencias/static/ocorrencias/js/jquery-ui.min.js
  22. 14
      sigi/apps/ocorrencias/templates/ocorrencias/anexo_form.html
  23. 24
      sigi/apps/ocorrencias/templates/ocorrencias/anexos_snippet.html
  24. 7
      sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_form.html
  25. 105
      sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_snippet.html
  26. 198
      sigi/apps/ocorrencias/templates/ocorrencias/painel.html
  27. 19
      sigi/apps/ocorrencias/urls.py
  28. 214
      sigi/apps/ocorrencias/views.py
  29. 3
      sigi/settings/base.py
  30. 1
      sigi/urls.py

2
sigi/apps/home/templatetags/menu_conf.yaml

@ -82,6 +82,8 @@ main_menu:
- title: Ocorrências - title: Ocorrências
url: ocorrencias/ocorrencia/?minhas=S&status__in=1,2 url: ocorrencias/ocorrencia/?minhas=S&status__in=1,2
children: children:
- title: Painel de ocorrências
url: ocorrencias/painel/
- title: Registro de ocorrências - title: Registro de ocorrências
url: ocorrencias/ocorrencia/?minhas=S&status__in=1,2 url: ocorrencias/ocorrencia/?minhas=S&status__in=1,2
- title: Tabela de categorias - title: Tabela de categorias

83
sigi/apps/ocorrencias/forms.py

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
#
# sigi.apps.ocorrencias.forms
#
# Copyright (c) 2015 by Interlegis
#
# GNU General Public License (GPL)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
from django.forms import ModelForm, ModelChoiceField, HiddenInput, TextInput
from sigi.apps.ocorrencias.models import Ocorrencia, Comentario, Anexo
from sigi.apps.servidores.models import Servico
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.forms.utils import flatatt
from django.core.urlresolvers import reverse_lazy
from django.utils.safestring import mark_safe
class AjaxSelect(TextInput):
url = ""
def __init__(self, url, attrs=None):
super(AjaxSelect, self).__init__(attrs)
self.url = url
def render(self, name, value, attrs=None):
if value is None:
value = ''
final_attrs = self.build_attrs(attrs, type=self.input_type)
code_attrs = self.build_attrs(type='hidden', name=name, id='hidden_'+name)
if value != '':
# Only add the 'value' attribute if a value is non-empty.
final_attrs['value'] = force_text(self._format_value(value))
result = format_html('<input{0} />', flatatt(final_attrs)) + "\n"
result = result + format_html('<input{0} />', flatatt(code_attrs))
js = """
<script type="text/javascript">
$( document ).ready(function() {
$("#id_%(name)s").autocomplete({
source: "%(url)s",
select: function(event, ui) {
$("#hidden_%(name)s").attr("value", ui.item.value);
ui.item.value = ui.item.label
}
})
});
</script>""" % {'name': name, 'url': self.url}
result = result + mark_safe(js)
return result
class AnexoForm(ModelForm):
class Meta:
model = Anexo
fields = ['ocorrencia', 'descricao', 'arquivo',]
widgets = {'ocorrencia': HiddenInput()}
class ComentarioForm(ModelForm):
encaminhar_setor = ModelChoiceField(queryset=Servico.objects.all(), cache_choices=True)
class Meta:
model = Comentario
fields = ['ocorrencia', 'descricao', 'novo_status', 'encaminhar_setor']
widgets = {'ocorrencia': HiddenInput(),}
class OcorrenciaForm(ModelForm):
class Meta:
model = Ocorrencia
fields = ['casa_legislativa', 'categoria', 'tipo_contato', 'assunto', 'prioridade',
'descricao', 'setor_responsavel',]
widgets = {'casa_legislativa': AjaxSelect(url=reverse_lazy('painel-buscacasa'), attrs={'size':100}), }

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_diagonals-thick_20_666666_40x40.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_flat_10_000000_40x100.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_100_f6f6f6_1x400.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_100_fdf5ce_1x400.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_glass_65_ffffff_1x400.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_222222_256x240.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_228ef1_256x240.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ef8c08_256x240.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ffd27a_256x240.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/css/images/ui-icons_ffffff_256x240.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

7
sigi/apps/ocorrencias/static/ocorrencias/css/jquery-ui.min.css

File diff suppressed because one or more lines are too long

5
sigi/apps/ocorrencias/static/ocorrencias/css/jquery-ui.theme.min.css

File diff suppressed because one or more lines are too long

BIN
sigi/apps/ocorrencias/static/ocorrencias/images/lid.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
sigi/apps/ocorrencias/static/ocorrencias/images/mm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

13
sigi/apps/ocorrencias/static/ocorrencias/js/jquery-ui.min.js

File diff suppressed because one or more lines are too long

14
sigi/apps/ocorrencias/templates/ocorrencias/anexo_form.html

@ -0,0 +1,14 @@
{% extends "admin/base.html" %}
{% load i18n admin_static %}
{% load static from staticfiles %}
{% block content_title %}<h1>{% trans "Enviar novo arquivo" %}</h1>{% endblock %}
{% block content %}
<div class="small">
<form id="form_anexos_{{ ocorrencia.id|safe }}" action="" method="POST" enctype="multipart/form-data" >
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Adicionar"/>
</form>
</div>
{% endblock %}

24
sigi/apps/ocorrencias/templates/ocorrencias/anexos_snippet.html

@ -0,0 +1,24 @@
{% load i18n admin_static %}
{% load static from staticfiles %}
{% if ocorrencia.anexo_set.exists %}
<table class="table">
<tr>
<th>{% trans "Descrição" %}</th>
<th>{% trans "Data de publicação" %}</th>
<th>&nbsp;</th>
</tr>
{% for anexo in ocorrencia.anexo_set.all %}
<tr>
<td><a href="{{ anexo.arquivo.url }}">{{ anexo.descricao }}</a></td>
<td>{{ anexo.data_pub }}</td>
<td><a href="{% url "ocorrencia-excluianexo" %}?anexo_id={{ anexo.id|safe }}"
data-ocorrencia-id="{{ ocorrencia.id|safe }}" onclick="return remove_anexo(this);">Excluir</a></td>
</tr>
{% endfor %}
</table>
{% endif %}
<a href="{% url 'ocorrencia-incluianexo' %}?ocorrencia_id={{ ocorrencia.id|safe }}" onclick="return showAddAnexoPopup(this);">
{% trans "Anexar novo arquivo" %}
</a>

7
sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_form.html

@ -0,0 +1,7 @@
<div class="panel-body">
<form id="form_ocorrencia" action="{% url 'ocorrencia-incluiocorrencia' %}" method="post">
{% csrf_token %}
{{ ocorrencia_form.as_p }}
<input type="submit" value="Salvar"/>
</form>
</div>

105
sigi/apps/ocorrencias/templates/ocorrencias/ocorrencia_snippet.html

@ -0,0 +1,105 @@
{% load i18n admin_static %}
{% load static from staticfiles %}
{% load thumbnail %}
{% static 'ocorrencias/images/lid.png' as default_lid %}
{% static 'ocorrencias/images/mm.png' as default_mm %}
<div class="panel panel-default" id='ticket_{{ ocorrencia.id|safe }}'>
<div class="panel-heading">
<div class="media">
<div class="media-left">
<img class="media-object" src="{{ ocorrencia.casa_legislativa.foto|thumbnail_url:'thumb'|default:default_lid }}" alt=""/>
</div>
<div class="media-body">
<h4><a href="{{ url_painel }}?type=casa&id={{ ocorrencia.casa_legislativa_id|safe }}">
{{ ocorrencia.casa_legislativa.nome }}, {{ ocorrencia.casa_legislativa.municipio.uf.sigla }}</a></h4>
<p><a href="{{ ocorrencia.get_absolute_url }}">{% trans "Ticket #" %}{{ ocorrencia.id|safe }}</a>:
{% blocktrans with data_criacao=ocorrencia.data_criacao tipo_contato=ocorrencia.tipo_contato categoria=ocorrencia.categoria id_setor=ocorrencia.setor_responsavel_id|safe setor=ocorrencia.setor_responsavel.sigla status=ocorrencia.get_status_display %}
Criado em {{ data_criacao }} via {{ tipo_contato }} solicitando {{ categoria }},
está no setor <a href="{{ url_painel }}?type=servico&id={{ id_setor }}">{{ setor }}</a>
com status {{ status }}
{% endblocktrans %}</p>
<p>{% trans "Gerente de contas:" %}
<a href="{{ url_painel }}?type=servidor&id={{ ocorrencia.casa_legislativa.gerente_contas_id|safe }}">
{{ ocorrencia.casa_legislativa.gerente_contas }}</a></p>
{% trans 'Prioridade' %}:
<div class="btn-group btn-group-xs" data-toggle="buttons" role="group" aria-label="...">
{% for id, name in PRIORITY_CHOICES %}
<label class="btn btn-primary {% if id == ocorrencia.prioridade %}active{% endif %}">
<input type="radio" name="ocorrencia-{{ ocorrencia.id|safe }}" value="{{ id|safe }}" autocomplete="off"{% if id == ocorrencia.prioridade %} checked {% endif %}>
{{ name }}
</label>
{% endfor %}
</div>
</div>
</div>
</div>
<div class="panel-body">
<div class="media">
<div class="media-left">
<img class="media-object" src="{{ ocorrencia.servidor_registro.foto|thumbnail_url:'icon'|default:default_mm }}" alt=""/>
</div>
<div class="media-body">
<p><a href="{{ url_painel }}?type=servidor&id={{ ocorrencia.servidor_registro_id|safe }}">
<strong>{{ ocorrencia.servidor_registro }}</strong></a>
{% trans 'comentou' %}:</p>
<p>{{ ocorrencia.descricao }}</p>
</div>
</div>
{% for comentario in ocorrencia.comentarios.all %}
<div class="media">
<div class="media-left">
<img class="media-object" src="{{ comentario.usuario.foto|thumbnail_url:'icon'|default:default_mm }}" alt=""/>
</div>
<div class="media-body">
<p><a href="{{ url_painel }}?type=servidor&id={{ comentario.usuario_id|safe }}">
<strong>{{ comentario.usuario.nome_completo }}</strong></a>
{% trans 'comentou' %}:</p>
<p>{{ comentario.descricao }}</p>
<p class="small">{% trans 'Em' %} {{ comentario.data_criacao }}
{% if comentarui.status %}
| {% trans 'novo status' %}: {{ comentario.get_novo_status_display }}
{% endif %}
{% if comentario.encaminhar_setor %}
| {% trans 'Encaminhado para' %} {{ comentario.encaminhar_setor.sigla }}
{% endif %}
</div>
</div>
{% endfor %}
<a id='link_comentar_{{ ocorrencia.id|safe }}' role="button" data-toggle="collapse" href="#comentario_{{ ocorrencia.id|safe }}" aria-expanded="false" aria-controls="comentario_{{ ocorrencia.id|safe }}">
{% trans "Comentar esta ocorrência" %}
</a>
<div class="collapse" id="comentario_{{ ocorrencia.id|safe }}">
<form id="comentar_ocorrencia_{{ ocorrencia.id|safe }}" action="{% url 'ocorrencia-incluicomentario' %}" method="post" data-ocorrencia-id="{{ ocorrencia.id|safe }}">
{% csrf_token %}
{{ comentario_form.non_field_errors }}
{% for field in comentario_form %}
<div class="fieldWrapper">
{% if field.name == 'ocorrencia' %}
<input type='hidden' name='ocorrencia' value='{{ ocorrencia.id|safe }}'/>
{% else %}
{{ field.errors }}
<p>{{ field.label_tag }} {{ field }}</p>
{% endif %}
</div>
{% endfor %}
<input type="submit" value="{% trans 'Comentar' %}">
</form>
</div>
</div>
<div class="panel-footer">
<a id='link_anexos_{{ ocorrencia.id|safe }}'role="button" data-toggle="collapse" href="#anexos_{{ ocorrencia.id|safe }}" aria-expanded="false" aria-controls="anexos_{{ ocorrencia.id|safe }}">
{% blocktrans count counter=ocorrencia.total_anexos %}
{{ counter }} arquivo anexo
{% plural %}
{{ counter }} arquivos anexos
{% endblocktrans %}
</a>
<div class="collapse" id="anexos_{{ ocorrencia.id|safe }}">
{% include 'ocorrencias/anexos_snippet.html' %}
</div>
</div>
</div>

198
sigi/apps/ocorrencias/templates/ocorrencias/painel.html

@ -0,0 +1,198 @@
{% extends "admin/base_site.html" %}
{% load i18n admin_static %}
{% load static from staticfiles %}
{% load thumbnail %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static 'ocorrencias/css/jquery-ui.min.css' %}"/>
{% endblock %}
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% static 'admin/js/core.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.min.js' %}" ></script>
<script type="text/javascript" src="{% static 'admin/js/jquery.init.js' %}" ></script>
<script type="text/javascript" src="{% static 'ocorrencias/js/jquery-ui.min.js' %}" ></script>
{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block content_title %}<h1>{{ panel_title }}</h1>{% endblock %}
{% block content %}
{% url 'painel-ocorrencias' as url_painel %}
<div id="content-main" class="container-fluid">
<div class="form-group">
<div class="input-group">
<input type="text" class="form-control" id="q" placeholder="{% trans 'Visitar o painel de' %}">
<span class="input-group-btn">
<button class="btn btn-default" type="button" onclick="window.location.href='{{ url_painel }}'">{% trans 'Meu painel' %}</button>
</span>
</div>
</div>
<div class="nav nav-pills">
<span class="glyphicon glyphicon-plus"></span>
<a role="button" data-toggle="collapse" href="#form_ocorrencia_panel" aria-expanded="false" aria-controls="form_ocorrencia_panel">
{% trans "Registrar nova ocorrência" %}
</a>
</div>
<div class="collapse panel panel-default" id='form_ocorrencia_panel'>
{% include 'ocorrencias/ocorrencia_form.html' %}
</div>
{% if paineis %}
<ul class="nav nav-pills">
{% for k, v in paineis.iteritems %}
<li role="presentation" class="{% if k == painel %}active{% endif %}">
<a href="{{ url_painel }}?type=servidor&id={{ servidor.id }}&painel={{ k }}">
{{ v }}</a></li>
{% endfor %}
</ul>
{% endif %}
<div class="row">
<div id="ocorrencias_display" class="col-md-12">
{% for ocorrencia in ocorrencias %}
{% include 'ocorrencias/ocorrencia_snippet.html' %}
{% empty %}
<div class="panel panel-default">
<div class="panel-body">
<p>{% trans 'Nenhuma ocorrência encontrada.' %}</p>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
<script type="text/javascript">
$( document ).ready(function() {
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^(GET|HEAD|OPTIONS|TRACE)$/.test(settings.type)) && !this.crossDomain) {
var cookieValue = null, name = 'csrftoken';
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
xhr.setRequestHeader("X-CSRFToken", cookieValue);
}
}
});
$("#q").autocomplete({
source: "{% url 'painel-buscanominal' %}",
select: function(event, ui) {
window.location.replace("{{ url_painel }}?type="+ui.item.origin+"&id="+ui.item.value);
ui.item.value = ui.item.label
}
})
$('input[name^=ocorrencia-]').on('change', function() {
var $this = $(this),
data = {'id_ocorrencia': $this.attr('name').split('-')[1],
'prioridade': $this.attr('value')};
$.post('{% url "ocorrencia-mudaprioridade" %}', data, function(result) {
if (result.result == 'error') {
alert(result.message);
$this.reset();
}
});
})
function inclui_comentario( event ) {
event.preventDefault()
var $this = $(this);
$.post($this.attr('action'), $this.serialize(), function( result ) {
$('div[id=ticket_'+result.ocorrencia_id+']').html(result.ocorrencia_panel);
$('form[id^=comentar_ocorrencia_').on('submit', inclui_comentario);
});
}
function inclui_ocorrencia( event ) {
event.preventDefault()
var $this = $(this);
$.post($this.attr('action'), $this.serialize(), function( result ) {
$("#form_ocorrencia_panel").html(result.ocorrencia_form);
if (result.result == 'success') {
$("#form_ocorrencia_panel").collapse('hide');
$("#ocorrencias_display").prepend(result.ocorrencia_panel);
$('form[id^=comentar_ocorrencia_').on('submit', inclui_comentario);
}
$('#form_ocorrencia').on('submit', inclui_ocorrencia);
});
}
$('form[id^=comentar_ocorrencia_').on('submit', inclui_comentario);
$('#form_ocorrencia').on('submit', inclui_ocorrencia);
});
function remove_anexo(link) {
var $this = $(link),
url = $this.attr('href'),
div = $("div#anexos_"+$this.attr('data-ocorrencia-id')),
link = $("a#link_anexos_"+$this.attr('data-ocorrencia-id'));
$( 'body' ).append('<div id="dialog-confirm" title="{% trans "Excluir anexo?" %}"><p><span class="glyphicon glyphicon-alert" style="float:left; margin:0 7px 20px 0;"></span>{% trans "Este anexo será definitivamente excluído e não poderá ser recuperado. Você confirma a exclusão?" %}</p></div>');
var dialog = $("#dialog-confirm");
dialog.dialog({
resizable: true,
modal: true,
buttons: {
"{% trans 'Excluir' %}": function() {
$.get(url, function(result) {
if (result.result == 'error') {
alert(result.message);
}
if (result.result == 'success') {
div.html(result.anexos_panel);
link.html(result.link_label);
}
});
dialog.dialog( 'destroy' );
},
"{% trans 'Cancelar' %}": function() {
dialog.dialog( 'destroy' );
}
}
});
return false;
}
function dismissAddAnexoPopup(win, ocorrencia_id) {
var div = $("div#anexos_"+ocorrencia_id),
link = $("a#link_anexos_"+ocorrencia_id);
win.close();
$.get('{% url "ocorrencia-anexosnippet" %}?ocorrencia_id='+ocorrencia_id, function( result ) {
div.html(result);
});
}
function showAddAnexoPopup(link) {
var $this = $(link),
href = $this.attr('href'),
win = window.open(href, '', 'height=500,width=800,resizable=yes,scrollbars=yes');
win.focus();
return false;
}
</script>
{% endblock %}

19
sigi/apps/ocorrencias/urls.py

@ -0,0 +1,19 @@
# coding: utf-8
from django.conf.urls import patterns, url
urlpatterns = patterns(
'sigi.apps.ocorrencias.views',
# Painel de ocorrencias
url(r'^painel/$', 'painel_ocorrencias', name='painel-ocorrencias'),
url(r'^painel/buscanominal/$', 'busca_nominal', {"origin": "tudo"}, name='painel-buscanominal'),
url(r'^painel/buscanominal/casa/$', 'busca_nominal', {"origin": "casa"}, name='painel-buscacasa'),
url(r'^painel/buscanominal/servidor/$', 'busca_nominal', {"origin": "servidor"}, name='painel-buscaservidor'),
url(r'^painel/buscanominal/servico/$', 'busca_nominal', {"origin": "servico"}, name='painel-buscaservico'),
url(r'^mudaprioridade/$', 'muda_prioridade', name='ocorrencia-mudaprioridade'),
url(r'^excluianexo/$', 'exclui_anexo', name='ocorrencia-excluianexo'),
url(r'^incluianexo/$', 'inclui_anexo', name='ocorrencia-incluianexo'),
url(r'^anexosnippet/$', 'anexo_snippet', name='ocorrencia-anexosnippet'),
url(r'^incluicomentario/$', 'inclui_comentario', name='ocorrencia-incluicomentario'),
url(r'^incluiocorrencia/$', 'inclui_ocorrencia', name='ocorrencia-incluiocorrencia'),
)

214
sigi/apps/ocorrencias/views.py

@ -0,0 +1,214 @@
# -*- coding: utf-8 -*-
from django.http import JsonResponse, Http404
from django.db.models import Q, Count
from django.utils.translation import ungettext, ugettext as _
from django.shortcuts import get_object_or_404, render, HttpResponse
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_POST
from django.template.loader import render_to_string
from django.template import RequestContext
from sigi.apps.utils import to_ascii
from sigi.apps.casas.models import CasaLegislativa
from sigi.apps.contatos.models import UnidadeFederativa
from sigi.apps.servidores.models import Servidor, Servico
from sigi.apps.ocorrencias.models import Ocorrencia, Anexo
from sigi.apps.ocorrencias.forms import AnexoForm, ComentarioForm, OcorrenciaForm
from django.utils.html import escape
@login_required
def painel_ocorrencias(request):
type = request.GET.get('type', None)
id = request.GET.get('id', None)
painel = request.GET.get('painel', None)
data = {}
if type is None or type == 'error':
type = 'servidor'
u = get_object_or_404(Servidor, user=request.user)
id = u.pk
if id is None:
raise Http404("id não definido")
if type == 'casa':
casa = get_object_or_404(CasaLegislativa, pk=id)
ocorrencias = Ocorrencia.objects.filter(casa_legislativa=casa)
panel_title = "%s, %s" % (casa.nome, casa.municipio.uf.sigla)
elif type == 'servidor':
servidor = get_object_or_404(Servidor, pk=id)
panel_title = servidor.nome_completo
paineis = {'gerente': 'Minhas casas', 'servico': 'Meu setor', 'timeline': 'Comentados por mim'}
if painel is None:
if CasaLegislativa.objects.filter(gerente_contas=servidor).count() > 0:
painel = 'gerente'
elif Ocorrencia.objects.filter(setor_responsavel=servidor.servico).count() > 0:
painel = 'servico'
else:
painel = 'timeline'
data.update({'paineis': paineis, 'painel': painel, 'servidor': servidor})
if painel == 'gerente':
ocorrencias = Ocorrencia.objects.filter(casa_legislativa__gerente_contas=servidor)
elif painel == 'servico':
ocorrencias = Ocorrencia.objects.filter(setor_responsavel_id=servidor.servico_id)
else:
ocorrencias = (Ocorrencia.objects.filter(servidor_registro=servidor) |
Ocorrencia.objects.filter(comentarios__usuario=servidor))
elif type == 'servico':
servico = get_object_or_404(Servico, pk=id)
ocorrencias = Ocorrencia.objects.filter(setor_responsavel_id=id)
panel_title = "%s - %s" % (servico.sigla, servico.nome)
ocorrencias = ocorrencias.filter(status__in=[1,2])
ocorrencias = ocorrencias.order_by('prioridade', '-data_modificacao')
ocorrencias = ocorrencias.select_related('casa_legislativa', 'categoria', 'tipo_contato', 'servidor_registro', 'setor_responsavel',
'casa_legislativa__gerente_contas')
ocorrencias = ocorrencias.prefetch_related('comentarios', 'comentarios__usuario', 'comentarios__encaminhar_setor',
'casa_legislativa__municipio', 'casa_legislativa__municipio__uf', 'anexo_set')
ocorrencias = ocorrencias.annotate(total_anexos=Count('anexo'))
data.update({'ocorrencias': ocorrencias, 'panel_title': panel_title, 'comentario_form': ComentarioForm(),
'ocorrencia_form': OcorrenciaForm(), 'PRIORITY_CHOICES': Ocorrencia.PRIORITY_CHOICES})
return render(request, 'ocorrencias/painel.html', data)
def busca_nominal(request, origin="tudo"):
term = request.GET.get('term', None)
if term is None:
return JsonResponse([{'label': _(u'Erro na pesquisa por termo'), 'value': 'type=error'}], safe=False)
data = []
if origin == "casa" or origin == "tudo":
casas = CasaLegislativa.objects.filter(search_text__icontains=to_ascii(term)).select_related('municipio', 'municipio__uf')[:10]
data += [{'value': c.pk, 'label': "%s, %s" % (c.nome, c.municipio.uf.sigla,), 'origin': 'casa'} for c in casas]
if origin == "servidor" or origin == "tudo":
servidores = Servidor.objects.filter(nome_completo__icontains=term)[:10]
data += [{'value': s.pk, 'label': s.nome_completo, 'origin': 'servidor'} for s in servidores]
if origin == "servico" or origin == "tudo":
setores = Servico.objects.filter(nome__icontains=term) | Servico.objects.filter(sigla__icontains=term)
setores = setores[:10]
data += [{'value': s.pk, 'label': '%s - %s' % (s.sigla, s.nome), 'origin': 'servico'} for s in setores]
data = sorted(data, key=lambda d: d['label'])
return JsonResponse(data, safe=False)
@login_required
@require_POST
def muda_prioridade(request):
id_ocorrencia = request.POST.get('id_ocorrencia', None)
prioridade = request.POST.get('prioridade', None)
if id_ocorrencia is None or prioridade is None:
return JsonResponse({'result': 'error', 'message': _(u'Erro nos parâmetros')})
if not any([int(prioridade) == p[0] for p in Ocorrencia.PRIORITY_CHOICES]):
return JsonResponse({'result': 'error', 'message': _(u'Valor de prioridade não aceito')})
try:
ocorrencia = Ocorrencia.objects.get(pk=id_ocorrencia)
except Exception as e:
return JsonResponse({'result': 'error', 'message': str(e)})
ocorrencia.prioridade = prioridade
ocorrencia.save()
return JsonResponse({'result': 'success', 'message': _(u'Prioridade alterada')})
@login_required
def exclui_anexo(request):
anexo_id = request.GET.get('anexo_id', None)
if anexo_id is None:
return JsonResponse({'result': 'error', 'message': _(u'Erro nos parâmetros')})
try:
anexo = Anexo.objects.get(pk=anexo_id)
except Exception as e:
return JsonResponse({'result': 'error', 'message': str(e)})
ocorrencia = anexo.ocorrencia
anexo.delete()
link_label = (ungettext('%s arquivo anexo', '%s arquivos anexos', ocorrencia.anexo_set.count()) %
(ocorrencia.anexo_set.count(),))
painel = render_to_string('ocorrencias/anexos_snippet.html', {'ocorrencia': ocorrencia},
context_instance=RequestContext(request))
return JsonResponse({'result': 'success', 'message': _(u'Anexo %s excluído com sucesso' % (anexo_id,)),
'link_label': link_label, 'anexos_panel': painel})
@login_required
def inclui_anexo(request):
if request.method == 'POST':
form = AnexoForm(request.POST, request.FILES)
if form.is_valid():
anexo = form.save()
return HttpResponse('<script type="text/javascript">opener.dismissAddAnexoPopup(window, "%s");</script>' %
escape(anexo.ocorrencia_id))
else:
ocorrencia = form.instance.ocorrencia
else:
ocorrencia_id = request.GET.get('ocorrencia_id', None)
ocorrencia = get_object_or_404(Ocorrencia, pk=ocorrencia_id)
form = AnexoForm(instance=Anexo(ocorrencia=ocorrencia))
return render(request, 'ocorrencias/anexo_form.html',
{'form': form, 'ocorrencia': ocorrencia, 'is_popup': True})
@login_required
def anexo_snippet(request):
ocorrencia_id = request.GET.get('ocorrencia_id', None)
ocorrencia = get_object_or_404(Ocorrencia, pk=ocorrencia_id)
return render(request, 'ocorrencias/anexos_snippet.html', {'ocorrencia': ocorrencia})
@login_required
@require_POST
def inclui_comentario(request):
form = ComentarioForm(request.POST)
if form.is_valid():
comentario = form.save(commit=False)
comentario.usuario = Servidor.objects.get(user=request.user)
comentario.save()
ocorrencia = comentario.ocorrencia
form = ComentarioForm()
else:
ocorrencia = form.instance.ocorrencia
painel = render_to_string('ocorrencias/ocorrencia_snippet.html', {'ocorrencia': ocorrencia,
'comentario_form': form,}, context_instance=RequestContext(request))
return JsonResponse({'ocorrencia_id': ocorrencia.id, 'ocorrencia_panel': painel})
@login_required
@require_POST
def inclui_ocorrencia(request):
form = OcorrenciaForm(request.POST)
data = {}
if form.is_valid():
ocorrencia = form.save(commit=False)
ocorrencia.servidor_registro = Servidor.objects.get(user=request.user)
ocorrencia.save()
form = OcorrenciaForm()
data['result'] = 'success'
data['ocorrencia_panel'] = render_to_string('ocorrencias/ocorrencia_snippet.html',
{'ocorrencia': ocorrencia, 'comentario_form': ComentarioForm(),
'PRIORITY_CHOICES': Ocorrencia.PRIORITY_CHOICES},
context_instance=RequestContext(request))
else:
data['result'] = 'error'
data['ocorrencia_form'] = render_to_string('ocorrencias/ocorrencia_form.html',
{'ocorrencia_form': form},
context_instance=RequestContext(request))
return JsonResponse(data)

3
sigi/settings/base.py

@ -138,6 +138,9 @@ THUMBNAIL_PROCESSORS = (
THUMBNAIL_ALIASES = { THUMBNAIL_ALIASES = {
'': { '': {
'small': {'size': (300, 225), 'crop': True, }, 'small': {'size': (300, 225), 'crop': True, },
'thumb': {'size': (160, 120), 'crop': True, },
'portrait': {'size': (73,100), 'crop': True},
'icon': {'size': (36,50), 'crop': True},
}, },
} }
IMAGE_CROPPING_SIZE_WARNING = True IMAGE_CROPPING_SIZE_WARNING = True

1
sigi/urls.py

@ -22,6 +22,7 @@ urlpatterns = patterns(
url(r'^servicos/', include('sigi.apps.servicos.urls')), url(r'^servicos/', include('sigi.apps.servicos.urls')),
url(r'^saberes/', include('sigi.apps.saberes.urls')), url(r'^saberes/', include('sigi.apps.saberes.urls')),
url(r'^dashboard/', include('sigi.apps.metas.urls')), url(r'^dashboard/', include('sigi.apps.metas.urls')),
url(r'^ocorrencias/', include('sigi.apps.ocorrencias.urls')),
url(r'^pentaho/(?P<path>(plugin|api)/.*)$', pentaho_proxy), url(r'^pentaho/(?P<path>(plugin|api)/.*)$', pentaho_proxy),
url(r'^', include(admin.site.urls)), url(r'^', include(admin.site.urls)),

Loading…
Cancel
Save