mirror of https://github.com/interlegis/sigi.git
Sesostris Vieira
9 years ago
4 changed files with 210 additions and 1 deletions
@ -0,0 +1,96 @@ |
|||||
|
{% extends "admin/base_site.html" %} |
||||
|
{% load i18n admin_static %} |
||||
|
{% load static from staticfiles %} |
||||
|
{% load thumbnail %} |
||||
|
|
||||
|
{% block extrastyle %} |
||||
|
<style type="text/css"> |
||||
|
th { |
||||
|
text-align: center !important; |
||||
|
vertical-align: bottom !important; |
||||
|
} |
||||
|
</style> |
||||
|
{{ block.super }} |
||||
|
{% endblock %} |
||||
|
|
||||
|
{% block extrahead %} |
||||
|
{{ block.super }} |
||||
|
{% endblock %} |
||||
|
|
||||
|
{% block coltype %}colMS{% endblock %} |
||||
|
|
||||
|
{% block content_title %}<h1>{% blocktrans %}Eventos de {{ mes_pesquisa }}/{{ ano_pesquisa }}{% endblocktrans %}</h1>{% endblock %} |
||||
|
|
||||
|
{% block object-tools-items %} |
||||
|
{% if prev_button %} |
||||
|
<li><a href="?mes={{ prev_button.mes|safe }}&ano={{ prev_button.ano|safe }}">{% trans "Mês anterior" %}</a></li> |
||||
|
{% endif %} |
||||
|
{% if next_button %} |
||||
|
<li><a href="?mes={{ next_button.mes|safe }}&ano={{ next_button.ano|safe }}">{% trans "Próximo mês" %}</a></li> |
||||
|
{% endif %} |
||||
|
{% endblock %} |
||||
|
|
||||
|
{% block content %} |
||||
|
<div class="table-responsive"> |
||||
|
<table class="table table-condensed table-bordered"> |
||||
|
<tr> |
||||
|
{% for d in dates %} |
||||
|
<th>{{ d|date:'D' }}</th> |
||||
|
{% endfor %} |
||||
|
</tr> |
||||
|
{% for d in dates %} |
||||
|
<th>{% ifchanged d|date:'b' %}{{ d|date:'b' }}<br/>{% endifchanged %}{{ d|date:'j' }}</th> |
||||
|
{% endfor %} |
||||
|
</tr> |
||||
|
{% for linha in linhas %} |
||||
|
<tr> |
||||
|
{% for evento in linha %} |
||||
|
{% if evento.start > 0 %} |
||||
|
<td colspan="{{ evento.start }}"> </td> |
||||
|
{% endif %} |
||||
|
|
||||
|
<td colspan="{{ evento.duration }}" class="{% if evento.evento.status == 'P' %}active{% endif %}{% if evento.evento.status == 'A' %}success{% endif %}{% if evento.evento.status == 'R' %}info{% endif %}{% if evento.evento.status == 'C' %}danger{% endif %}"> |
||||
|
<h5><a href="{% url 'admin:eventos_evento_change' evento.evento.pk %}">{{ evento.evento.nome }}</a></h5> |
||||
|
<h6>({{ evento.evento.tipo_evento }})</h6> |
||||
|
<dl class="dl-horizontal"> |
||||
|
{% if evento.evento.solicitante %} |
||||
|
<dt>{% trans "Solicitante" %}:</dt> |
||||
|
<dd>{{ evento.evento.solicitante }}</dd> |
||||
|
{% endif %} |
||||
|
|
||||
|
{% if evento.evento.casa_anfitria %} |
||||
|
<dt>{% trans "Casa anfitriã" %}:</dt> |
||||
|
<dd>{{ evento.evento.casa_anfitria }}<dd> |
||||
|
{% endif %} |
||||
|
|
||||
|
<dt>{% trans "Município" %}:</dt> |
||||
|
<dd>{{ evento.evento.municipio }}<dd> |
||||
|
<dt>{% trans "Status" %}:</dt> |
||||
|
<dd>{{ evento.evento.get_status_display }}<dd> |
||||
|
|
||||
|
{% if evento.evento.data_cancelamento %} |
||||
|
<dt>{% trans "Data de cancelamento" %}:</dt> |
||||
|
<dd>{{ evento.evento.data_cancelamento }}<dd> |
||||
|
{% endif %} |
||||
|
|
||||
|
{% if evento.evento.equipe_set.count > 0 %} |
||||
|
<dt>{% trans "Equipe" %}:</dt> |
||||
|
<dd><ul class="list-unstyled"> |
||||
|
{% for m in evento.evento.equipe_set.all %} |
||||
|
<li>{{ m.membro }} ({{ m.funcao }})</li> |
||||
|
{% endfor %} |
||||
|
<ul><dd> |
||||
|
{% endif %} |
||||
|
</dl> |
||||
|
</td> |
||||
|
|
||||
|
{% if evento.close > 0 %} |
||||
|
<td colspan="{{ evento.close }}"> </td> |
||||
|
{% endif %} |
||||
|
|
||||
|
{% endfor %} |
||||
|
</tr> |
||||
|
{% endfor %} |
||||
|
</table> |
||||
|
</div> |
||||
|
{% endblock %} |
@ -0,0 +1,9 @@ |
|||||
|
# coding: utf-8 |
||||
|
from django.conf.urls import patterns, url |
||||
|
|
||||
|
|
||||
|
urlpatterns = patterns( |
||||
|
'sigi.apps.eventos.views', |
||||
|
# Painel de ocorrencias |
||||
|
url(r'^calendario/$', 'calendario', name='eventos-calendario'), |
||||
|
) |
@ -1,3 +1,106 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# |
||||
|
# sigi.apps.eventos.views |
||||
|
# |
||||
|
# Copyright (C) 2015 Interlegis |
||||
|
# |
||||
|
# 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. |
||||
|
|
||||
|
import calendar |
||||
|
import datetime |
||||
|
from django.contrib.auth.decorators import login_required |
||||
from django.shortcuts import render |
from django.shortcuts import render |
||||
|
from sigi.apps.eventos.models import Evento |
||||
|
|
||||
|
@login_required |
||||
|
def calendario(request): |
||||
|
mes_pesquisa = int(request.GET.get('mes', datetime.date.today().month)) |
||||
|
ano_pesquisa = int(request.GET.get('ano', datetime.date.today().year)) |
||||
|
|
||||
|
dia1 = datetime.date(ano_pesquisa, mes_pesquisa, 1) |
||||
|
mes_anterior = dia1 - datetime.timedelta(days=1) |
||||
|
mes_seguinte = dia1.replace(day=28) + datetime.timedelta(days=4) # Ugly hack |
||||
|
mes_seguinte = mes_seguinte.replace(day=1) |
||||
|
|
||||
|
data = {'mes_pesquisa': mes_pesquisa, 'ano_pesquisa': ano_pesquisa} |
||||
|
|
||||
|
if Evento.objects.filter(data_inicio__year=mes_anterior.year, |
||||
|
data_inicio__month=mes_anterior.month).exists(): |
||||
|
data['prev_button'] = {'mes': mes_anterior.month, 'ano': mes_anterior.year } |
||||
|
|
||||
|
if Evento.objects.filter(data_inicio__year=mes_seguinte.year, |
||||
|
data_inicio__month=mes_seguinte.month).exists(): |
||||
|
data['next_button'] = {'mes': mes_seguinte.month, 'ano': mes_seguinte.year } |
||||
|
|
||||
|
c = calendar.Calendar(6) |
||||
|
dates = reduce(lambda x,y: x+y, c.monthdatescalendar(ano_pesquisa, mes_pesquisa)) |
||||
|
|
||||
|
eventos = [] |
||||
|
|
||||
|
for evento in Evento.objects.filter(data_inicio__year=ano_pesquisa, |
||||
|
data_inicio__month=mes_pesquisa).order_by('data_inicio'): |
||||
|
start = dates.index(evento.data_inicio) |
||||
|
if not evento.data_termino in dates: |
||||
|
lastday = dates[-1] |
||||
|
while lastday < evento.data_termino: |
||||
|
lastday = lastday + datetime.timedelta(days=1) |
||||
|
dates.append(lastday) |
||||
|
eventos.append({'evento': evento, 'start': start}) |
||||
|
|
||||
|
# Calcula a distância dos eventos para as bordas do calendário |
||||
|
for evento in eventos: |
||||
|
end = dates.index(evento['evento'].data_termino) |
||||
|
evento['duration'] = end-evento['start']+1 |
||||
|
evento['close'] = len(dates)-end-1 |
||||
|
|
||||
|
# Agrupa os eventos em linhas para melhorar a visualização |
||||
|
linhas = [] |
||||
|
|
||||
|
for evento in eventos: |
||||
|
encaixado = False |
||||
|
for linha in linhas: |
||||
|
sobrepoe = False |
||||
|
for e in linha: |
||||
|
if (((evento['evento'].data_inicio >= e['evento'].data_inicio) and |
||||
|
(evento['evento'].data_inicio <= e['evento'].data_termino)) or |
||||
|
((evento['evento'].data_termino >= e['evento'].data_inicio) and |
||||
|
(evento['evento'].data_termino <= e['evento'].data_termino))): |
||||
|
sobrepoe = True |
||||
|
break |
||||
|
if not sobrepoe: |
||||
|
# Adiona o evento em uma linha que ele não sobrepoe nenhum outro |
||||
|
linha.append(evento) |
||||
|
encaixado = True |
||||
|
break |
||||
|
if not encaixado: |
||||
|
# Adiciona uma nova linha porque este evento não se encaixa em nenhuma existente |
||||
|
linhas.append([evento]) |
||||
|
|
||||
|
# Recalcula as distâncias dos eventos por linha para encaixar no calendário |
||||
|
for linha in linhas: |
||||
|
anterior = None |
||||
|
for evento in linha: |
||||
|
if anterior is None: |
||||
|
anterior = evento |
||||
|
continue |
||||
|
anterior['close'] = (evento['evento'].data_inicio - anterior['evento'].data_termino).days-1 |
||||
|
evento['start'] = 0 |
||||
|
anterior = evento |
||||
|
|
||||
|
data['dates'] = dates |
||||
|
data['eventos'] = eventos |
||||
|
data['linhas'] = linhas |
||||
|
|
||||
# Create your views here. |
return render(request, 'eventos/calendario.html', data) |
Loading…
Reference in new issue