Projet

Général

Profil

Télécharger (11,8 ko) Statistiques
| Branche: | Tag: | Révision:

calebasse / calebasse / agenda / forms.py @ 8c0910ce

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

    
3
from datetime import datetime, timedelta, time
4

    
5
from django import forms
6
from django.db.models import Q
7
from django.utils.translation import ugettext_lazy as _
8

    
9
from ..dossiers.models import PatientRecord
10
from ..personnes.models import Worker
11
from ..ressources.models import ActType
12
from ..middleware.request import get_request
13

    
14
from ajax_select import make_ajax_field
15
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
16
from models import Event, EventWithAct, EventType
17

    
18
class BaseForm(forms.ModelForm):
19
    date = forms.DateField(label=u'Date', localize=True)
20
    time = forms.TimeField(label=u'Heure de début')
21
    duration = forms.CharField(label=u'Durée',
22
            help_text=u'en minutes; vous pouvez utiliser la roulette de votre souris.')
23
    participants = make_ajax_field(EventWithAct, 'participants', 'worker-or-group', True)
24

    
25

    
26
class NewAppointmentForm(BaseForm):
27
    patient = AutoCompleteSelectMultipleField('patientrecord')
28

    
29
    class Meta:
30
        model = EventWithAct
31
        fields = (
32
                'start_datetime',
33
                'date',
34
                'time',
35
                'duration',
36
                'patient',
37
                'participants',
38
                'ressource',
39
                'act_type',
40
                'description',
41
                'recurrence_periodicity',
42
                'recurrence_end_date'
43
        )
44
        widgets = {
45
                'start_datetime': forms.HiddenInput,
46
        }
47

    
48
    def __init__(self, instance, service=None, **kwargs):
49
        self.service = None
50
        super(NewAppointmentForm, self).__init__(instance=instance, **kwargs)
51
        self.fields['date'].css = 'datepicker'
52
        self.fields['participants'].required = True
53
        self.fields['time'].required = False
54
        self.fields['duration'].required = False
55
        if service:
56
            self.service = service
57
            self.special_types = [str(act.id) for act in ActType.objects.filter(Q(name__iexact='courriel')
58
                                                                                | Q(name__iexact='telephone')
59
                                                                                | Q(name__iexact='téléphone'))]
60
            self.fields['participants'].queryset = \
61
                    Worker.objects.for_service(service)
62
            self.fields['patient'].queryset = \
63
                    PatientRecord.objects.for_service(service)
64
            self.fields['act_type'].queryset = \
65
                    ActType.objects.for_service(service) \
66
                    .order_by('name')
67

    
68
    def clean_time(self):
69
        act_type = self.data.get('act_type')
70
        # act type is available as raw data from the post request
71
        if act_type in self.special_types:
72
            return time(8, 0)
73
        if self.cleaned_data['time']:
74
            return self.cleaned_data['time']
75
        raise forms.ValidationError(_(u'This field is required.'))
76

    
77
    def clean_duration(self):
78
        act_type = self.data.get('act_type')
79
        if act_type in self.special_types:
80
            return 10
81
        if self.cleaned_data['duration']:
82
            duration = self.cleaned_data['duration']
83
            try:
84
                duration = int(duration)
85
                if duration <= 0:
86
                    raise ValueError
87
                return duration
88
            except ValueError:
89
                raise forms.ValidationError(u'Le champ doit contenir uniquement des chiffres')
90
        raise forms.ValidationError(_(u'This field is required.'))
91

    
92
    def clean_patient(self):
93
        patients = self.cleaned_data['patient']
94
        if patients:
95
            return [patient for patient in PatientRecord.objects.filter(pk__in=patients)]
96

    
97
    def clean(self):
98
        cleaned_data = super(NewAppointmentForm, self).clean()
99
        if not cleaned_data.get('recurrence_periodicity'):
100
            cleaned_data['recurrence_end_date'] = None
101
        if cleaned_data.has_key('date') and cleaned_data.has_key('time'):
102
            cleaned_data['start_datetime'] = datetime.combine(cleaned_data['date'],
103
                    cleaned_data['time'])
104
        if 'patient' in cleaned_data and isinstance(cleaned_data['patient'], list):
105
            # nasty trick to store the list of patients and pass the form
106
            # validation
107
            cleaned_data['patients'] = cleaned_data['patient']
108
            cleaned_data['patient'] = cleaned_data['patient'][0]
109
        return cleaned_data
110

    
111
    def save(self, commit=True):
112

    
113
        patients = self.cleaned_data.pop('patients')
114
        for patient in patients:
115
            appointment = forms.save_instance(self, self._meta.model(), commit=False)
116
            appointment.start_datetime = datetime.combine(self.cleaned_data['date'],
117
                                                          self.cleaned_data['time'])
118
            appointment.end_datetime = appointment.start_datetime + timedelta(
119
                minutes=self.cleaned_data['duration'])
120
            appointment.creator = get_request().user
121
            appointment.clean()
122
            if commit:
123
                appointment.patient = patient
124
                appointment.save()
125
                get_request().record('new-eventwithact',
126
                                    '{obj_id} created by {user} from {ip}',
127
                                     obj_id=appointment.id)
128
                self.save_m2m()
129
                appointment.services = [self.service]
130

    
131
class UpdateAppointmentForm(NewAppointmentForm):
132

    
133
    patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
134

    
135
    def clean_patient(self):
136
        return self.cleaned_data['patient']
137

    
138
    def save(self, commit=True):
139
        appointment = super(NewAppointmentForm, self).save(commit=False)
140
        appointment.start_datetime = datetime.combine(self.cleaned_data['date'],
141
                    self.cleaned_data['time'])
142
        appointment.end_datetime = appointment.start_datetime + timedelta(
143
                minutes=self.cleaned_data['duration'])
144
        appointment.creator = get_request().user
145
        appointment.clean()
146
        if commit:
147
            appointment.save()
148
            get_request().record('update-eventwithact',
149
                                 '{obj_id} saved by {user} from {ip}',
150
                                 obj_id=appointment.id)
151
            self.save_m2m()
152
            appointment.services = [self.service]
153
        return appointment
154

    
155

    
156
class UpdatePeriodicAppointmentForm(UpdateAppointmentForm):
157
    patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
158
    recurrence_periodicity = forms.ChoiceField(label=u"Périodicité",
159
            choices=Event.PERIODICITIES, required=True)
160

    
161
    def clean(self):
162
        cleaned_data = super(UpdatePeriodicAppointmentForm, self).clean()
163
        acts = self.instance.act_set.filter(is_billed=True).order_by('-date')
164
        if acts and cleaned_data.get('recurrence_end_date'):
165
            recurrence_end_date = cleaned_data['recurrence_end_date']
166
            if recurrence_end_date < acts[0].date:
167
                self._errors['recurrence_end_date'] = self.error_class([
168
                            u"La date doit être supérieur au dernier acte facturé de la récurrence"])
169
        return cleaned_data
170

    
171
class DisablePatientAppointmentForm(UpdateAppointmentForm):
172

    
173
    def __init__(self, instance, service=None, **kwargs):
174
        super(DisablePatientAppointmentForm, self).__init__(instance,
175
                service, **kwargs)
176
        if instance and instance.pk:
177
            self.fields['patient'].required = False
178
            self.fields['patient'].widget.attrs['disabled'] = 'disabled'
179

    
180
    def clean_patient(self):
181
        instance = getattr(self, 'instance', None)
182
        if instance:
183
            return instance.patient
184
        else:
185
            return self.cleaned_data.get('patient', None)
186

    
187

    
188
class NewEventForm(BaseForm):
189
    title = forms.CharField(label=u"Complément de l'intitulé", max_length=32, required=False)
190

    
191
    class Meta:
192
        model = Event
193
        fields = (
194
                'start_datetime',
195
                'title',
196
                'date',
197
                'time',
198
                'duration',
199
                'ressource',
200
                'participants',
201
                'event_type',
202
                'services',
203
                'description',
204
                'recurrence_periodicity',
205
                'recurrence_end_date',
206
        )
207
        widgets = {
208
                'start_datetime': forms.HiddenInput,
209
                'services': forms.CheckboxSelectMultiple,
210
        }
211

    
212
    def __init__(self, instance, service=None, **kwargs):
213
        self.service = service
214
        super(NewEventForm, self).__init__(instance=instance, **kwargs)
215
        self.fields['date'].css = 'datepicker'
216
        self.fields['event_type'].queryset = \
217
                    EventType.objects.exclude(id=1).exclude(id=3).order_by('rank', 'label')
218

    
219
    def clean_duration(self):
220
        duration = self.cleaned_data['duration']
221
        try:
222
            return int(duration)
223
        except:
224
            raise forms.ValidationError('Veuillez saisir un entier')
225

    
226
    def save(self, commit=True):
227
        event = super(NewEventForm, self).save(commit=False)
228
        event.start_datetime = datetime.combine(self.cleaned_data['date'],
229
                    self.cleaned_data['time'])
230
        event.end_datetime = event.start_datetime + timedelta(
231
                minutes=self.cleaned_data['duration'])
232
        event.creator = get_request().user
233
        event.clean()
234
        if commit:
235
            event.save()
236
            get_request().record('new-event', '{obj_id} created by {user} from {ip}',
237
                                 obj_id=event.id)
238
            event.services = [self.service]
239
        return event
240

    
241
    def clean(self):
242
        cleaned_data = super(NewEventForm, self).clean()
243
        if cleaned_data.has_key('date') and cleaned_data.has_key('time'):
244
            cleaned_data['start_datetime'] = datetime.combine(cleaned_data['date'],
245
                    cleaned_data['time'])
246
        if not cleaned_data.get('recurrence_periodicity'):
247
            cleaned_data['recurrence_end_date'] = None
248
        event_type = cleaned_data.get('event_type')
249
        if event_type and event_type.id == 4 and not cleaned_data.get('title'): # 'Autre'
250
            self._errors['title'] = self.error_class([
251
                            u"Ce champ est obligatoire pour les événements de type « Autre »."])
252
        return cleaned_data
253

    
254
class UpdatePeriodicEventForm(NewEventForm):
255
    recurrence_periodicity = forms.ChoiceField(label=u"Périodicité",
256
            choices=Event.PERIODICITIES, required=True)
257

    
258
class UpdateEventForm(NewEventForm):
259
    class Meta(NewEventForm.Meta):
260
        fields = (
261
                'start_datetime',
262
                'title',
263
                'date',
264
                'time',
265
                'duration',
266
                'ressource',
267
                'participants',
268
                'event_type',
269
                'services',
270
        )
271

    
272
class PeriodicEventsSearchForm(forms.Form):
273
    start_date = forms.DateField(localize=True, required = False)
274
    end_date = forms.DateField(required=False, localize=True)
275

    
276
    event_type = forms.MultipleChoiceField(
277
            choices=(
278
                (0, 'Rendez-vous patient'),
279
                (1, 'Évènement')),
280
            widget=forms.CheckboxSelectMultiple,
281
            initial=[0,1])
282
    no_end_date = forms.BooleanField(label=u'Sans date de fin', required=False)
283
    patient = AutoCompleteSelectField('patientrecord', required=False, help_text='')
284
    worker = AutoCompleteSelectField('worker', required=False, help_text='')
285

    
286
    def clean(self):
287
        cleaned_data = super(PeriodicEventsSearchForm, self).clean()
288
        if cleaned_data.get('start_date') and cleaned_data.get('end_date'):
289
            if cleaned_data['start_date'] > cleaned_data['end_date']:
290
                raise forms.ValidationError(u'La date de début doit être supérieure à la date de fin')
291
        return cleaned_data
(5-5/10)