Project

General

Profile

Download (31.6 KB) Statistics
| Branch: | Tag: | Revision:
0d46dc26 Mikaël Ates
# -*- coding: utf-8 -*-

22dfa9ef Benjamin Dauvergne
import datetime
67351017 Jérôme Schneider
import logging
e46a1c3f Benjamin Dauvergne
from itertools import chain
42670aa4 Jérôme Schneider
1e03331f Jérôme Schneider
from django.contrib import messages
2ff5e689 Jérôme Schneider
from django.db.models import Q
37674910 Benjamin Dauvergne
from django.shortcuts import redirect, get_object_or_404
1f9e881e Benjamin Dauvergne
from django.http import HttpResponseRedirect, HttpResponse
fe04204b Mikaël Ates
from django.conf import settings
61d218b9 Jérôme Schneider
b0e22743 Jérôme Schneider
from calebasse.cbv import TemplateView, CreateView, UpdateView
76974b6f Benjamin Dauvergne
from calebasse.agenda.models import Event, EventType, EventWithAct
1eab6c73 Frédéric Péters
from calebasse.personnes.models import TimeTable, Holiday
197e410c Frédéric Péters
from calebasse.agenda.appointments import get_daily_appointments, get_daily_usage
e3c5afd2 Jérôme Schneider
from calebasse.personnes.models import Worker
dd986559 Serghei MIHAI
from calebasse.ressources.models import WorkerType, Ressource
76974b6f Benjamin Dauvergne
from calebasse.actes.validation import (get_acts_of_the_day,
get_days_with_acts_not_locked)
0839ccbe Benjamin Dauvergne
from calebasse.actes.validation_states import VALIDATION_STATES
0d46dc26 Mikaël Ates
from calebasse.actes.models import Act, ValidationMessage
76974b6f Benjamin Dauvergne
from calebasse.actes.validation import (automated_validation, unlock_all_acts_of_the_day)
5e21bdcd Benjamin Dauvergne
from calebasse import cbv
0db45b73 Benjamin Dauvergne
5feec0ab Jérôme Schneider
from calebasse.agenda.forms import (NewAppointmentForm, NewEventForm, UpdatePeriodicAppointmentForm,
9ca08421 Jérôme Schneider
DisablePatientAppointmentForm, UpdateAppointmentForm, UpdatePeriodicEventForm,
7af04d52 Jérôme Schneider
UpdateEventForm, PeriodicEventsSearchForm)
0a82dcb8 Benjamin Dauvergne
67351017 Jérôme Schneider
logger = logging.getLogger(__name__)

22dfa9ef Benjamin Dauvergne
def redirect_today(request, service):
'''If not date is given we redirect on the agenda for today'''
return redirect('agenda', date=datetime.date.today().strftime('%Y-%m-%d'),
service=service)
0db45b73 Benjamin Dauvergne
0f0cacbb Jérôme Schneider
3e9b47e9 Benjamin Dauvergne
class AgendaHomepageView(TemplateView):
0db45b73 Benjamin Dauvergne
template_name = 'agenda/index.html'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
0db45b73 Benjamin Dauvergne
2f8649fe Mikaël Ates
def post(self, request, *args, **kwargs):
433b67bb Benjamin Dauvergne
acte_id = request.POST.get('event-id')
2f8649fe Mikaël Ates
try:
433b67bb Benjamin Dauvergne
event = EventWithAct.objects.get(id=acte_id)
event = event.today_occurrence(self.date)
act = event.act
2f8649fe Mikaël Ates
if not act.validation_locked:
state_name = request.POST.get('act_state')
433b67bb Benjamin Dauvergne
act.save()
2f8649fe Mikaël Ates
act.set_state(state_name, request.user)
except Act.DoesNotExist:
5feec0ab Jérôme Schneider
logger.warning('agenda homepage acte_id %d not found' % acte_id)
2f8649fe Mikaël Ates
return HttpResponseRedirect('#acte-frame-'+acte_id)

0db45b73 Benjamin Dauvergne
def get_context_data(self, **kwargs):
67351017 Jérôme Schneider
logger.info('AgendaHomepageView.get_context_data called')
0db45b73 Benjamin Dauvergne
context = super(AgendaHomepageView, self).get_context_data(**kwargs)
2ff5e689 Jérôme Schneider
0f0cacbb Jérôme Schneider
context['workers_types'] = []
e379734d Benjamin Dauvergne
workers = Worker.objects.filter(enabled=True).select_related() \
.prefetch_related('services')
dbb64d4f Benjamin Dauvergne
worker_by_type = {}
for worker in workers:
workers_for_type = worker_by_type.setdefault(worker.type, [])
workers_for_type.append(worker)
for worker_type, workers_for_type in worker_by_type.iteritems():
context['workers_types'].append(
{'type': worker_type.name, 'workers': workers_for_type })
b306fcbb Frédéric Péters
context['workers'] = workers
context['disponibility_start_times'] = range(8, 20)
d051df53 Frédéric Péters
5acde67b Serghei MIHAI
# ressources
context['ressources_types'] = []
dd986559 Serghei MIHAI
data = {'type': Ressource._meta.verbose_name_plural,
'ressources': Ressource.objects.all()}
5acde67b Serghei MIHAI
context['ressources_types'].append(data)
0a82dcb8 Benjamin Dauvergne
5acde67b Serghei MIHAI
return context
ad9330e1 Jérôme Schneider
1df3d699 Serghei MIHAI
class AgendaServiceActivityView(TemplateView, cbv.ServiceViewMixin):
ad9330e1 Jérôme Schneider
template_name = 'agenda/service-activity.html'
2136241a Serghei MIHAI
cookies_to_clear = [('agenda-tabs', ), ('active-agenda', ), ('last-ressource', )]
ad9330e1 Jérôme Schneider
def get_context_data(self, **kwargs):
context = super(AgendaServiceActivityView, self).get_context_data(**kwargs)

appointments_times = dict()
e379734d Benjamin Dauvergne
events = Event.objects.for_today(self.date) \
.exclude(event_type_id=1) \
1fdaaa35 Benjamin Dauvergne
.filter(services=self.service) \
e709c53e Jérôme Schneider
.order_by('start_datetime', 'id') \
e379734d Benjamin Dauvergne
.select_related() \
.prefetch_related('participants', 'exceptions')
eventswithact = EventWithAct.objects.for_today(self.date) \
.filter(services=self.service) \
e709c53e Jérôme Schneider
.order_by('start_datetime', 'id') \
e379734d Benjamin Dauvergne
.select_related() \
.prefetch_related('participants', 'exceptions')
events = [ e.today_occurrence(self.date) for e in events ] \
+ [ e.today_occurrence(self.date) for e in eventswithact ]
76974b6f Benjamin Dauvergne
for event in events:
start_datetime = event.start_datetime.strftime("%H:%M")
if not appointments_times.has_key(start_datetime):
appointments_times[start_datetime] = dict()
appointments_times[start_datetime]['row'] = 0
appointments_times[start_datetime]['appointments'] = []
ad9330e1 Jérôme Schneider
appointment = dict()
76974b6f Benjamin Dauvergne
length = event.end_datetime - event.start_datetime
ad9330e1 Jérôme Schneider
if length.seconds:
length = length.seconds / 60
appointment['length'] = "%sm" % length
1fdaaa35 Benjamin Dauvergne
if event.event_type_id == 1:
477e1b65 Frédéric Péters
appointment['type'] = 1
1fdaaa35 Benjamin Dauvergne
appointment['label'] = event.patient.display_name
15a79142 Mikaël Ates
appointment['paper_id'] = event.patient.paper_id
1fdaaa35 Benjamin Dauvergne
appointment['act'] = event.act_type.name
7db9b9ef Jérôme Schneider
appointment['state'] = event.act.get_state()
55441838 Mikaël Ates
appointment['absent'] = event.act.is_absent()
1fdaaa35 Benjamin Dauvergne
else:
477e1b65 Frédéric Péters
appointment['type'] = 2
58c43bdb Benjamin Dauvergne
if event.event_type.label == 'Autre' and event.title:
appointment['label'] = event.title
else:
appointment['label'] = '%s - %s' % (event.event_type.label,
event.title)
e0fa659d Jérôme Schneider
appointment['participants'] = event.participants.filter(worker__enabled=True)
15a79142 Mikaël Ates
appointment['len_participants'] = len(appointment['participants'])
e6b125bd Mikaël Ates
appointment['workers_absent'] = event.get_missing_participants()
76974b6f Benjamin Dauvergne
appointments_times[start_datetime]['row'] += 1
appointments_times[start_datetime]['appointments'].append(appointment)
d86f6cd6 Jérôme Schneider
context['appointments_times'] = sorted(appointments_times.items())
ad9330e1 Jérôme Schneider
return context


5e21bdcd Benjamin Dauvergne
class NewAppointmentView(cbv.ReturnToObjectMixin, cbv.ServiceFormMixin, CreateView):
76974b6f Benjamin Dauvergne
model = EventWithAct
e92e5a1b Benjamin Dauvergne
form_class = NewAppointmentForm
3e9b47e9 Benjamin Dauvergne
template_name = 'agenda/new-appointment.html'
f2ac4430 Jérôme Schneider
success_msg = u'Rendez-vous enregistré avec succès.'
d5d27a07 Serghei MIHAI
cookies_to_clear = []
e92e5a1b Benjamin Dauvergne
7f9269be Benjamin Dauvergne
def get_initial(self):
initial = super(NewAppointmentView, self).get_initial()
5e9463c5 Benjamin Dauvergne
initial['start_datetime'] = self.date
541c2278 Benjamin Dauvergne
initial['date'] = self.date
7f9269be Benjamin Dauvergne
initial['participants'] = self.request.GET.getlist('participants')
initial['time'] = self.request.GET.get('time')
dd986559 Serghei MIHAI
initial['ressource'] = self.request.GET.get('ressource')
ad2b7483 Serghei MIHAI
initial['duration'] = self.request.GET.get('duration')
7f9269be Benjamin Dauvergne
return initial

0779c576 Benjamin Dauvergne
def get_form_kwargs(self):
kwargs = super(NewAppointmentView, self).get_form_kwargs()
kwargs['service'] = self.service
return kwargs
e92e5a1b Benjamin Dauvergne
71e21299 Serghei MIHAI
def get_success_url(self):
return self.request.META.get('HTTP_REFERER', '..')

1e03331f Jérôme Schneider
def form_valid(self, form):
f2ac4430 Jérôme Schneider
messages.add_message(self.request, messages.INFO, self.success_msg)
1e03331f Jérôme Schneider
return super(NewAppointmentView, self).form_valid(form)

3e9b47e9 Benjamin Dauvergne
ade323e2 Benjamin Dauvergne
class TodayOccurrenceMixin(object):
def get_object(self, queryset=None):
o = super(TodayOccurrenceMixin, self).get_object(queryset)
return o.today_occurrence(self.date)

3e9b47e9 Benjamin Dauvergne
class BaseAppointmentView(UpdateView):
76974b6f Benjamin Dauvergne
model = EventWithAct
266e951c Jérôme Schneider
form_class = UpdateAppointmentForm
9c1d4044 Jérôme Schneider
template_name = 'agenda/update-rdv.html'
b0e22743 Jérôme Schneider
success_url = '..'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
b0e22743 Jérôme Schneider
def get_initial(self):
3e9b47e9 Benjamin Dauvergne
initial = super(BaseAppointmentView, self).get_initial()
5e9463c5 Benjamin Dauvergne
initial['start_datetime'] = self.date
91e89dfb Benjamin Dauvergne
initial['date'] = self.object.start_datetime.date()
initial['time'] = self.object.start_datetime.time()
76974b6f Benjamin Dauvergne
time = self.object.end_datetime - self.object.start_datetime
b0e22743 Jérôme Schneider
if time:
time = time.seconds / 60
else:
time = 0
initial['duration'] = time
initial['participants'] = self.object.participants.values_list('id', flat=True)
return initial

266e951c Jérôme Schneider
def get_form_kwargs(self):
3e9b47e9 Benjamin Dauvergne
kwargs = super(BaseAppointmentView, self).get_form_kwargs()
b9bad0d6 Frédéric Péters
kwargs['service'] = self.service
266e951c Jérôme Schneider
return kwargs
b0e22743 Jérôme Schneider

3e9b47e9 Benjamin Dauvergne
class UpdateAppointmentView(TodayOccurrenceMixin, BaseAppointmentView):
c082b14e Jérôme Schneider
def get_form_class(self):
if self.object.exception_to and not self.object.exception_to.canceled:
7af04d52 Jérôme Schneider
return DisablePatientAppointmentForm
c082b14e Jérôme Schneider
else:
return self.form_class
3e9b47e9 Benjamin Dauvergne

class UpdatePeriodicAppointmentView(BaseAppointmentView):
7af04d52 Jérôme Schneider
form_class = UpdatePeriodicAppointmentForm
3e9b47e9 Benjamin Dauvergne
template_name = 'agenda/new-appointment.html'

7af04d52 Jérôme Schneider
67707adb Jérôme Schneider
class NewEventView(CreateView):
model = Event
form_class = NewEventForm
template_name = 'agenda/new-event.html'
d5d27a07 Serghei MIHAI
cookies_to_clear = []
67707adb Jérôme Schneider
def get_initial(self):
initial = super(NewEventView, self).get_initial()
5e9463c5 Benjamin Dauvergne
initial['start_datetime'] = self.date
541c2278 Benjamin Dauvergne
initial['date'] = self.date
67707adb Jérôme Schneider
initial['participants'] = self.request.GET.getlist('participants')
initial['time'] = self.request.GET.get('time')
c8d74e1a Jérôme Schneider
initial['event_type'] = 2
dd986559 Serghei MIHAI
initial['ressource'] = self.request.GET.get('ressource')
ad2b7483 Serghei MIHAI
initial['duration'] = self.request.GET.get('duration')
7dae6e42 Jérôme Schneider
if not initial.has_key('services'):
initial['services'] = [self.service]
67707adb Jérôme Schneider
return initial

0779c576 Benjamin Dauvergne
def get_form_kwargs(self):
kwargs = super(NewEventView, self).get_form_kwargs()
kwargs['service'] = self.service
return kwargs

71e21299 Serghei MIHAI
def get_success_url(self):
return self.request.META.get('HTTP_REFERER', '..')

1e03331f Jérôme Schneider
def form_valid(self, form):
messages.add_message(self.request, messages.INFO, u'Evénement enregistré avec succès.')
return super(NewEventView, self).form_valid(form)

76974b6f Benjamin Dauvergne
3e9b47e9 Benjamin Dauvergne
class BaseEventView(UpdateView):
9c1d4044 Jérôme Schneider
model = Event
2ae5dd3d Benjamin Dauvergne
form_class = UpdateEventForm
9c1d4044 Jérôme Schneider
template_name = 'agenda/update-event.html'
success_url = '..'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
9c1d4044 Jérôme Schneider
def get_initial(self):
3e9b47e9 Benjamin Dauvergne
initial = super(BaseEventView, self).get_initial()
5e9463c5 Benjamin Dauvergne
initial['start_datetime'] = self.date
91e89dfb Benjamin Dauvergne
initial['date'] = self.object.start_datetime.date()
initial['time'] = self.object.start_datetime.time()
76974b6f Benjamin Dauvergne
time = self.object.end_datetime - self.object.start_datetime
9c1d4044 Jérôme Schneider
if time:
time = time.seconds / 60
else:
time = 0
initial['duration'] = time
initial['participants'] = self.object.participants.values_list('id', flat=True)
return initial

0779c576 Benjamin Dauvergne
def get_form_kwargs(self):
3e9b47e9 Benjamin Dauvergne
kwargs = super(BaseEventView, self).get_form_kwargs()
0779c576 Benjamin Dauvergne
kwargs['service'] = self.service
return kwargs

3e9b47e9 Benjamin Dauvergne
class UpdateEventView(TodayOccurrenceMixin, BaseEventView):
pass


class UpdatePeriodicEventView(BaseEventView):
9ca08421 Jérôme Schneider
form_class = UpdatePeriodicEventForm
3e9b47e9 Benjamin Dauvergne
template_name = 'agenda/new-event.html'

6738ceb2 Jérôme Schneider
def delete_eventwithact(event):
assert event.event_type == 1
if event.act.id \
and not event.act.is_billed:
event.act.delete()
if not event.act.id or \
not event.act.is_billed:
event.delete()
3e9b47e9 Benjamin Dauvergne
e242e850 Benjamin Dauvergne
class DeleteOccurrenceView(TodayOccurrenceMixin, cbv.DeleteView):
1f9e881e Benjamin Dauvergne
model = Event
success_url = '..'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
1f9e881e Benjamin Dauvergne
def delete(self, request, *args, **kwargs):
17861d43 Jérôme Schneider
self.object = self.get_object()
6738ceb2 Jérôme Schneider
if self.object.event_type == 1:
delete_eventwithact(self.object)
else:
self.object.delete()
17861d43 Jérôme Schneider
1f9e881e Benjamin Dauvergne
return HttpResponse(status=204)
2ff5e689 Jérôme Schneider
e242e850 Benjamin Dauvergne
class DeleteEventView(cbv.DeleteView):
model = Event
success_url = '..'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
e242e850 Benjamin Dauvergne
def delete(self, request, *args, **kwargs):
6738ceb2 Jérôme Schneider
self.object = self.get_object()
# If exceptions remove them only if act is not billed
for exception in self.object.exceptions.all():
exception.recurrence_periodicity = None
exception.exception_to = None
exception.save()
if exception.event_type == 1:
delete_eventwithact(exception)
else:
exception.delete()

if self.object.event_type == 1:
delete_eventwithact(self.object)
else:
self.object.delete()
e242e850 Benjamin Dauvergne
return HttpResponse(status=204)
3e9b47e9 Benjamin Dauvergne
6552e0b4 Mikaël Ates
class AgendaServiceActValidationView(TemplateView):
template_name = 'agenda/act-validation.html'
2136241a Serghei MIHAI
cookies_to_clear = [('agenda-tabs', ), ('active-agenda', ), ('last-ressource', )]
6552e0b4 Mikaël Ates
86dfa623 Benjamin Dauvergne
def acts_of_the_day(self):
77922967 Benjamin Dauvergne
acts = list(Act.objects \
5b0ffff2 Mikaël Ates
.filter(date=self.date, patient__service=self.service) \
77922967 Benjamin Dauvergne
.select_related() \
5b0ffff2 Mikaël Ates
.prefetch_related('doctors',
77922967 Benjamin Dauvergne
'patient__patientcontact',
'actvalidationstate_set__previous_state') \
.order_by('time'))
event_ids = [ a.parent_event_id for a in acts if a.parent_event_id ]
events = EventWithAct.objects.for_today(self.date) \
5b0ffff2 Mikaël Ates
.filter(patient__service=self.service) \
77922967 Benjamin Dauvergne
.exclude(id__in=event_ids)
events = [ event.today_occurrence(self.date) for event in events ]
acts += [ event.act for event in events if event ]
return sorted(acts, key=lambda a: (a.time or datetime.time.min, a.id))
86dfa623 Benjamin Dauvergne
6552e0b4 Mikaël Ates
def post(self, request, *args, **kwargs):
9d75fa2a Benjamin Dauvergne
if 'unlock-all' in request.POST:
1db69825 Mikaël Ates
#TODO: check that the user is authorized
0853d495 Mikaël Ates
unlock_all_acts_of_the_day(self.date, self.service)
0d46dc26 Mikaël Ates
ValidationMessage(validation_date=self.date,
who=request.user, what='Déverrouillage',
service=self.service).save()
86dfa623 Benjamin Dauvergne
else:
acte_id = request.POST.get('acte-id')
try:
act = Act.objects.get(id=acte_id)
if 'lock' in request.POST or 'unlock' in request.POST:
1db69825 Mikaël Ates
#TODO: check that the user is authorized
86dfa623 Benjamin Dauvergne
act.validation_locked = 'lock' in request.POST
act.save()
else:
state_name = request.POST.get('act_state')
act.set_state(state_name, request.user)
except Act.DoesNotExist:
pass
return HttpResponseRedirect('#acte-frame-'+acte_id)
return HttpResponseRedirect('')
6552e0b4 Mikaël Ates
def get_context_data(self, **kwargs):
context = super(AgendaServiceActValidationView, self).get_context_data(**kwargs)
authorized_lock = True # is_authorized_for_locking(get_request().user)
0d46dc26 Mikaël Ates
validation_msg = ValidationMessage.objects.\
filter(validation_date=self.date, service=self.service).\
order_by('-when')[:3]
86dfa623 Benjamin Dauvergne
acts_of_the_day = self.acts_of_the_day()
6552e0b4 Mikaël Ates
actes = list()
for act in acts_of_the_day:
433b67bb Benjamin Dauvergne
if not act.id:
ab849694 Benjamin Dauvergne
if act.date < datetime.date(2013, 1, 1):
continue
else:
act.save()
6552e0b4 Mikaël Ates
state = act.get_state()
a157a35c Mikaël Ates
display_name = None
if state :
display_name = VALIDATION_STATES[state.state_name]
77922967 Benjamin Dauvergne
if not state.previous_state_id and state.state_name == 'NON_VALIDE':
a157a35c Mikaël Ates
state = None
1db69825 Mikaël Ates
actes.append((act, state, display_name))
cdf3d9de Mikaël Ates
validation_states = dict(VALIDATION_STATES)
e36e0819 Mikaël Ates
if self.service.name != 'CMPP' and \
cdf3d9de Mikaël Ates
'ACT_DOUBLE' in validation_states:
validation_states.pop('ACT_DOUBLE')
vs = [('VALIDE', 'Présent')]
validation_states.pop('VALIDE')
a50df9c4 Mikaël Ates
validation_states.pop('ACT_LOST')
cdf3d9de Mikaël Ates
validation_states = vs + sorted(validation_states.items(), key=lambda tup: tup[0])
context['validation_states'] = validation_states
6552e0b4 Mikaël Ates
context['actes'] = actes
context['validation_msg'] = validation_msg
context['authorized_lock'] = authorized_lock
return context


9d75fa2a Benjamin Dauvergne
class AutomatedValidationView(TemplateView):
template_name = 'agenda/automated-validation.html'

def post(self, request, *args, **kwargs):
automated_validation(self.date, self.service,
request.user)
0d46dc26 Mikaël Ates
ValidationMessage(validation_date=self.date,
who=request.user, what='Validation automatique',
service=self.service).save()
9d75fa2a Benjamin Dauvergne
return HttpResponseRedirect('..')

def get_context_data(self, **kwargs):
context = super(AutomatedValidationView, self).get_context_data(**kwargs)
request = self.request
(nb_acts_total, nb_acts_validated, nb_acts_double,
08bf3477 Mikaël Ates
nb_acts_abs_non_exc, nb_acts_abs_exc, nb_acts_abs_inter, nb_acts_annul_nous,
nb_acts_annul_famille, nb_acts_reporte, nb_acts_abs_ess_pps,
nb_acts_enf_hosp, nb_acts_losts) = \
9d75fa2a Benjamin Dauvergne
automated_validation(self.date, self.service,
request.user, commit = False)

9c8dd34b Mikaël Ates
nb_acts_not_validated = nb_acts_double + \
nb_acts_abs_non_exc + \
nb_acts_abs_exc + \
08bf3477 Mikaël Ates
nb_acts_abs_inter + \
9c8dd34b Mikaël Ates
nb_acts_annul_nous + \
nb_acts_annul_famille + \
6c9a3a0d Mikaël Ates
nb_acts_reporte + \
9c8dd34b Mikaël Ates
nb_acts_abs_ess_pps + \
08bf3477 Mikaël Ates
nb_acts_enf_hosp + \
nb_acts_losts
9d75fa2a Benjamin Dauvergne
context.update({
'nb_acts_total': nb_acts_total,
'nb_acts_validated': nb_acts_validated,
9c8dd34b Mikaël Ates
'nb_acts_not_validated': nb_acts_not_validated,
9d75fa2a Benjamin Dauvergne
'nb_acts_double': nb_acts_double,
'nb_acts_abs_non_exc': nb_acts_abs_non_exc,
9c8dd34b Mikaël Ates
'nb_acts_abs_exc': nb_acts_abs_exc,
08bf3477 Mikaël Ates
'nb_acts_abs_inter': nb_acts_abs_inter,
9d75fa2a Benjamin Dauvergne
'nb_acts_annul_nous': nb_acts_annul_nous,
9c8dd34b Mikaël Ates
'nb_acts_annul_famille': nb_acts_annul_famille,
6c9a3a0d Mikaël Ates
'nb_acts_reporte': nb_acts_reporte,
9d75fa2a Benjamin Dauvergne
'nb_acts_abs_ess_pps': nb_acts_abs_ess_pps,
08bf3477 Mikaël Ates
'nb_acts_enf_hosp': nb_acts_enf_hosp,
'nb_acts_losts': nb_acts_losts})
9d75fa2a Benjamin Dauvergne
return context
6552e0b4 Mikaël Ates
class UnlockAllView(CreateView):
pass
4aa8bb1d Jérôme Schneider
ec83d7ba Frédéric Péters
class AgendasTherapeutesView(AgendaHomepageView):
template_name = 'agenda/agendas-therapeutes.html'
2136241a Serghei MIHAI
cookies_to_clear = [('agenda-tabs', ), ('active-agenda', ), ('last-ressource', )]
ec83d7ba Frédéric Péters
def get_context_data(self, **kwargs):
context = super(AgendasTherapeutesView, self).get_context_data(**kwargs)
d051df53 Frédéric Péters
time_tables = TimeTable.objects.select_related('worker'). \
filter(services=self.service). \
for_today(self.date). \
order_by('start_date')
e379734d Benjamin Dauvergne
holidays = Holiday.objects.select_related('worker') \
.for_period(self.date, self.date) \
.order_by('start_date') \
.select_related()
events = Event.objects.for_today(self.date) \
.exclude(event_type_id=1) \
.filter(services=self.service) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related('services',
'exceptions',
'participants')
eventswithact = EventWithAct.objects.for_today(self.date) \
.filter(services=self.service) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related(
'services',
'patient__service',
55441838 Mikaël Ates
'act_set__actvalidationstate_set',
e379734d Benjamin Dauvergne
'exceptions', 'participants')
events = [ e.today_occurrence(self.date) for e in events ] \
+ [ e.today_occurrence(self.date) for e in eventswithact ]
for e in events:
e.workers_ids = set(p.id for p in e.participants.all())
d051df53 Frédéric Péters
76974b6f Benjamin Dauvergne
events_workers = {}
2c80c165 Frédéric Péters
time_tables_workers = {}
holidays_workers = {}
context['workers_agenda'] = []
82b34e25 Benjamin Dauvergne
context['workers'] = context['workers'].filter(services=self.service)
2c80c165 Frédéric Péters
for worker in context['workers']:
time_tables_worker = [tt for tt in time_tables if tt.worker.id == worker.id]
e379734d Benjamin Dauvergne
events_worker = [o for o in events if worker.id in o.workers_ids ]
2c80c165 Frédéric Péters
holidays_worker = [h for h in holidays if h.worker_id in (None, worker.id)]
76974b6f Benjamin Dauvergne
events_workers[worker.id] = events_worker
2c80c165 Frédéric Péters
time_tables_workers[worker.id] = time_tables_worker
holidays_workers[worker.id] = holidays_worker
e379734d Benjamin Dauvergne
daily_appointments = get_daily_appointments(context['date'], worker, self.service,
time_tables_worker, events_worker, holidays_worker)
db33aecd Benjamin Dauvergne
if all(map(lambda x: x.holiday, daily_appointments)):
e379734d Benjamin Dauvergne
continue
2c80c165 Frédéric Péters
context['workers_agenda'].append({'worker': worker,
e379734d Benjamin Dauvergne
'appointments': daily_appointments})
2c80c165 Frédéric Péters
ec83d7ba Frédéric Péters
for worker_agenda in context.get('workers_agenda', []):
patient_appointments = [x for x in worker_agenda['appointments'] if x.patient_record_id]
worker_agenda['summary'] = {
'rdv': len(patient_appointments),
'presence': len([x for x in patient_appointments if x.act_absence is None]),
'absence': len([x for x in patient_appointments if x.act_absence is not None]),
'doubles': len([x for x in patient_appointments if x.act_type == 'ACT_DOUBLE']),
'valides': len([x for x in patient_appointments if x.act_type == 'ACT_VALIDE']),
}

return context

ba9e01fa Mikaël Ates
class JoursNonVerrouillesView(TemplateView):
fcfb4f5b Mikaël Ates
template_name = 'agenda/days-not-locked.html'

def get_context_data(self, **kwargs):
ba9e01fa Mikaël Ates
context = super(JoursNonVerrouillesView, self).get_context_data(**kwargs)
76974b6f Benjamin Dauvergne
acts = Act.objects.filter(is_billed=False,
fcfb4f5b Mikaël Ates
patient__service=self.service).order_by('date')
76974b6f Benjamin Dauvergne
days = set(acts.values_list('date', flat=True))
2e8e4ab0 Mikaël Ates
if days:
max_day, min_day = max(days), min(days)
006e8d36 Mikaël Ates
today = datetime.datetime.today().date()
if max_day > today:
max_day = today
2e8e4ab0 Mikaël Ates
days &= set(get_days_with_acts_not_locked(min_day, max_day, self.service))
d0b8cfab Mikaël Ates
context['days_not_locked'] = sorted(days)
fcfb4f5b Mikaël Ates
return context
197e410c Frédéric Péters
b306fcbb Frédéric Péters
class AjaxWorkerTabView(TemplateView):

template_name = 'agenda/ajax-worker-tab.html'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
b306fcbb Frédéric Péters
def get_context_data(self, worker_id, **kwargs):
context = super(AjaxWorkerTabView, self).get_context_data(**kwargs)
e379734d Benjamin Dauvergne
worker = Worker.objects.get(id=worker_id)
b306fcbb Frédéric Péters
time_tables_worker = TimeTable.objects.select_related('worker'). \
e379734d Benjamin Dauvergne
filter(services=self.service, worker=worker) \
.for_today(self.date) \
.order_by('start_date') \
.select_related()
holidays_worker = Holiday.objects.for_worker(worker) \
.for_period(self.date, self.date) \
.order_by('start_date') \
.select_related()
events = Event.objects.for_today(self.date) \
.exclude(event_type_id=1) \
.filter(participants=worker) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related('services',
'exceptions',
'participants')
eventswithact = EventWithAct.objects.for_today(self.date) \
.filter(participants=worker) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related('patient__addresses',
'patient__addresses__patientcontact_set',
'services',
'patient__service',
55441838 Mikaël Ates
'act_set__actvalidationstate_set',
e379734d Benjamin Dauvergne
'exceptions', 'participants')
events = [ e.today_occurrence(self.date) for e in events ] \
+ [ e.today_occurrence(self.date) for e in eventswithact ]
b306fcbb Frédéric Péters
context['worker_agenda'] = {'worker': worker,
'appointments': get_daily_appointments(context['date'], worker, self.service,
e379734d Benjamin Dauvergne
time_tables_worker, events, holidays_worker)}
e6b125bd Mikaël Ates
fe04204b Mikaël Ates
if settings.RTF_TEMPLATES_DIRECTORY:
context['mail'] = True
b306fcbb Frédéric Péters
return context

5acde67b Serghei MIHAI
class AjaxRessourceTabView(TemplateView):
template_name = 'agenda/ajax-ressource-tab.html'
cookies_to_clear = []

def get_context_data(self, ressource_id, **kwargs):
context = super(AjaxRessourceTabView, self).get_context_data(**kwargs)
dd986559 Serghei MIHAI
ressource = Ressource.objects.get(pk=ressource_id)
5acde67b Serghei MIHAI
plain_events = Event.objects.for_today(self.date) \
.order_by('start_datetime').select_subclasses()
events = [ e.today_occurrence(self.date) for e in plain_events ]
dd986559 Serghei MIHAI
events_ressource = [e for e in events if ressource == e.ressource]
5acde67b Serghei MIHAI
context['ressource_agenda'] = {'appointments': get_daily_usage(context['date'],
ressource,
self.service,
events_ressource)
}
return context

3a38fa86 Serghei MIHAI
class AjaxDisponibilityColumnView(TemplateView):
b306fcbb Frédéric Péters
3a38fa86 Serghei MIHAI
template_name = 'agenda/ajax-disponibility-column.html'
206fe640 Benjamin Dauvergne
cookies_to_clear = []
b306fcbb Frédéric Péters
3a38fa86 Serghei MIHAI
def get_ressource_context_data(self, ressource_id, context):
dd986559 Serghei MIHAI
ressource = Ressource.objects.get(pk = ressource_id)
3a38fa86 Serghei MIHAI
context['initials'] = ressource.name[:3]
disponibility = dict()
start_datetime = datetime.datetime(self.date.year,
self.date.month,
self.date.day, 8, 0)
end_datetime = datetime.datetime(self.date.year, self.date.month,
self.date.day, 8, 15)
dd986559 Serghei MIHAI
events = Event.objects.filter(ressource__id=ressource_id).today_occurrences(self.date)
3a38fa86 Serghei MIHAI
while (start_datetime.hour <= 19):
if start_datetime.hour not in disponibility:
disponibility[start_datetime.hour] = [[], [], [], []]
quarter = 0
dispo = 'free'
mins = quarter * 15

if events:
event = events[0]

if event.start_datetime <= start_datetime and event.end_datetime >= end_datetime:
dispo = 'busy'
disponibility[start_datetime.hour][quarter].append((mins, {'id': ressource_id, 'dispo': dispo}))
quarter += 1
start_datetime += datetime.timedelta(minutes=15)
end_datetime += datetime.timedelta(minutes=15)
context['disponibility'] = disponibility
return context


def get_worker_context_data(self, worker_id, context):
e379734d Benjamin Dauvergne
worker = Worker.objects.get(pk=worker_id)
b306fcbb Frédéric Péters
time_tables_worker = TimeTable.objects.select_related('worker'). \
e379734d Benjamin Dauvergne
filter(services=self.service, worker=worker). \
b306fcbb Frédéric Péters
for_today(self.date). \
order_by('start_date')
e379734d Benjamin Dauvergne
holidays_worker = Holiday.objects.for_worker(worker). \
b306fcbb Frédéric Péters
for_period(self.date, self.date). \
order_by('start_date')
e379734d Benjamin Dauvergne
events = Event.objects.for_today(self.date) \
.exclude(event_type_id=1) \
.filter(participants=worker) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related('participants', 'exceptions')
eventswithact = EventWithAct.objects.for_today(self.date) \
.filter(participants=worker) \
.order_by('start_datetime') \
.select_related() \
.prefetch_related('participants', 'exceptions',
'act_set__actvalidationstate_set')

events = list(events) + list(eventswithact)
events = [ e.today_occurrence(self.date) for e in events ]
b306fcbb Frédéric Péters
time_tables_workers = {worker.id: time_tables_worker}
e379734d Benjamin Dauvergne
events_workers = {worker.id: events}
b306fcbb Frédéric Péters
holidays_workers = {worker.id: holidays_worker}

97bee351 Jérôme Schneider
context['initials'] = worker.initials
76974b6f Benjamin Dauvergne
context['disponibility'] = Event.objects.daily_disponibilities(self.date,
events_workers, [worker], time_tables_workers, holidays_workers)
b306fcbb Frédéric Péters
return context
e46a1c3f Benjamin Dauvergne
3a38fa86 Serghei MIHAI
def get_context_data(self, ressource_type, ressource_id, **kwargs):
context = super(AjaxDisponibilityColumnView, self).get_context_data(**kwargs)
if ressource_type in ('worker', 'ressource',):
context['ressource_type'] = ressource_type
context['ressource_id'] = ressource_id
getattr(self, 'get_%s_context_data' % ressource_type)(ressource_id, context)
7ee2f91a Serghei MIHAI
return context

e46a1c3f Benjamin Dauvergne
class PeriodicEventsView(cbv.ListView):
model = EventWithAct
template_name = 'agenda/periodic-events.html'
2136241a Serghei MIHAI
cookies_to_clear = [('agenda-tabs', ), ('active-agenda', ), ('last-ressource', )]
e46a1c3f Benjamin Dauvergne
37674910 Benjamin Dauvergne
def dispatch(self, request, *args, **kwargs):
if 'worker_id' in kwargs:
self.worker = get_object_or_404(Worker, id=kwargs['worker_id'])
else:
self.worker = None
return super(PeriodicEventsView, self).dispatch(request, *args, **kwargs)

e46a1c3f Benjamin Dauvergne
def get_form(self):
kwargs = {
'initial': {
'start_date': self.date,
}
}
if self.request.GET:
kwargs['data'] = self.request.GET
8e9ed408 Benjamin Dauvergne
self.form = PeriodicEventsSearchForm(prefix='periodic-events-search-form', **kwargs)
e46a1c3f Benjamin Dauvergne
return self.form

def get_queryset(self):
qs1 = Event.objects.exclude(event_type_id=1)
qs2 = EventWithAct.objects.all()
form = self.get_form()
ee2be5e8 Benjamin Dauvergne
if not self.request.GET:
return ()
e46a1c3f Benjamin Dauvergne
qs1 = self.filter_queryset(form, qs1)
qs2 = self.filter_queryset(form, qs2)
37674910 Benjamin Dauvergne
if form.is_valid():
patient = form.cleaned_data.get('patient')
if patient is not None:
qs1 = qs1.none()
qs2 = qs2.filter(patient=patient)
6afd600b Benjamin Dauvergne
worker = form.cleaned_data.get('worker')
if worker is not None:
qs1 = qs1.filter(participants=worker)
qs2 = qs2.filter(participants=worker)
e46a1c3f Benjamin Dauvergne
return sorted(chain(qs1, qs2),
key=lambda x: (x.start_datetime, x.recurrence_end_date or datetime.date(9999,12,31)))

def filter_queryset(self, form, qs):
37674910 Benjamin Dauvergne
if self.worker is not None:
qs = qs.filter(participants=self.worker)
e46a1c3f Benjamin Dauvergne
start_date = datetime.date.today()
end_date = start_date+datetime.timedelta(days=90)
if form.is_valid():
if form.cleaned_data.get('start_date'):
start_date = form.cleaned_data['start_date']
if form.cleaned_data.get('end_date'):
e7992f44 Benjamin Dauvergne
end_date = form.cleaned_data['end_date']
e46a1c3f Benjamin Dauvergne
else:
end_date = start_date+datetime.timedelta(days=90)
37674910 Benjamin Dauvergne
if len(form.cleaned_data.get('event_type')) != 2:
if '0' in form.cleaned_data.get('event_type'):
qs = qs.filter(event_type_id=1)
else:
qs = qs.exclude(event_type_id=1)
if form.cleaned_data.get('no_end_date'):
qs = qs.filter(recurrence_end_date__isnull=True)
d8d69901 Mikaël Ates
qs = qs.filter(canceled=False)
e46a1c3f Benjamin Dauvergne
qs = qs.filter(services=self.service)
qs = qs.filter(recurrence_periodicity__isnull=False)
qs = qs.filter(start_datetime__lt=end_date)
qs = qs.filter(Q(recurrence_end_date__isnull=True)
| Q(recurrence_end_date__gte=start_date))
qs = qs.order_by('start_datetime', 'recurrence_end_date')
qs = qs.select_related()
37674910 Benjamin Dauvergne
qs = qs.prefetch_related('participants', 'services')
e46a1c3f Benjamin Dauvergne
return qs

def get_context_data(self, **kwargs):
ctx = super(PeriodicEventsView, self).get_context_data(**kwargs)
ctx['search_form'] = self.form
37674910 Benjamin Dauvergne
ctx['worker'] = self.worker
e46a1c3f Benjamin Dauvergne
return ctx