Browse Source

Exportar dados de oficinas para CSV

pull/66/head
Sesostris Vieira 4 years ago
parent
commit
c23371695c
  1. 23
      sigi/apps/eventos/admin.py
  2. 1
      sigi/apps/eventos/templates/admin/eventos/change_list.html
  3. 63
      sigi/apps/eventos/templates/eventos/carrinho.html
  4. 9
      sigi/apps/eventos/urls.py
  5. 178
      sigi/apps/eventos/views.py

23
sigi/apps/eventos/admin.py

@ -18,10 +18,12 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
from django.contrib import admin
from django import forms from django import forms
from django.contrib import admin
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from sigi.apps.eventos.models import TipoEvento, Funcao, Evento, Equipe, Convite from sigi.apps.eventos.models import TipoEvento, Funcao, Evento, Equipe, Convite
from sigi.apps.eventos.views import adicionar_eventos_carrinho
class EventoAdminForm(forms.ModelForm): class EventoAdminForm(forms.ModelForm):
class Meta: class Meta:
@ -70,3 +72,22 @@ class EventoAdmin(admin.ModelAdmin):
search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text', search_fields = ('nome', 'tipo_evento__nome', 'casa_anfitria__search_text',
'municipio__search_text', 'solicitante') 'municipio__search_text', 'solicitante')
inlines = (EquipeInline, ConviteInline) inlines = (EquipeInline, ConviteInline)
actions = ['adicionar_eventos', ]
def adicionar_eventos(self, request, queryset):
if 'carrinho_eventos' in request.session:
q1 = len(request.session['carrinho_eventos'])
else:
q1 = 0
response = adicionar_eventos_carrinho(request, queryset=queryset)
q2 = len(request.session['carrinho_eventos'])
quant = q2 - q1
if quant:
self.message_user(request, str(q2 - q1) + " " +
_(u"Eventos adicionados no carrinho"))
else:
self.message_user(request, _(u"Os Eventos selecionados "
u"já foram adicionados anteriormente"))
return HttpResponseRedirect('.')
adicionar_eventos.short_description = _(u"Armazenar eventos no carrinho "
u"para exportar")

1
sigi/apps/eventos/templates/admin/eventos/change_list.html

@ -0,0 +1 @@
{% extends "change_list_with_cart.html" %}

63
sigi/apps/eventos/templates/eventos/carrinho.html

@ -0,0 +1,63 @@
{% extends "admin/carrinho.html" %}
{% load admin_list i18n %}
{% block extrastyle %}
{{ block.super }}
{#% include "admin/tabs_style.html" %#}
{% endblock %}
{% block title %}{% trans 'Eventos no Carrinho | SIGI' %}{% endblock %}
{% block content_title %}<h1>{% trans 'Eventos no Carrinho' %}</h1>{% endblock %}
{% block mensagem%}
<ul class="messagelist">
{%if carIsEmpty%}
<li class="warning">{% trans 'O carrinho está vazio, sendo assim todos os eventos entram na lista para exportação de acordo com os filtros aplicados.' %}</li>
{%else%}
<li>{{paginas.paginator.count}} {% trans 'Eventos no carrinho' %}.</li>
{%endif%}
</ul>
{% endblock %}
{% block action %}deleta_itens_carrinho{% endblock %}
{% block tabela %}
<table class="table table-striped">
<thead class="thead-dark">
<tr>
{%if not carIsEmpty%}
<th><!-- <input type="checkbox" id="action-toggle" style="display: inline;">-->
</th>
{% endif %}
<th>{% trans 'Nome do evento' %}</th>
<th>{% trans 'Tipo evento' %}</th>
<th>{% trans 'Status' %}</th>
<th>{% trans 'Data de início' %}</th>
<th>{% trans 'Data de término' %}</th>
<th>{% trans 'município' %}</th>
<th>{% trans 'Solicitante' %}</th>
</tr>
</thead>
<tbody>
{% for evento in paginas.object_list %}
<tr>
{%if not carIsEmpty%}
<th><input type="checkbox" name="_selected_action"
value="{{evento.id|safe}}" class="action-select" />
</th>
{% endif %}
<td style="text-align: left;">{{evento.nome}}</td>
<td>{{evento.tipo_evento}}</td>
<td>{{evento.get_status_display}}</td>
<td>{{evento.data_inicio}}</td>
<td>{{evento.data_termino}}</td>
<td>{{evento.municipio}}</td>
<td>{{evento.solicitante}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block botoes %}
<a class="btn btn-primary" href="../csv/{{query_str}}">{% trans "Exportar CVS" %}</a>
{% endblock %}

9
sigi/apps/eventos/urls.py

@ -7,4 +7,13 @@ urlpatterns = patterns(
# Painel de ocorrencias # Painel de ocorrencias
url(r'^calendario/$', 'calendario', name='eventos-calendario'), url(r'^calendario/$', 'calendario', name='eventos-calendario'),
url(r'^alocacaoequipe/$', 'alocacao_equipe', name='eventos-alocacaoequipe'), url(r'^alocacaoequipe/$', 'alocacao_equipe', name='eventos-alocacaoequipe'),
# Carrinho
url(r'^evento/carrinho/$', 'visualizar_carrinho',
name='visualizar-carrinho-evento'),
url(r'^evento/carrinho/excluir_carrinho/$', 'excluir_carrinho',
name='excluir-carrinho-evento'), # Error
url(r'^evento/carrinho/deleta_itens_carrinho$', 'deleta_itens_carrinho',
name='deleta-itens-carrinho-evento'), # Error
url(r'^evento/csv/$', 'export_csv', name='evento-export-csv'), # Error
) )

178
sigi/apps/eventos/views.py

@ -21,11 +21,14 @@
import calendar import calendar
import datetime import datetime
import locale import locale
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import render from django.shortcuts import render
from django.utils import translation from django.utils import translation
from django.utils.translation import ungettext, ugettext as _ from django.utils.translation import ungettext, ugettext as _
from sigi.apps.eventos.models import Evento from sigi.apps.eventos.models import Evento, Equipe, Convite
from sigi.apps.servidores.models import Servidor from sigi.apps.servidores.models import Servidor
from sigi.shortcuts import render_to_pdf from sigi.shortcuts import render_to_pdf
import csv import csv
@ -189,3 +192,176 @@ def alocacao_equipe(request):
return JsonResponse(result) return JsonResponse(result)
return render(request, 'eventos/alocacao_equipe.html', data) return render(request, 'eventos/alocacao_equipe.html', data)
# Views e functions para carrinho de exportação
def query_ordena(qs, o):
from sigi.apps.eventos.admin import EventoAdmin
list_display = EventoAdmin.list_display
order_fields = []
for order_number in o.split('.'):
order_number = int(order_number)
order = ''
if order_number != abs(order_number):
order_number = abs(order_number)
order = '-'
order_fields.append(order + list_display[order_number - 1])
qs = qs.order_by(*order_fields)
return qs
def get_for_qs(get, qs):
kwargs = {}
for k, v in get.iteritems():
if str(k) not in ('page', 'pop', 'q', '_popup', 'o', 'ot'):
kwargs[str(k)] = v
qs = qs.filter(**kwargs)
if 'o' in get:
qs = query_ordena(qs, get['o'])
return qs
def carrinhoOrGet_for_qs(request):
if 'carrinho_eventos' in request.session:
ids = request.session['carrinho_eventos']
qs = Evento.objects.filter(pk__in=ids)
else:
qs = Evento.objects.all()
if request.GET:
qs = get_for_qs(request.GET, qs)
return qs
def adicionar_eventos_carrinho(request, queryset=None, id=None):
if request.method == 'POST':
ids_selecionados = request.POST.getlist('_selected_action')
if 'carrinho_eventos' not in request.session:
request.session['carrinho_eventos'] = ids_selecionados
else:
lista = request.session['carrinho_eventos']
# Verifica se id já não está adicionado
for id in ids_selecionados:
if id not in lista:
lista.append(id)
request.session['carrinho_eventos'] = lista
@login_required
def visualizar_carrinho(request):
qs = carrinhoOrGet_for_qs(request)
paginator = Paginator(qs, 100)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
paginas = paginator.page(page)
except (EmptyPage, InvalidPage):
paginas = paginator.page(paginator.num_pages)
carrinhoIsEmpty = not('carrinho_eventos' in request.session)
return render(
request,
'eventos/carrinho.html',
{
'carIsEmpty': carrinhoIsEmpty,
'paginas': paginas,
'query_str': '?' + request.META['QUERY_STRING']
}
)
@login_required
def excluir_carrinho(request):
if 'carrinho_eventos' in request.session:
del request.session['carrinho_eventos']
messages.info(request, u'O carrinho foi esvaziado')
return HttpResponseRedirect('../../')
@login_required
def deleta_itens_carrinho(request):
if request.method == 'POST':
ids_selecionados = request.POST.getlist('_selected_action')
removed = 0
if 'carrinho_eventos' in request.session:
lista = request.session['carrinho_eventos']
for item in ids_selecionados:
lista.remove(item)
removed += 1
if lista:
request.session['carrinho_eventos'] = lista
else:
del lista
del request.session['carrinho_eventos']
messages.info(request, u"{0} itens removidos do carrinho".format(removed))
return HttpResponseRedirect('.')
@login_required
def export_csv(request):
def serialize(r, field):
value = (getattr(r, 'get_{0}_display'.format(field.name), None) or
getattr(r, field.name, ""))
if callable(value):
value = value()
if value is None:
value = ""
return unicode(value).encode('utf8')
eventos_fields = Evento._meta.fields
equipe_fields = Equipe._meta.fields
convite_fields = Convite._meta.fields
eventos = carrinhoOrGet_for_qs(request)
eventos.select_related('equipe', 'convite')
if not eventos:
messages.info(request, _(u"Nenhum evento a exportar"))
return HttpResponseRedirect('../')
max_equipe = max([e.equipe_set.count() for e in eventos])
max_convite = max([e.convite_set.count() for e in eventos])
head = [f.verbose_name.encode('utf8') for f in eventos_fields
if f.name != 'id']
head.extend([f.verbose_name.encode('utf8')+"_{0}".format(i+1)
for i in range(max_equipe) for f in Equipe._meta.fields
if f.name not in ('id', 'evento')])
head.extend([f.verbose_name.encode('utf8')+"_{0}".format(i+1)
for i in range(max_convite) for f in Convite._meta.fields
if f.name not in ('id', 'evento')])
head.append('total_participantes')
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename=eventos.csv'
writer = csv.DictWriter(response, fieldnames=head)
writer.writeheader()
for evento in eventos:
reg = {f.verbose_name.encode('utf8'): serialize(evento, f)
for f in Evento._meta.fields if f.name != 'id'}
reg['total_participantes'] = 0
idx = 1
for membro in evento.equipe_set.all():
reg.update(
{
"{0}_{1}".format(f.verbose_name.encode('utf8'), idx):
serialize(membro, f) for f in Equipe._meta.fields
if f.name not in ('id', 'evento')
}
)
idx += 1
idx = 1
for convite in evento.convite_set.all():
reg.update(
{
"{0}_{1}".format(f.verbose_name.encode('utf8'), idx):
serialize(convite, f) for f in Convite._meta.fields
if f.name not in ('id', 'evento')
}
)
reg['total_participantes'] += convite.qtde_participantes
idx += 1
writer.writerow(reg)
return response

Loading…
Cancel
Save