Project

General

Profile

Download (27.9 KB) Statistics
| Branch: | Tag: | Revision:

calebasse / calebasse / agenda / views.py @ 881c0e89

1
# -*- coding: utf-8 -*-
2

    
3
import datetime
4
from itertools import chain
5

    
6
from django.contrib import messages
7
from django.db.models import Q
8
from django.shortcuts import redirect, get_object_or_404
9
from django.http import HttpResponseRedirect, HttpResponse
10

    
11
from calebasse.cbv import TemplateView, CreateView, UpdateView
12
from calebasse.agenda.models import Event, EventType, EventWithAct
13
from calebasse.personnes.models import TimeTable, Holiday
14
from calebasse.agenda.appointments import get_daily_appointments, get_daily_usage
15
from calebasse.personnes.models import Worker
16
from calebasse.ressources.models import WorkerType, Room
17
from calebasse.actes.validation import (get_acts_of_the_day,
18
        get_days_with_acts_not_locked)
19
from calebasse.actes.validation_states import VALIDATION_STATES
20
from calebasse.actes.models import Act, ValidationMessage
21
from calebasse.actes.validation import (automated_validation, unlock_all_acts_of_the_day)
22
from calebasse import cbv
23

    
24
from forms import (NewAppointmentForm, NewEventForm,
25
        UpdateAppointmentForm, UpdateEventForm, PeriodicEventsSearchForm)
26

    
27

    
28
def redirect_today(request, service):
29
    '''If not date is given we redirect on the agenda for today'''
30
    return redirect('agenda', date=datetime.date.today().strftime('%Y-%m-%d'),
31
            service=service)
32

    
33

    
34
class AgendaHomepageView(TemplateView):
35
    template_name = 'agenda/index.html'
36
    cookies_to_clear = []
37

    
38
    def post(self, request, *args, **kwargs):
39
        acte_id = request.POST.get('event-id')
40
        try:
41
            event = EventWithAct.objects.get(id=acte_id)
42
            event = event.today_occurrence(self.date)
43
            act = event.act
44
            if not act.validation_locked:
45
                state_name = request.POST.get('act_state')
46
                act.save()
47
                act.set_state(state_name, request.user)
48
        except Act.DoesNotExist:
49
            pass
50
        return HttpResponseRedirect('#acte-frame-'+acte_id)
51

    
52
    def get_context_data(self, **kwargs):
53
        context = super(AgendaHomepageView, self).get_context_data(**kwargs)
54

    
55
        context['workers_types'] = []
56
        workers = Worker.objects.filter(enabled=True).select_related() \
57
                .prefetch_related('services')
58
        worker_by_type = {}
59
        for worker in workers:
60
            workers_for_type = worker_by_type.setdefault(worker.type, [])
61
            workers_for_type.append(worker)
62
        for worker_type, workers_for_type in worker_by_type.iteritems():
63
            context['workers_types'].append(
64
                    {'type': worker_type.name, 'workers': workers_for_type })
65
        context['workers'] = workers
66
        context['disponibility_start_times'] = range(8, 20)
67

    
68
        return context
69

    
70

    
71
class AgendaServiceActivityView(TemplateView):
72
    template_name = 'agenda/service-activity.html'
73

    
74
    def get_context_data(self, **kwargs):
75
        context = super(AgendaServiceActivityView, self).get_context_data(**kwargs)
76

    
77
        appointments_times = dict()
78
        events = Event.objects.for_today(self.date) \
79
                .exclude(event_type_id=1) \
80
                .filter(services=self.service) \
81
                .order_by('start_datetime', 'id') \
82
                .select_related() \
83
                .prefetch_related('participants', 'exceptions')
84
        eventswithact = EventWithAct.objects.for_today(self.date) \
85
                .filter(services=self.service) \
86
                .order_by('start_datetime', 'id') \
87
                .select_related() \
88
                .prefetch_related('participants', 'exceptions')
89
        events = [ e.today_occurrence(self.date) for e in events ] \
90
             + [ e.today_occurrence(self.date) for e in eventswithact ]
91
        for event in events:
92
            start_datetime = event.start_datetime.strftime("%H:%M")
93
            if not appointments_times.has_key(start_datetime):
94
                appointments_times[start_datetime] = dict()
95
                appointments_times[start_datetime]['row'] = 0
96
                appointments_times[start_datetime]['appointments'] = []
97
            appointment = dict()
98
            length = event.end_datetime - event.start_datetime
99
            if length.seconds:
100
                length = length.seconds / 60
101
                appointment['length'] = "%sm" % length
102
            if event.event_type_id == 1:
103
                appointment['type'] = 1
104
                appointment['label'] = event.patient.display_name
105
                appointment['paper_id'] = event.patient.paper_id
106
                appointment['act'] = event.act_type.name
107
                appointment['state'] = event.act.get_state()
108
                appointment['absent'] = event.act.is_absent()
109
            else:
110
                appointment['type'] = 2
111
                if event.event_type.label == 'Autre' and event.title:
112
                    appointment['label'] = event.title
113
                else:
114
                    appointment['label'] = '%s - %s' % (event.event_type.label,
115
                                                        event.title)
116
            appointment['participants'] = event.participants.filter(worker__enabled=True)
117
            appointment['len_participants'] = len(appointment['participants'])
118
            appointments_times[start_datetime]['row'] += 1
119
            appointments_times[start_datetime]['appointments'].append(appointment)
120
        context['appointments_times'] = sorted(appointments_times.items())
121
        return context
122

    
123

    
124
class NewAppointmentView(cbv.ReturnToObjectMixin, cbv.ServiceFormMixin, CreateView):
125
    model = EventWithAct
126
    form_class = NewAppointmentForm
127
    template_name = 'agenda/new-appointment.html'
128
    success_url = '..'
129
    cookies_to_clear = []
130

    
131
    def get_initial(self):
132
        initial = super(NewAppointmentView, self).get_initial()
133
        initial['start_datetime'] = self.date
134
        initial['date'] = self.date
135
        initial['participants'] = self.request.GET.getlist('participants')
136
        initial['time'] = self.request.GET.get('time')
137
        initial['room'] = self.request.GET.get('room')
138
        return initial
139

    
140
    def get_form_kwargs(self):
141
        kwargs = super(NewAppointmentView, self).get_form_kwargs()
142
        kwargs['service'] = self.service
143
        return kwargs
144

    
145
    def form_valid(self, form):
146
        messages.add_message(self.request, messages.INFO, u'Rendez-vous enregistré avec succès.')
147
        return super(NewAppointmentView, self).form_valid(form)
148

    
149

    
150
class TodayOccurrenceMixin(object):
151
    def get_object(self, queryset=None):
152
        o = super(TodayOccurrenceMixin, self).get_object(queryset)
153
        return o.today_occurrence(self.date)
154

    
155

    
156
class BaseAppointmentView(UpdateView):
157
    model = EventWithAct
158
    form_class = UpdateAppointmentForm
159
    template_name = 'agenda/update-rdv.html'
160
    success_url = '..'
161
    cookies_to_clear = []
162

    
163
    def get_initial(self):
164
        initial = super(BaseAppointmentView, self).get_initial()
165
        initial['start_datetime'] = self.date
166
        initial['date'] = self.object.start_datetime.date()
167
        initial['time'] = self.object.start_datetime.time()
168
        time = self.object.end_datetime - self.object.start_datetime
169
        if time:
170
            time = time.seconds / 60
171
        else:
172
            time = 0
173
        initial['duration'] = time
174
        initial['participants'] = self.object.participants.values_list('id', flat=True)
175
        return initial
176

    
177
    def get_form_kwargs(self):
178
        kwargs = super(BaseAppointmentView, self).get_form_kwargs()
179
        kwargs['service'] = self.service
180
        return kwargs
181

    
182

    
183
class UpdateAppointmentView(TodayOccurrenceMixin, BaseAppointmentView):
184
    pass
185

    
186

    
187
class UpdatePeriodicAppointmentView(BaseAppointmentView):
188
    form_class = NewAppointmentForm
189
    template_name = 'agenda/new-appointment.html'
190

    
191

    
192
class NewEventView(CreateView):
193
    model = Event
194
    form_class = NewEventForm
195
    template_name = 'agenda/new-event.html'
196
    success_url = '..'
197
    cookies_to_clear = []
198

    
199
    def get_initial(self):
200
        initial = super(NewEventView, self).get_initial()
201
        initial['start_datetime'] = self.date
202
        initial['date'] = self.date
203
        initial['participants'] = self.request.GET.getlist('participants')
204
        initial['time'] = self.request.GET.get('time')
205
        initial['event_type'] = 2
206
        initial['room'] = self.request.GET.get('room')
207
        if not initial.has_key('services'):
208
            initial['services'] = [self.service]
209
        return initial
210

    
211
    def get_form_kwargs(self):
212
        kwargs = super(NewEventView, self).get_form_kwargs()
213
        kwargs['service'] = self.service
214
        return kwargs
215

    
216
    def form_valid(self, form):
217
        messages.add_message(self.request, messages.INFO, u'Evénement enregistré avec succès.')
218
        return super(NewEventView, self).form_valid(form)
219

    
220

    
221
class BaseEventView(UpdateView):
222
    model = Event
223
    form_class = UpdateEventForm
224
    template_name = 'agenda/update-event.html'
225
    success_url = '..'
226
    cookies_to_clear = []
227

    
228
    def get_initial(self):
229
        initial = super(BaseEventView, self).get_initial()
230
        initial['start_datetime'] = self.date
231
        initial['date'] = self.object.start_datetime.date()
232
        initial['time'] = self.object.start_datetime.time()
233
        time = self.object.end_datetime - self.object.start_datetime
234
        if time:
235
            time = time.seconds / 60
236
        else:
237
            time = 0
238
        initial['duration'] = time
239
        initial['participants'] = self.object.participants.values_list('id', flat=True)
240
        return initial
241

    
242
    def get_form_kwargs(self):
243
        kwargs = super(BaseEventView, self).get_form_kwargs()
244
        kwargs['service'] = self.service
245
        return kwargs
246

    
247

    
248
class UpdateEventView(TodayOccurrenceMixin, BaseEventView):
249
    pass
250

    
251

    
252
class UpdatePeriodicEventView(BaseEventView):
253
    form_class = NewEventForm
254
    template_name = 'agenda/new-event.html'
255

    
256

    
257
class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):
258
    model = Event
259
    success_url = '..'
260
    cookies_to_clear = []
261

    
262
    def delete(self, request, *args, **kwargs):
263
        self.object = self.get_object()
264
        if self.object.event_type == 1 and self.object.act.id \
265
                and not self.object.act.is_billed:
266
            self.object.act.delete()
267
        self.object.delete()
268

    
269
        return HttpResponse(status=204)
270

    
271
class DeleteEventView(cbv.DeleteView):
272
    """
273
    TODO: Remove this class
274
    """
275
    model = Event
276
    success_url = '..'
277
    cookies_to_clear = []
278

    
279
    def delete(self, request, *args, **kwargs):
280
        super(DeleteEventView, self).delete(request, *args, **kwargs)
281
        return HttpResponse(status=204)
282

    
283
class AgendaServiceActValidationView(TemplateView):
284
    template_name = 'agenda/act-validation.html'
285

    
286
    def acts_of_the_day(self):
287
        acts = list(Act.objects \
288
                .filter(date=self.date, patient__service=self.service) \
289
                .select_related() \
290
                .prefetch_related('doctors',
291
                        'patient__patientcontact',
292
                        'actvalidationstate_set__previous_state') \
293
                .order_by('time'))
294
        event_ids = [ a.parent_event_id for a in acts if a.parent_event_id ]
295
        events = EventWithAct.objects.for_today(self.date) \
296
                .filter(patient__service=self.service) \
297
                .exclude(id__in=event_ids)
298
        events = [ event.today_occurrence(self.date) for event in events ]
299
        acts += [ event.act for event in events if event ]
300
        return sorted(acts, key=lambda a: (a.time or datetime.time.min, a.id))
301

    
302
    def post(self, request, *args, **kwargs):
303
        if 'unlock-all' in request.POST:
304
            #TODO: check that the user is authorized
305
            unlock_all_acts_of_the_day(self.date, self.service)
306
            ValidationMessage(validation_date=self.date,
307
                who=request.user, what='Déverrouillage',
308
                service=self.service).save()
309
        else:
310
            acte_id = request.POST.get('acte-id')
311
            try:
312
                act = Act.objects.get(id=acte_id)
313
                if 'lock' in request.POST or 'unlock' in request.POST:
314
                    #TODO: check that the user is authorized
315
                    act.validation_locked = 'lock' in request.POST
316
                    act.save()
317
                else:
318
                    state_name = request.POST.get('act_state')
319
                    act.set_state(state_name, request.user)
320
            except Act.DoesNotExist:
321
                pass
322
            return HttpResponseRedirect('#acte-frame-'+acte_id)
323
        return HttpResponseRedirect('')
324

    
325
    def get_context_data(self, **kwargs):
326
        context = super(AgendaServiceActValidationView, self).get_context_data(**kwargs)
327
        authorized_lock = True # is_authorized_for_locking(get_request().user)
328
        validation_msg = ValidationMessage.objects.\
329
            filter(validation_date=self.date, service=self.service).\
330
            order_by('-when')[:3]
331
        acts_of_the_day = self.acts_of_the_day()
332
        actes = list()
333
        for act in acts_of_the_day:
334
            if not act.id:
335
                if act.date < datetime.date(2013, 1, 1):
336
                    continue
337
                else:
338
                    act.save()
339
            state = act.get_state()
340
            display_name = None
341
            if state :
342
                display_name = VALIDATION_STATES[state.state_name]
343
                if not state.previous_state_id and state.state_name == 'NON_VALIDE':
344
                    state = None
345
            actes.append((act, state, display_name))
346
        validation_states = dict(VALIDATION_STATES)
347
        if self.service.name != 'CMPP' and \
348
                'ACT_DOUBLE' in validation_states:
349
            validation_states.pop('ACT_DOUBLE')
350
        vs = [('VALIDE', 'Présent')]
351
        validation_states.pop('VALIDE')
352
        validation_states.pop('ACT_LOST')
353
        validation_states = vs + sorted(validation_states.items(), key=lambda tup: tup[0])
354
        context['validation_states'] = validation_states
355
        context['actes'] = actes
356
        context['validation_msg'] = validation_msg
357
        context['authorized_lock'] = authorized_lock
358
        return context
359

    
360

    
361
class AutomatedValidationView(TemplateView):
362
    template_name = 'agenda/automated-validation.html'
363

    
364
    def post(self, request, *args, **kwargs):
365
        automated_validation(self.date, self.service,
366
            request.user)
367
        ValidationMessage(validation_date=self.date,
368
            who=request.user, what='Validation automatique',
369
            service=self.service).save()
370
        return HttpResponseRedirect('..')
371

    
372
    def get_context_data(self, **kwargs):
373
        context = super(AutomatedValidationView, self).get_context_data(**kwargs)
374
        request = self.request
375
        (nb_acts_total, nb_acts_validated, nb_acts_double,
376
        nb_acts_abs_non_exc, nb_acts_abs_exc, nb_acts_abs_inter, nb_acts_annul_nous,
377
        nb_acts_annul_famille, nb_acts_reporte, nb_acts_abs_ess_pps,
378
        nb_acts_enf_hosp, nb_acts_losts) = \
379
            automated_validation(self.date, self.service,
380
                request.user, commit = False)
381

    
382
        nb_acts_not_validated = nb_acts_double + \
383
            nb_acts_abs_non_exc + \
384
            nb_acts_abs_exc + \
385
            nb_acts_abs_inter + \
386
            nb_acts_annul_nous + \
387
            nb_acts_annul_famille + \
388
            nb_acts_reporte + \
389
            nb_acts_abs_ess_pps + \
390
            nb_acts_enf_hosp + \
391
            nb_acts_losts
392
        context.update({
393
            'nb_acts_total': nb_acts_total,
394
            'nb_acts_validated': nb_acts_validated,
395
            'nb_acts_not_validated': nb_acts_not_validated,
396
            'nb_acts_double': nb_acts_double,
397
            'nb_acts_abs_non_exc': nb_acts_abs_non_exc,
398
            'nb_acts_abs_exc': nb_acts_abs_exc,
399
            'nb_acts_abs_inter': nb_acts_abs_inter,
400
            'nb_acts_annul_nous': nb_acts_annul_nous,
401
            'nb_acts_annul_famille': nb_acts_annul_famille,
402
            'nb_acts_reporte': nb_acts_reporte,
403
            'nb_acts_abs_ess_pps': nb_acts_abs_ess_pps,
404
            'nb_acts_enf_hosp': nb_acts_enf_hosp,
405
            'nb_acts_losts': nb_acts_losts})
406
        return context
407

    
408
class UnlockAllView(CreateView):
409
    pass
410

    
411

    
412
class AgendasTherapeutesView(AgendaHomepageView):
413
    template_name = 'agenda/agendas-therapeutes.html'
414

    
415
    def get_context_data(self, **kwargs):
416
        context = super(AgendasTherapeutesView, self).get_context_data(**kwargs)
417

    
418
        time_tables = TimeTable.objects.select_related('worker'). \
419
                filter(services=self.service). \
420
                for_today(self.date). \
421
                order_by('start_date')
422
        holidays = Holiday.objects.select_related('worker') \
423
                .for_period(self.date, self.date) \
424
                .order_by('start_date') \
425
                .select_related()
426
        events = Event.objects.for_today(self.date) \
427
                .exclude(event_type_id=1) \
428
                .filter(services=self.service) \
429
                .order_by('start_datetime') \
430
                .select_related() \
431
                .prefetch_related('services',
432
                        'exceptions',
433
                        'participants')
434
        eventswithact = EventWithAct.objects.for_today(self.date) \
435
                .filter(services=self.service) \
436
                .order_by('start_datetime') \
437
                .select_related() \
438
                .prefetch_related(
439
                        'services',
440
                        'patient__service',
441
                        'act_set__actvalidationstate_set',
442
                        'exceptions', 'participants')
443
        events = [ e.today_occurrence(self.date) for e in events ] \
444
             + [ e.today_occurrence(self.date) for e in eventswithact ]
445
        for e in events:
446
            e.workers_ids = set(p.id for p in e.participants.all())
447

    
448
        events_workers = {}
449
        time_tables_workers = {}
450
        holidays_workers = {}
451
        context['workers_agenda'] = []
452
        context['workers'] = context['workers'].filter(services=self.service)
453
        for worker in context['workers']:
454
            time_tables_worker = [tt for tt in time_tables if tt.worker.id == worker.id]
455
            events_worker = [o for o in events if worker.id in o.workers_ids ]
456
            holidays_worker = [h for h in holidays if h.worker_id in (None, worker.id)]
457
            events_workers[worker.id] = events_worker
458
            time_tables_workers[worker.id] = time_tables_worker
459
            holidays_workers[worker.id] = holidays_worker
460
            daily_appointments = get_daily_appointments(context['date'], worker, self.service,
461
                        time_tables_worker, events_worker, holidays_worker)
462
            if all(map(lambda x: x.holiday, daily_appointments)):
463
                continue
464
            context['workers_agenda'].append({'worker': worker,
465
                    'appointments': daily_appointments})
466

    
467
        for worker_agenda in context.get('workers_agenda', []):
468
            patient_appointments = [x for x in worker_agenda['appointments'] if x.patient_record_id]
469
            worker_agenda['summary'] = {
470
              'rdv': len(patient_appointments),
471
              'presence': len([x for x in patient_appointments if x.act_absence is None]),
472
              'absence': len([x for x in patient_appointments if x.act_absence is not None]),
473
              'doubles': len([x for x in patient_appointments if x.act_type == 'ACT_DOUBLE']),
474
              'valides': len([x for x in patient_appointments if x.act_type == 'ACT_VALIDE']),
475
            }
476

    
477
        return context
478

    
479
class JoursNonVerrouillesView(TemplateView):
480
    template_name = 'agenda/days-not-locked.html'
481

    
482
    def get_context_data(self, **kwargs):
483
        context = super(JoursNonVerrouillesView, self).get_context_data(**kwargs)
484
        acts = Act.objects.filter(is_billed=False,
485
            patient__service=self.service).order_by('date')
486
        days = set(acts.values_list('date', flat=True))
487
        if days:
488
            max_day, min_day = max(days), min(days)
489
            today = datetime.datetime.today().date()
490
            if max_day > today:
491
                max_day = today
492
            days &= set(get_days_with_acts_not_locked(min_day, max_day, self.service))
493
        context['days_not_locked'] = sorted(days)
494
        return context
495

    
496
class RessourcesView(TemplateView):
497

    
498
    template_name = 'agenda/ressources.html'
499

    
500
    def get_context_data(self, **kwargs):
501
        context = super(RessourcesView, self).get_context_data(**kwargs)
502

    
503
        plain_events = Event.objects.for_today(self.date) \
504
                .order_by('start_datetime').select_subclasses()
505
        events = [ e.today_occurrence(self.date) for e in plain_events ]
506

    
507
        context['ressources_types'] = []
508
        context['ressources_agenda'] = []
509
        context['disponibility'] = {}
510
        ressources = []
511
        data = {'type': Room._meta.verbose_name_plural, 'ressources': Room.objects.all() }
512
        context['ressources_types'].append(data)
513
        ressources.extend(data['ressources'])
514

    
515
        events_ressources = {}
516
        for ressource in ressources:
517
            events_ressource = [e for e in events if ressource == e.room]
518
            events_ressources[ressource.id] = events_ressource
519
            context['ressources_agenda'].append({'ressource': ressource,
520
                    'appointments': get_daily_usage(context['date'], ressource,
521
                        self.service, events_ressource)})
522

    
523
        return context
524

    
525
class AjaxWorkerTabView(TemplateView):
526

    
527
    template_name = 'agenda/ajax-worker-tab.html'
528
    cookies_to_clear = []
529

    
530
    def get_context_data(self, worker_id, **kwargs):
531
        context = super(AjaxWorkerTabView, self).get_context_data(**kwargs)
532
        worker = Worker.objects.get(id=worker_id)
533

    
534
        time_tables_worker = TimeTable.objects.select_related('worker'). \
535
                filter(services=self.service, worker=worker) \
536
                .for_today(self.date) \
537
                .order_by('start_date') \
538
                .select_related()
539
        holidays_worker = Holiday.objects.for_worker(worker) \
540
                .for_period(self.date, self.date) \
541
                .order_by('start_date') \
542
                .select_related()
543
        events = Event.objects.for_today(self.date) \
544
                .exclude(event_type_id=1) \
545
                .filter(participants=worker) \
546
                .order_by('start_datetime') \
547
                .select_related() \
548
                .prefetch_related('services',
549
                        'exceptions',
550
                        'participants')
551
        eventswithact = EventWithAct.objects.for_today(self.date) \
552
                .filter(participants=worker) \
553
                .order_by('start_datetime') \
554
                .select_related() \
555
                .prefetch_related('patient__addresses',
556
                        'patient__addresses__patientcontact_set',
557
                        'services',
558
                        'patient__service',
559
                        'act_set__actvalidationstate_set',
560
                        'exceptions', 'participants')
561
        events = [ e.today_occurrence(self.date) for e in events ] \
562
             + [ e.today_occurrence(self.date) for e in eventswithact ]
563

    
564
        context['worker_agenda'] = {'worker': worker,
565
                    'appointments': get_daily_appointments(context['date'], worker, self.service,
566
                        time_tables_worker, events, holidays_worker)}
567
        return context
568

    
569
class AjaxWorkerDisponibilityColumnView(TemplateView):
570

    
571
    template_name = 'agenda/ajax-worker-disponibility-column.html'
572
    cookies_to_clear = []
573

    
574
    def get_context_data(self, worker_id, **kwargs):
575
        context = super(AjaxWorkerDisponibilityColumnView, self).get_context_data(**kwargs)
576
        worker = Worker.objects.get(pk=worker_id)
577

    
578
        time_tables_worker = TimeTable.objects.select_related('worker'). \
579
                filter(services=self.service, worker=worker). \
580
                for_today(self.date). \
581
                order_by('start_date')
582
        holidays_worker = Holiday.objects.for_worker(worker). \
583
                for_period(self.date, self.date). \
584
                order_by('start_date')
585
        events = Event.objects.for_today(self.date) \
586
                .exclude(event_type_id=1) \
587
                .filter(participants=worker) \
588
                .order_by('start_datetime') \
589
                .select_related() \
590
                .prefetch_related('participants', 'exceptions')
591
        eventswithact = EventWithAct.objects.for_today(self.date) \
592
                .filter(participants=worker) \
593
                .order_by('start_datetime') \
594
                .select_related() \
595
                .prefetch_related('participants', 'exceptions',
596
                        'act_set__actvalidationstate_set')
597

    
598
        events = list(events) + list(eventswithact)
599
        events = [ e.today_occurrence(self.date) for e in events ]
600
        time_tables_workers = {worker.id: time_tables_worker}
601
        events_workers = {worker.id: events}
602
        holidays_workers = {worker.id: holidays_worker}
603

    
604
        context['initials'] = worker.initials
605
        context['worker_id'] = worker.id
606
        context['disponibility'] = Event.objects.daily_disponibilities(self.date,
607
                events_workers, [worker], time_tables_workers, holidays_workers)
608
        return context
609

    
610

    
611
class PeriodicEventsView(cbv.ListView):
612
    model = EventWithAct
613
    template_name = 'agenda/periodic-events.html'
614

    
615
    def dispatch(self, request, *args, **kwargs):
616
        if 'worker_id' in kwargs:
617
            self.worker = get_object_or_404(Worker, id=kwargs['worker_id'])
618
        else:
619
            self.worker = None
620
        return super(PeriodicEventsView, self).dispatch(request, *args, **kwargs)
621

    
622
    def get_form(self):
623
        kwargs = {
624
                'initial': {
625
                    'start_date': self.date,
626
                }
627
        }
628
        if self.request.GET:
629
            kwargs['data'] = self.request.GET
630
        self.form = PeriodicEventsSearchForm(prefix='periodic-events-search-form', **kwargs)
631
        return self.form
632

    
633
    def get_queryset(self):
634
        qs1 = Event.objects.exclude(event_type_id=1)
635
        qs2 = EventWithAct.objects.all()
636
        form = self.get_form()
637
        if not self.request.GET:
638
            return ()
639
        qs1 = self.filter_queryset(form, qs1)
640
        qs2 = self.filter_queryset(form, qs2)
641
        if form.is_valid():
642
            patient = form.cleaned_data.get('patient')
643
            if patient is not None:
644
                qs1 = qs1.none()
645
                qs2 = qs2.filter(patient=patient)
646
            worker = form.cleaned_data.get('worker')
647
            if worker is not None:
648
                qs1 = qs1.filter(participants=worker)
649
                qs2 = qs2.filter(participants=worker)
650
        return sorted(chain(qs1, qs2),
651
                key=lambda x: (x.start_datetime, x.recurrence_end_date or datetime.date(9999,12,31)))
652

    
653
    def filter_queryset(self, form, qs):
654
        if self.worker is not None:
655
            qs = qs.filter(participants=self.worker)
656
        start_date = datetime.date.today()
657
        end_date = start_date+datetime.timedelta(days=90)
658
        if form.is_valid():
659
            if form.cleaned_data.get('start_date'):
660
                start_date = form.cleaned_data['start_date']
661
            if form.cleaned_data.get('end_date'):
662
                end_date = form.cleaned_data['end_date']
663
            else:
664
                end_date = start_date+datetime.timedelta(days=90)
665
            if len(form.cleaned_data.get('event_type')) != 2:
666
                if '0' in form.cleaned_data.get('event_type'):
667
                    qs = qs.filter(event_type_id=1)
668
                else:
669
                    qs = qs.exclude(event_type_id=1)
670
            if form.cleaned_data.get('no_end_date'):
671
                qs = qs.filter(recurrence_end_date__isnull=True)
672
        qs = qs.filter(services=self.service)
673
        qs = qs.filter(recurrence_periodicity__isnull=False)
674
        qs = qs.filter(start_datetime__lt=end_date)
675
        qs = qs.filter(Q(recurrence_end_date__isnull=True)
676
                | Q(recurrence_end_date__gte=start_date))
677
        qs = qs.order_by('start_datetime', 'recurrence_end_date')
678
        qs = qs.select_related()
679
        qs = qs.prefetch_related('participants', 'services')
680
        return qs
681

    
682
    def get_context_data(self, **kwargs):
683
        ctx = super(PeriodicEventsView, self).get_context_data(**kwargs)
684
        ctx['search_form'] = self.form
685
        ctx['worker'] = self.worker
686
        return ctx
(10-10/10)