Revision 2ff5e689
Added by Jérôme Schneider over 12 years ago
calebasse/agenda/appointments.py | ||
---|---|---|
3 | 3 |
from django.db.models import Q |
4 | 4 |
from datetime import datetime, time |
5 | 5 |
|
6 |
from interval import IntervalSet |
|
7 |
|
|
6 | 8 |
from calebasse.actes.models import EventAct |
7 | 9 |
from calebasse.agenda.models import Occurrence |
8 | 10 |
from calebasse.personnes.models import TimeTable |
... | ... | |
77 | 79 |
self.title = title |
78 | 80 |
self.__set_time(time) |
79 | 81 |
|
80 |
def _add_free_time(delta, appointments, begin_time): |
|
81 |
if delta > 0: |
|
82 |
delta_minutes = delta / 60 |
|
83 |
appointment = Appointment() |
|
84 |
appointment.init_free_time(delta_minutes, begin_time) |
|
85 |
appointments.append(appointment) |
|
86 |
return appointments |
|
87 |
|
|
88 |
def get_daily_appointments(date, worker, service): |
|
82 |
def get_daily_appointments(date, worker, service, time_tables, occurrences): |
|
89 | 83 |
""" |
90 | 84 |
""" |
91 | 85 |
appointments = [] |
92 |
weekday_mapping = { |
|
93 |
'0': u'dimanche', |
|
94 |
'1': u'lundi', |
|
95 |
'2': u'mardi', |
|
96 |
'3': u'mercredi', |
|
97 |
'4': u'jeudi', |
|
98 |
'5': u'vendredi', |
|
99 |
'6': u'samedi' |
|
100 |
} |
|
101 |
weekday = weekday_mapping[date.strftime("%w")] |
|
102 |
time_tables = TimeTable.objects.filter(worker=worker).\ |
|
103 |
filter(service=service).\ |
|
104 |
filter(weekday=weekday).\ |
|
105 |
filter(start_date__lte=date).\ |
|
106 |
filter(Q(end_date=None) |Q(end_date__gte=date)).\ |
|
107 |
order_by('start_date') |
|
108 | 86 |
|
109 |
appointments = [] |
|
110 |
occurrences = Occurrence.objects.daily_occurrences(date, [worker]).order_by('start_time') |
|
87 |
timetables_set = IntervalSet((t.to_interval(date) for t in time_tables)) |
|
88 |
occurrences_set = IntervalSet((o.to_interval() for o in occurrences)) |
|
89 |
for free_time in timetables_set - occurrences_set: |
|
90 |
if free_time: |
|
91 |
delta = free_time.upper_bound - free_time.lower_bound |
|
92 |
delta_minutes = delta.seconds / 60 |
|
93 |
appointment = Appointment() |
|
94 |
appointment.init_free_time(delta_minutes, |
|
95 |
time(free_time.lower_bound.hour, free_time.upper_bound.minute)) |
|
96 |
appointments.append(appointment) |
|
111 | 97 |
for occurrence in occurrences: |
112 | 98 |
appointment = Appointment() |
113 | 99 |
appointment.init_from_occurrence(occurrence, service) |
114 | 100 |
appointments.append(appointment) |
115 |
# Find free times between occurrences in time_tables |
|
116 |
next_occurrences = Occurrence.objects.filter(start_time__gte=occurrence.end_time).order_by('start_time') |
|
117 |
if next_occurrences: |
|
118 |
next_occurrence = next_occurrences[0] |
|
119 |
if not Occurrence.objects.filter(end_time__gt=occurrence.end_time).filter(end_time__lt=next_occurrence.start_time): |
|
120 |
for time_table in time_tables: |
|
121 |
start_time_table = datetime(date.year, date.month, date.day, |
|
122 |
time_table.start_time.hour, time_table.start_time.minute) |
|
123 |
end_time_table = datetime(date.year, date.month, date.day, |
|
124 |
time_table.end_time.hour, time_table.end_time.minute) |
|
125 |
if (occurrence.end_time >= start_time_table) and (next_occurrence.start_time < end_time_table): |
|
126 |
delta = next_occurrence.start_time - occurrence.end_time |
|
127 |
appointments = _add_free_time(delta.seconds, appointments, |
|
128 |
time(occurrence.end_time.hour, occurrence.end_time.minute)) |
|
129 |
|
|
130 | 101 |
for time_table in time_tables: |
131 | 102 |
appointment = Appointment() |
132 | 103 |
appointment.init_start_stop(u"Arrivée", |
... | ... | |
136 | 107 |
appointment.init_start_stop(u"Départ", |
137 | 108 |
time(time_table.end_time.hour, time_table.end_time.minute)) |
138 | 109 |
appointments.append(appointment) |
139 |
start_datetime = datetime(date.year, date.month, date.day, |
|
140 |
time_table.start_time.hour, time_table.start_time.minute) |
|
141 |
end_datetime = datetime(date.year, date.month, date.day, |
|
142 |
time_table.end_time.hour, time_table.end_time.minute) |
|
143 |
smallest = Occurrence.objects.smallest_start_in_range(start_datetime, end_datetime, [worker]) |
|
144 |
biggest = Occurrence.objects.biggest_end_in_range(start_datetime, end_datetime, [worker]) |
|
145 |
if not smallest and not biggest: |
|
146 |
delta = end_datetime - start_datetime |
|
147 |
appointments = _add_free_time(delta.seconds, appointments, |
|
148 |
time(start_datetime.hour, start_datetime.minute)) |
|
149 |
if smallest: |
|
150 |
delta = smallest.start_time - start_datetime |
|
151 |
appointments = _add_free_time(delta.seconds, appointments, |
|
152 |
time(start_datetime.hour, start_datetime.minute)) |
|
153 |
if biggest: |
|
154 |
delta = end_datetime - biggest.end_time |
|
155 |
appointments = _add_free_time(delta.seconds, appointments, |
|
156 |
time(biggest.end_time.hour, biggest.end_time.minute)) |
|
157 | 110 |
|
158 | 111 |
appointments = sorted(appointments, key=lambda app: app.begin_time) |
159 | 112 |
return appointments |
calebasse/agenda/models.py | ||
---|---|---|
159 | 159 |
|
160 | 160 |
def to_interval(self): |
161 | 161 |
return Interval(self.start_time, self.end_time) |
162 |
|
calebasse/agenda/utils.py | ||
---|---|---|
1 |
from interval import IntervalSet |
|
2 |
|
|
3 |
def free_time(date, timetables, events): |
|
4 |
timetables = IntervalSet((t.to_interval(date) for t in timetables)) |
|
5 |
events = IntervalSet((e.to_interval() for e in events)) |
|
6 |
for free_time in timetables - events: |
|
7 |
yield free_time |
calebasse/agenda/views.py | ||
---|---|---|
1 | 1 |
import datetime |
2 | 2 |
|
3 |
from django.db.models import Q |
|
3 | 4 |
from django.shortcuts import redirect |
4 | 5 |
|
5 | 6 |
from calebasse.cbv import TemplateView, CreateView |
6 | 7 |
from calebasse.agenda.models import Occurrence |
8 |
from calebasse.personnes.models import TimeTable |
|
7 | 9 |
from calebasse.actes.models import EventAct |
8 | 10 |
from calebasse.agenda.appointments import get_daily_appointments |
9 | 11 |
from calebasse.personnes.models import Worker |
... | ... | |
22 | 24 |
|
23 | 25 |
def get_context_data(self, **kwargs): |
24 | 26 |
context = super(AgendaHomepageView, self).get_context_data(**kwargs) |
27 |
|
|
28 |
weekday_mapping = { |
|
29 |
'0': u'dimanche', |
|
30 |
'1': u'lundi', |
|
31 |
'2': u'mardi', |
|
32 |
'3': u'mercredi', |
|
33 |
'4': u'jeudi', |
|
34 |
'5': u'vendredi', |
|
35 |
'6': u'samedi' |
|
36 |
} |
|
37 |
weekday = weekday_mapping[context['date'].strftime("%w")] |
|
38 |
time_tables = TimeTable.objects.select_related().\ |
|
39 |
filter(service=self.service).\ |
|
40 |
filter(weekday=weekday).\ |
|
41 |
filter(start_date__lte=context['date']).\ |
|
42 |
filter(Q(end_date=None) |Q(end_date__gte=context['date'])).\ |
|
43 |
order_by('start_date') |
|
44 |
occurrences = Occurrence.objects.daily_occurrences(context['date']).select_related().order_by('start_time') |
|
45 |
|
|
25 | 46 |
context['workers_types'] = [] |
26 | 47 |
context['workers_agenda'] = [] |
27 | 48 |
context['disponnibility'] = {} |
28 | 49 |
workers = [] |
29 |
service = Service.objects.get(name=context['service_name']) |
|
30 | 50 |
for worker_type in WorkerType.objects.all(): |
31 | 51 |
data = {'type': worker_type.name, 'workers': Worker.objects.for_service(self.service, worker_type) } |
32 | 52 |
context['workers_types'].append(data) |
33 | 53 |
workers.extend(data['workers']) |
34 | 54 |
|
35 | 55 |
for worker in workers: |
56 |
time_tables_worker = [tt for tt in time_tables if tt.worker.id == worker.id] |
|
57 |
occurrences_worker = [o for o in occurrences for id in o.event.participants.values_list('id') if id[0] == worker.id] |
|
36 | 58 |
context['workers_agenda'].append({'worker': worker, |
37 |
'appointments': get_daily_appointments(context['date'], worker, service)}) |
|
59 |
'appointments': get_daily_appointments(context['date'], worker, self.service, |
|
60 |
time_tables_worker, occurrences_worker)}) |
|
38 | 61 |
|
39 | 62 |
context['disponibility'] = Occurrence.objects.daily_disponiblity(context['date'], workers) |
40 | 63 |
return context |
... | ... | |
62 | 85 |
|
63 | 86 |
def new_appointment(request): |
64 | 87 |
pass |
88 |
|
calebasse/fixtures/personnes.json | ||
---|---|---|
57 | 57 |
"pk": 7, |
58 | 58 |
"model": "personnes.people", |
59 | 59 |
"fields": { |
60 |
"first_name": " Lepoulpe",
|
|
61 |
"last_name": "Pol",
|
|
62 |
"display_name": " Lepoulpe Pol"
|
|
60 |
"first_name": "Pol",
|
|
61 |
"last_name": "Lepoulpe",
|
|
62 |
"display_name": "Pol Lepoulpe"
|
|
63 | 63 |
} |
64 | 64 |
}, |
65 | 65 |
{ |
scripts/import_db.py | ||
---|---|---|
1 | 1 |
#!/usr/bin/env python |
2 | 2 |
|
3 |
import ipdb |
|
4 | 3 |
import os |
5 | 4 |
import csv |
6 | 5 |
|
Also available in: Unified diff
agenda: optimize appoinments rendering and use interval lib
sql request * calebasse/agenda/views.py: use more generic sql requests * calebasse/agenda/models.py: cosmetic * calebasse/agenda/utils.py: deleted is use this function into
appointments * calebasse/fixtures/personnes.json: rename Lepouple Pol to Pol
Lepouple * scripts/import_db.py: remove ipdb