Project

General

Profile

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

calebasse / calebasse / agenda / forms.py @ 784abc51

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
                self.save_m2m()
126
                appointment.services = [self.service]
127

    
128
class UpdateAppointmentForm(NewAppointmentForm):
129

    
130
    patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
131

    
132
    def clean_patient(self):
133
        return self.cleaned_data['patient']
134

    
135
    def save(self, commit=True):
136
        appointment = super(NewAppointmentForm, self).save(commit=False)
137
        appointment.start_datetime = datetime.combine(self.cleaned_data['date'],
138
                    self.cleaned_data['time'])
139
        appointment.end_datetime = appointment.start_datetime + timedelta(
140
                minutes=self.cleaned_data['duration'])
141
        appointment.creator = get_request().user
142
        appointment.clean()
143
        if commit:
144
            appointment.save()
145
            self.save_m2m()
146
            appointment.services = [self.service]
147
        return appointment
148

    
149

    
150
class UpdatePeriodicAppointmentForm(UpdateAppointmentForm):
151
    patient = make_ajax_field(EventWithAct, 'patient', 'patientrecord', False)
152
    recurrence_periodicity = forms.ChoiceField(label=u"Périodicité",
153
            choices=Event.PERIODICITIES, required=True)
154

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

    
165
class DisablePatientAppointmentForm(UpdateAppointmentForm):
166

    
167
    def __init__(self, instance, service=None, **kwargs):
168
        super(DisablePatientAppointmentForm, self).__init__(instance,
169
                service, **kwargs)
170
        if instance and instance.pk:
171
            self.fields['patient'].required = False
172
            self.fields['patient'].widget.attrs['disabled'] = 'disabled'
173

    
174
    def clean_patient(self):
175
        instance = getattr(self, 'instance', None)
176
        if instance:
177
            return instance.patient
178
        else:
179
            return self.cleaned_data.get('patient', None)
180

    
181

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

    
185
    class Meta:
186
        model = Event
187
        fields = (
188
                'start_datetime',
189
                'title',
190
                'date',
191
                'time',
192
                'duration',
193
                'ressource',
194
                'participants',
195
                'event_type',
196
                'services',
197
                'description',
198
                'recurrence_periodicity',
199
                'recurrence_end_date',
200
        )
201
        widgets = {
202
                'start_datetime': forms.HiddenInput,
203
                'services': forms.CheckboxSelectMultiple,
204
        }
205

    
206
    def __init__(self, instance, service=None, **kwargs):
207
        self.service = service
208
        super(NewEventForm, self).__init__(instance=instance, **kwargs)
209
        self.fields['date'].css = 'datepicker'
210
        self.fields['event_type'].queryset = \
211
                    EventType.objects.exclude(id=1).exclude(id=3).order_by('rank', 'label')
212

    
213
    def clean_duration(self):
214
        duration = self.cleaned_data['duration']
215
        try:
216
            return int(duration)
217
        except:
218
            raise forms.ValidationError('Veuillez saisir un entier')
219

    
220
    def save(self, commit=True):
221
        event = super(NewEventForm, self).save(commit=False)
222
        event.start_datetime = datetime.combine(self.cleaned_data['date'],
223
                    self.cleaned_data['time'])
224
        event.end_datetime = event.start_datetime + timedelta(
225
                minutes=self.cleaned_data['duration'])
226
        event.creator = get_request().user
227
        event.clean()
228
        if commit:
229
            event.save()
230
            event.services = [self.service]
231
        return event
232

    
233
    def clean(self):
234
        cleaned_data = super(NewEventForm, self).clean()
235
        if cleaned_data.has_key('date') and cleaned_data.has_key('time'):
236
            cleaned_data['start_datetime'] = datetime.combine(cleaned_data['date'],
237
                    cleaned_data['time'])
238
        if not cleaned_data.get('recurrence_periodicity'):
239
            cleaned_data['recurrence_end_date'] = None
240
        event_type = cleaned_data.get('event_type')
241
        if event_type and event_type.id == 4 and not cleaned_data.get('title'): # 'Autre'
242
            self._errors['title'] = self.error_class([
243
                            u"Ce champ est obligatoire pour les événements de type « Autre »."])
244
        return cleaned_data
245

    
246
class UpdatePeriodicEventForm(NewEventForm):
247
    recurrence_periodicity = forms.ChoiceField(label=u"Périodicité",
248
            choices=Event.PERIODICITIES, required=True)
249

    
250
class UpdateEventForm(NewEventForm):
251
    class Meta(NewEventForm.Meta):
252
        fields = (
253
                'start_datetime',
254
                'title',
255
                'date',
256
                'time',
257
                'duration',
258
                'ressource',
259
                'participants',
260
                'event_type',
261
                'services',
262
        )
263

    
264
class PeriodicEventsSearchForm(forms.Form):
265
    start_date = forms.DateField(localize=True, required = False)
266
    end_date = forms.DateField(required=False, localize=True)
267

    
268
    event_type = forms.MultipleChoiceField(
269
            choices=(
270
                (0, 'Rendez-vous patient'),
271
                (1, 'Évènement')),
272
            widget=forms.CheckboxSelectMultiple,
273
            initial=[0,1])
274
    no_end_date = forms.BooleanField(label=u'Sans date de fin', required=False)
275
    patient = AutoCompleteSelectField('patientrecord', required=False, help_text='')
276
    worker = AutoCompleteSelectField('worker', required=False, help_text='')
277

    
278
    def clean(self):
279
        cleaned_data = super(PeriodicEventsSearchForm, self).clean()
280
        if cleaned_data.get('start_date') and cleaned_data.get('end_date'):
281
            if cleaned_data['start_date'] > cleaned_data['end_date']:
282
                raise forms.ValidationError(u'La date de début doit être supérieure à la date de fin')
283
        return cleaned_data
(5-5/10)