Projet

Général

Profil

Télécharger (44,6 ko) Statistiques
| Branche: | Tag: | Révision:

calebasse / calebasse / dossiers / views.py @ c14fdef9

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

    
3
import os
4

    
5
from datetime import datetime, date
6

    
7
from django.conf import settings
8
from django.db import models
9
from django.http import HttpResponseRedirect, HttpResponse
10
from django.views.generic import View
11
from django.views.generic.edit import DeleteView
12
from django.contrib import messages
13
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
14
from django.core.files import File
15
from django.forms import Form
16
from django.utils import formats
17
from django.shortcuts import get_object_or_404
18

    
19
from calebasse import cbv
20
from calebasse.doc_templates import make_doc_from_template
21
from calebasse.dossiers import forms
22
from calebasse.dossiers.views_utils import get_next_rdv, get_last_rdv, get_status
23
from calebasse.dossiers.transport import render_transport
24
from calebasse.agenda.models import Event, EventWithAct
25
from calebasse.actes.models import Act
26
from calebasse.agenda.appointments import Appointment
27
from calebasse.dossiers.models import (PatientRecord, PatientContact,
28
        PatientAddress, Status, FileState, create_patient, CmppHealthCareTreatment,
29
        CmppHealthCareDiagnostic, SessadHealthCareNotification, HealthCare,
30
        TransportPrescriptionLog, ProtectionState)
31
from calebasse.dossiers.states import STATES_MAPPING, STATES_BTN_MAPPER
32
from calebasse.ressources.models import (Service,
33
    SocialisationDuration, MDPHRequest, MDPHResponse)
34
from calebasse.facturation.list_acts import list_acts_for_billing_CMPP_per_patient
35

    
36
from calebasse.decorators import validator_only
37

    
38

    
39
class NewPatientRecordView(cbv.FormView, cbv.ServiceViewMixin):
40
    form_class = forms.NewPatientRecordForm
41
    template_name = 'dossiers/patientrecord_new.html'
42
    success_url = '..'
43
    patient = None
44

    
45
    def post(self, request, *args, **kwarg):
46
        self.user = request.user
47
        return super(NewPatientRecordView, self).post(request, *args, **kwarg)
48

    
49
    def form_valid(self, form):
50
        self.patient = create_patient(form.data['first_name'], form.data['last_name'], self.service,
51
                self.user, date_selected=datetime.strptime(form.data['date_selected'], "%d/%m/%Y"))
52
        return super(NewPatientRecordView, self).form_valid(form)
53

    
54
    def get_success_url(self):
55
        return '%s/view' % self.patient.id
56

    
57
new_patient_record = NewPatientRecordView.as_view()
58

    
59
class RecordPatientRecordIdMixing(object):
60
    def dispatch(self, request, *args, **kwargs):
61
        self.patientrecord_id = request.session['patientrecord_id'] = int(kwargs['patientrecord_id'])
62
        return super(RecordPatientRecordIdMixing, self).dispatch(request, *args, **kwargs)
63

    
64
    def get_form_kwargs(self):
65
        kwargs = super(RecordPatientRecordIdMixing, self).get_form_kwargs()
66
        kwargs['patient'] = PatientRecord.objects.get(id=self.patientrecord_id)
67
        return kwargs
68

    
69
class NewPatientContactView(RecordPatientRecordIdMixing, cbv.CreateView):
70
    model = PatientContact
71
    form_class = forms.PatientContactForm
72
    template_name = 'dossiers/patientcontact_new.html'
73
    success_url = '../view#tab=2'
74

    
75
    def get_initial(self):
76
        initial = super(NewPatientContactView, self).get_initial()
77
        fields = self.form_class.base_fields.keys()
78
        for arg in self.request.GET.keys():
79
            if arg in fields:
80
                if arg == 'addresses':
81
                    value = self.request.GET.getlist(arg)
82
                else:
83
                    value = self.request.GET.get(arg)
84
                initial[arg] = value
85
        if initial:
86
            if not initial.has_key('addresses'):
87
                initial['addresses'] = []
88
            patient = PatientRecord.objects.get(id=self.patientrecord_id)
89
            addresses = patient.addresses.order_by('-id')
90
            if addresses:
91
                initial['addresses'].append(addresses[0].pk)
92
        return initial
93

    
94
new_patient_contact = NewPatientContactView.as_view()
95

    
96
class UpdatePatientContactView(RecordPatientRecordIdMixing, cbv.UpdateView):
97
    model = PatientContact
98
    form_class = forms.PatientContactForm
99
    template_name = 'dossiers/patientcontact_new.html'
100
    success_url = '../../view#tab=2'
101

    
102
update_patient_contact = UpdatePatientContactView.as_view()
103

    
104
class DeletePatientContactView(cbv.DeleteView):
105
    model = PatientContact
106
    form_class = forms.PatientContactForm
107
    template_name = 'dossiers/patientcontact_confirm_delete.html'
108
    success_url = '../../view#tab=2'
109

    
110
    def post(self, request, *args, **kwargs):
111
        try:
112
            patient = PatientRecord.objects.get(id=kwargs.get('pk'))
113
        except PatientRecord.DoesNotExist:
114
            return super(DeletePatientContactView, self).post(request, *args, **kwargs)
115
        # the contact is also a patient record; it shouldn't be deleted; just
116
        # altered to remove an address
117
        patient.addresses.remove(self.request.GET['address'])
118
        return HttpResponseRedirect(self.get_success_url())
119

    
120
delete_patient_contact = DeletePatientContactView.as_view()
121

    
122
class NewPatientAddressView(cbv.CreateView):
123
    model = PatientAddress
124
    form_class = forms.PatientAddressForm
125
    template_name = 'dossiers/patientaddress_new.html'
126
    success_url = '../view#tab=2'
127

    
128
    def get_success_url(self):
129
        return self.success_url
130

    
131
    def form_valid(self, form):
132
        patientaddress = form.save()
133
        patientrecord = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
134
        patientrecord.addresses.add(patientaddress)
135
        messages.add_message(self.request, messages.INFO, u'Nouvelle adresse enregistrée avec succès.')
136
        return HttpResponseRedirect(self.get_success_url())
137

    
138
new_patient_address = NewPatientAddressView.as_view()
139

    
140
class UpdatePatientAddressView(cbv.UpdateView):
141
    model = PatientAddress
142
    form_class = forms.PatientAddressForm
143
    template_name = 'dossiers/patientaddress_new.html'
144
    success_url = '../../view#tab=2'
145

    
146
    def form_valid(self, form):
147
        messages.add_message(self.request,
148
                messages.INFO,
149
                u'Modification enregistrée avec succès.')
150
        return super(UpdatePatientAddressView, self).form_valid(form)
151

    
152
update_patient_address = UpdatePatientAddressView.as_view()
153

    
154
class DeletePatientAddressView(cbv.DeleteView):
155
    model = PatientAddress
156
    form_class = forms.PatientAddressForm
157
    template_name = 'dossiers/patientaddress_confirm_delete.html'
158
    success_url = '../../view#tab=2'
159

    
160
delete_patient_address = DeletePatientAddressView.as_view()
161

    
162

    
163
class NewHealthCareView(cbv.CreateView):
164

    
165
    def get_initial(self):
166
        initial = super(NewHealthCareView, self).get_initial()
167
        initial['author'] = self.request.user.id
168
        initial['patient'] = self.kwargs['patientrecord_id']
169
        return initial
170

    
171
new_healthcare_treatment = \
172
    NewHealthCareView.as_view(model=CmppHealthCareTreatment,
173
        template_name = 'dossiers/generic_form.html',
174
        success_url = '../view#tab=3',
175
        form_class=forms.CmppHealthCareTreatmentForm)
176
new_healthcare_diagnostic = \
177
    NewHealthCareView.as_view(model=CmppHealthCareDiagnostic,
178
        template_name = 'dossiers/generic_form.html',
179
        success_url = '../view#tab=3',
180
        form_class=forms.CmppHealthCareDiagnosticForm)
181
new_healthcare_notification = \
182
    NewHealthCareView.as_view(model=SessadHealthCareNotification,
183
        template_name = 'dossiers/generic_form.html',
184
        success_url = '../view#tab=3',
185
        form_class=forms.SessadHealthCareNotificationForm)
186
update_healthcare_treatment = \
187
    cbv.UpdateView.as_view(model=CmppHealthCareTreatment,
188
        template_name = 'dossiers/generic_form.html',
189
        success_url = '../../view#tab=3',
190
        form_class=forms.CmppHealthCareTreatmentForm)
191
update_healthcare_diagnostic = \
192
    cbv.UpdateView.as_view(model=CmppHealthCareDiagnostic,
193
        template_name = 'dossiers/generic_form.html',
194
        success_url = '../../view#tab=3',
195
        form_class=forms.CmppHealthCareDiagnosticForm)
196
update_healthcare_notification = \
197
    cbv.UpdateView.as_view(model=SessadHealthCareNotification,
198
        template_name = 'dossiers/generic_form.html',
199
        success_url = '../../view#tab=3',
200
        form_class=forms.SessadHealthCareNotificationForm)
201
delete_healthcare_treatment = \
202
    cbv.DeleteView.as_view(model=CmppHealthCareTreatment,
203
        template_name = 'dossiers/generic_confirm_delete.html',
204
        success_url = '../../view#tab=3')
205
delete_healthcare_diagnostic = \
206
    cbv.DeleteView.as_view(model=CmppHealthCareDiagnostic,
207
        template_name = 'dossiers/generic_confirm_delete.html',
208
        success_url = '../../view#tab=3')
209
delete_healthcare_notification = \
210
    cbv.DeleteView.as_view(model=SessadHealthCareNotification,
211
        template_name = 'dossiers/generic_confirm_delete.html',
212
        success_url = '../../view#tab=3')
213

    
214

    
215
class StateFormView(cbv.FormView):
216
    template_name = 'dossiers/state.html'
217
    form_class = forms.StateForm
218
    success_url = './view#tab=0'
219

    
220

    
221
    def post(self, request, *args, **kwarg):
222
        self.user = request.user
223
        return super(StateFormView, self).post(request, *args, **kwarg)
224

    
225
    def form_valid(self, form):
226
        service = Service.objects.get(id=form.data['service_id'])
227
        status = Status.objects.filter(services=service).filter(type=form.data['state_type'])
228
        patient = PatientRecord.objects.get(id=form.data['patient_id'])
229
        date_selected = datetime.strptime(form.data['date'], "%d/%m/%Y")
230
        patient.set_state(status[0], self.user, date_selected, form.data['comment'])
231
        return super(StateFormView, self).form_valid(form)
232

    
233
state_form = StateFormView.as_view()
234

    
235
class PatientRecordView(cbv.UpdateView):
236
    model = PatientRecord
237
    template_name = 'dossiers/patientrecord_update.html'
238

    
239
    def get_context_data(self, **kwargs):
240
        ctx = super(PatientRecordView, self).get_context_data(**kwargs)
241
        ctx['object'].create_diag_healthcare(self.request.user)
242
        ctx['object'].automated_switch_state(self.request.user)
243
        current_state = ctx['object'].get_current_state()
244
        if not current_state:
245
            current_state = ctx['object'].get_state()
246
            ctx['future_state'] = True
247
        if STATES_MAPPING.has_key(current_state.status.type):
248
            state = STATES_MAPPING[current_state.status.type]
249
        else:
250
            state = current_state.status.name
251
        ctx['current_state'] = current_state
252
        ctx['service_id'] = self.service.id
253
        ctx['states'] = FileState.objects.filter(patient=self.object) \
254
                .filter(status__services=self.service) \
255
                .order_by('-date_selected')
256
        return ctx
257

    
258
patient_record = PatientRecordView.as_view()
259

    
260
class PatientRecordGeneralView(cbv.UpdateView):
261
    model = PatientRecord
262
    form_class = forms.GeneralForm
263
    template_name = 'dossiers/patientrecord_tab1_general.html'
264
    success_url = './view'
265

    
266
    def get_context_data(self, **kwargs):
267
        ctx = super(PatientRecordGeneralView, self).get_context_data(**kwargs)
268
        ctx['nb_place_of_lifes'] = ctx['object'].addresses.filter(place_of_life=True).count()
269
        ctx['initial_state'] = ctx['object'].get_initial_state()
270
        ctx['last_rdv'] = get_last_rdv(ctx['object'])
271
        ctx['next_rdv'] = get_next_rdv(ctx['object'])
272
        current_state = ctx['object'].get_current_state()
273
        if current_state.status and STATES_MAPPING.has_key(current_state.status.type):
274
            state = STATES_MAPPING[current_state.status.type]
275
        else:
276
            state = current
277
        ctx['current_state'] = current_state
278
        ctx['status'], ctx['hc_status'] = get_status(ctx, self.request.user)
279
        ctx['missing_policy'] = False
280
        if not self.object.policyholder or \
281
                not self.object.policyholder.health_center or \
282
                not self.object.policyholder.social_security_id:
283
            ctx['missing_policy'] = True
284
        ctx['missing_birthdate'] = False
285
        if not self.object.birthdate:
286
            ctx['missing_birthdate'] = True
287
        return ctx
288

    
289
tab1_general = PatientRecordGeneralView.as_view()
290

    
291
class PatientRecordAdmView(cbv.ServiceViewMixin, cbv.MultiUpdateView):
292
    model = PatientRecord
293
    forms_classes = {
294
            'id': forms.CivilStatusForm,
295
            'inscription': forms.InscriptionForm,
296
            'out': forms.OutForm,
297
            'family': forms.FamilyForm,
298
            'transport': forms.TransportFrom,
299
            'followup': forms.FollowUpForm,
300
            }
301
    template_name = 'dossiers/patientrecord_tab2_fiche_adm.html'
302
    success_url = './view#tab=1'
303

    
304

    
305
    def get_context_data(self, **kwargs):
306
        ctx = super(PatientRecordAdmView, self).get_context_data(**kwargs)
307
        try:
308
            ctx['last_prescription'] = TransportPrescriptionLog.objects.filter(patient=ctx['object']).latest('created')
309
        except:
310
            pass
311
        return ctx
312

    
313
tab2_fiche_adm = PatientRecordAdmView.as_view()
314

    
315
class PatientRecordAddrView(cbv.ServiceViewMixin, cbv.MultiUpdateView):
316
    model = PatientRecord
317
    forms_classes = {
318
            'contact': forms.PatientContactForm,
319
            'policyholder': forms.PolicyHolderForm
320
            }
321
    template_name = 'dossiers/patientrecord_tab3_adresses.html'
322
    success_url = './view#tab=2'
323

    
324

    
325
    def get_context_data(self, **kwargs):
326
        ctx = super(PatientRecordAddrView, self).get_context_data(**kwargs)
327
        ctx['nb_place_of_lifes'] = ctx['object'].addresses.filter(place_of_life=True).count()
328
        ctx['addresses'] = ctx['object'].addresses.order_by('-place_of_life', 'id')
329
        return ctx
330

    
331
tab3_addresses = PatientRecordAddrView.as_view()
332

    
333
class PatientRecordNotifsView(cbv.DetailView):
334
    model = PatientRecord
335
    template_name = 'dossiers/patientrecord_tab4_notifs.html'
336

    
337
    def get_context_data(self, **kwargs):
338
        ctx = super(PatientRecordNotifsView, self).get_context_data(**kwargs)
339
        ctx['status'], ctx['hc_status'] = get_status(ctx, self.request.user)
340
        if ctx['object'].service.slug == "cmpp":
341
            (acts_not_locked, days_not_locked, acts_not_valide,
342
            acts_not_billable, acts_pause, acts_per_hc, acts_losts) = \
343
                list_acts_for_billing_CMPP_per_patient(self.object,
344
                    datetime.today(), self.service)
345
            ctx['acts_losts'] = acts_losts
346
            ctx['acts_pause'] = acts_pause
347
            hcs_used = acts_per_hc.keys()
348
            hcs = None
349
            if not hcs_used:
350
                hcs = [(hc, None) for hc in HealthCare.objects.filter(patient=self.object).order_by('-start_date')]
351
            else:
352
                hcs = []
353
                for hc in HealthCare.objects.filter(patient=self.object).order_by('-start_date'):
354
                    acts = None
355
                    if hasattr(hc, 'cmpphealthcarediagnostic') and hc.cmpphealthcarediagnostic in hcs_used:
356
                        acts = acts_per_hc[hc.cmpphealthcarediagnostic]
357
                    elif hasattr(hc, 'cmpphealthcaretreatment') and hc.cmpphealthcaretreatment in hcs_used:
358
                        acts = acts_per_hc[hc.cmpphealthcaretreatment]
359
                    hcs.append((hc, acts))
360
            ctx['hcs'] = []
361
            for hc, acts in hcs:
362
                ctx['hcs'].append((hc, acts, hc.act_set.order_by('date', 'time')))
363
        elif ctx['object'].service.slug == "sessad-ted" or ctx['object'].service.slug == "sessad-dys":
364
            ctx['hcs'] = HealthCare.objects.filter(patient=self.object).order_by('-start_date')
365
        return ctx
366

    
367
tab4_notifs = PatientRecordNotifsView.as_view()
368

    
369
class PatientRecordOldActs(cbv.DetailView):
370
    model = PatientRecord
371
    template_name = 'dossiers/patientrecord_tab5_actes_passes.html'
372

    
373
    def get_context_data(self, **kwargs):
374
        ctx = super(PatientRecordOldActs, self).get_context_data(**kwargs)
375
        ctx['last_rdvs'] = []
376
        for act in Act.objects.last_acts(ctx['object']).prefetch_related('doctors'):
377
            state = act.get_state()
378
            if state and not state.previous_state and state.state_name == 'NON_VALIDE':
379
                state = None
380
            missing_workers = []
381
            try:
382
                missing_workers = [participant.worker for participant in act.event.get_missing_participants()]
383
            except:
384
                pass
385
            ctx['last_rdvs'].append((act, state, missing_workers))
386
        history = []
387
        i = 0
388
        for state in ctx['object'].filestate_set.order_by('-date_selected'):
389
            acts = []
390
            try:
391
                while ctx['last_rdvs'][i][0].date >= state.date_selected.date():
392
                    acts.append(ctx['last_rdvs'][i])
393
                    i += 1
394
            except:
395
                pass
396
            history.append((state, acts))
397
        if i < len(ctx['last_rdvs']) - 1:
398
            history.append((None, ctx['last_rdvs'][i:]))
399
        ctx['history'] = history
400
        return ctx
401

    
402
tab5_old_acts = PatientRecordOldActs.as_view()
403

    
404
class PatientRecordNextAppointmentsView(cbv.DetailView):
405
    model = PatientRecord
406
    template_name = 'dossiers/patientrecord_tab6_next_rdv.html'
407

    
408
    def get_context_data(self, **kwargs):
409
        ctx = super(PatientRecordNextAppointmentsView, self).get_context_data(**kwargs)
410
        ctx['next_rdvs'] = []
411
        Q = models.Q
412
        today = date.today()
413
        qs = EventWithAct.objects.filter(patient=ctx['object']) \
414
                .filter(exception_to__isnull=True, canceled=False) \
415
                .filter(Q(start_datetime__gte=today) \
416
                |  Q(exceptions__isnull=False) \
417
                | ( Q(recurrence_periodicity__isnull=False) \
418
                & (Q(recurrence_end_date__gte=today) \
419
                | Q(recurrence_end_date__isnull=True) \
420
                ))) \
421
                .distinct() \
422
                .select_related() \
423
                .prefetch_related('participants', 'exceptions__eventwithact',
424
                        'act_set__actvalidationstate_set')
425
        occurrences = []
426
        for event in qs:
427
            occurrences.extend(filter(lambda e: e.start_datetime.date() >= today,
428
                event.all_occurences(limit=180)))
429
        occurrences = sorted(occurrences, key=lambda e: e.start_datetime)
430
        for event in occurrences:
431
            state = None
432
            if event.act:
433
                state = event.act.get_state()
434
            if state and not state.previous_state and state.state_name == 'NON_VALIDE':
435
                state = None
436
            ctx['next_rdvs'].append((event, state, event.get_missing_participants(), event.get_inactive_participants()))
437
        return ctx
438

    
439
tab6_next_rdv = PatientRecordNextAppointmentsView.as_view()
440

    
441
class PatientRecordSocialisationView(cbv.DetailView):
442
    model = PatientRecord
443
    template_name = 'dossiers/patientrecord_tab7_socialisation.html'
444

    
445
tab7_socialisation = PatientRecordSocialisationView.as_view()
446

    
447
class PatientRecordMedicalView(cbv.UpdateView):
448
    model = PatientRecord
449
    form_class = forms.PhysiologyForm
450
    template_name = 'dossiers/patientrecord_tab8_medical.html'
451
    success_url = './view#tab=7'
452

    
453
tab8_medical = PatientRecordMedicalView.as_view()
454

    
455
class PatientRecordsHomepageView(cbv.ListView):
456
    model = PatientRecord
457
    template_name = 'dossiers/index.html'
458

    
459

    
460
    def _get_search_result(self, paginate_patient_records):
461
        patient_records = []
462
        for patient_record in paginate_patient_records:
463
            next_rdv = get_next_rdv(patient_record)
464
            last_rdv = get_last_rdv(patient_record)
465
            current_status = patient_record.last_state.status
466
            state = current_status.name
467
            state_class = current_status.type.lower()
468
            patient_records.append(
469
                    {
470
                        'object': patient_record,
471
                        'next_rdv': next_rdv,
472
                        'last_rdv': last_rdv,
473
                        'state': state,
474
                        'state_class': state_class
475
                        }
476
                    )
477
        return patient_records
478

    
479
    def get_queryset(self):
480
        first_name = self.request.GET.get('first_name')
481
        last_name = self.request.GET.get('last_name')
482
        paper_id = self.request.GET.get('paper_id')
483
        id = self.request.GET.get('id')
484
        social_security_id = self.request.GET.get('social_security_id')
485
        if not (first_name or last_name or paper_id or id or social_security_id):
486
            return None
487
        if (first_name and len(first_name) < 2) or (last_name and len(last_name) < 2):
488
            return None
489
        qs = super(PatientRecordsHomepageView, self).get_queryset()
490
        states = self.request.GET.getlist('states')
491
        if last_name:
492
            qs = qs.filter(last_name__istartswith=last_name)
493
        if first_name:
494
            qs = qs.filter(first_name__istartswith=first_name)
495
        if paper_id:
496
            qs = qs.filter(paper_id__startswith=paper_id)
497
        if id:
498
            qs = qs.filter(id__startswith=id)
499
        if social_security_id:
500
            qs = qs.filter(models.Q(social_security_id__startswith=social_security_id) | \
501
                models.Q(contacts__social_security_id__startswith=social_security_id))
502
        if states:
503
            qs = qs.filter(last_state__status__id__in=states)
504
        else:
505
            qs = qs.filter(last_state__status__type__in="")
506
        qs = qs.filter(service=self.service).order_by('last_name').\
507
                prefetch_related('last_state',
508
                        'patientcontact', 'last_state__status')
509
        return qs
510

    
511
    def get_context_data(self, **kwargs):
512
        ctx = super(PatientRecordsHomepageView, self).get_context_data(**kwargs)
513
        ctx['search_form'] = forms.SearchForm(service=self.service, data=self.request.GET or None)
514
        ctx['stats'] = [["Dossiers", 0]]
515
        for status in Status.objects.filter(services=self.service):
516
            ctx['stats'].append([status.name, 0])
517

    
518
        page = self.request.GET.get('page')
519
        if ctx['object_list']:
520
            patient_records = ctx['object_list'].filter()
521
        else:
522
            patient_records = []
523

    
524
        # TODO: use a sql query to do this
525
        for patient_record in patient_records:
526
            ctx['stats'][0][1] += 1
527
            for elem in ctx['stats']:
528
                if elem[0] == patient_record.last_state.status.name:
529
                    elem[1] += 1
530
        paginator = Paginator(patient_records, 50)
531
        try:
532
            paginate_patient_records = paginator.page(page)
533
        except PageNotAnInteger:
534
            paginate_patient_records = paginator.page(1)
535
        except EmptyPage:
536
            paginate_patient_records = paginator.page(paginator.num_pages)
537

    
538
        query = self.request.GET.copy()
539
        if 'page' in query:
540
            del query['page']
541
        ctx['query'] = query.urlencode()
542

    
543
        ctx['paginate_patient_records'] = paginate_patient_records
544
        ctx['patient_records'] = self._get_search_result(paginate_patient_records)
545
        return ctx
546

    
547
patientrecord_home = PatientRecordsHomepageView.as_view()
548

    
549
class PatientRecordDeleteView(DeleteView):
550
    model = PatientRecord
551
    success_url = ".."
552
    template_name = 'dossiers/patientrecord_confirm_delete.html'
553

    
554
patientrecord_delete = validator_only(PatientRecordDeleteView.as_view())
555

    
556

    
557
class PatientRecordPaperIDUpdateView(cbv.UpdateView):
558
    model = PatientRecord
559
    form_class = forms.PaperIDForm
560
    template_name = 'dossiers/generic_form.html'
561
    success_url = '../..'
562

    
563
update_paper_id = PatientRecordPaperIDUpdateView.as_view()
564

    
565

    
566
class NewSocialisationDurationView(cbv.CreateView):
567
    model = SocialisationDuration
568
    form_class = forms.SocialisationDurationForm
569
    template_name = 'dossiers/generic_form.html'
570
    success_url = '../view#tab=6'
571

    
572
    def get_success_url(self):
573
        return self.success_url
574

    
575
    def get(self, request, *args, **kwargs):
576
        if kwargs.has_key('patientrecord_id'):
577
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
578
        return super(NewSocialisationDurationView, self).get(request, *args, **kwargs)
579

    
580
    def form_valid(self, form):
581
        duration = form.save()
582
        patientrecord = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
583
        patientrecord.socialisation_durations.add(duration)
584
        return HttpResponseRedirect(self.get_success_url())
585

    
586
new_socialisation_duration = NewSocialisationDurationView.as_view()
587

    
588
class UpdateSocialisationDurationView(cbv.UpdateView):
589
    model = SocialisationDuration
590
    form_class = forms.SocialisationDurationForm
591
    template_name = 'dossiers/generic_form.html'
592
    success_url = '../../view#tab=6'
593

    
594
    def get(self, request, *args, **kwargs):
595
        if kwargs.has_key('patientrecord_id'):
596
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
597
        return super(UpdateSocialisationDurationView, self).get(request, *args, **kwargs)
598

    
599
update_socialisation_duration = UpdateSocialisationDurationView.as_view()
600

    
601
class DeleteSocialisationDurationView(cbv.DeleteView):
602
    model = SocialisationDuration
603
    form_class = forms.SocialisationDurationForm
604
    template_name = 'dossiers/socialisationduration_confirm_delete.html'
605
    success_url = '../../view#tab=6'
606

    
607
delete_socialisation_duration = DeleteSocialisationDurationView.as_view()
608

    
609

    
610
class NewMDPHRequestView(cbv.CreateView):
611
    def get(self, request, *args, **kwargs):
612
        if kwargs.has_key('patientrecord_id'):
613
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
614
        return super(NewMDPHRequestView, self).get(request, *args, **kwargs)
615

    
616
    def form_valid(self, form):
617
        request = form.save()
618
        patientrecord = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
619
        patientrecord.mdph_requests.add(request)
620
        return HttpResponseRedirect(self.success_url)
621

    
622
class UpdateMDPHRequestView(cbv.UpdateView):
623
    def get(self, request, *args, **kwargs):
624
        if kwargs.has_key('patientrecord_id'):
625
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
626
        return super(UpdateMDPHRequestView, self).get(request, *args, **kwargs)
627

    
628

    
629
new_mdph_request = \
630
    NewMDPHRequestView.as_view(model=MDPHRequest,
631
        template_name = 'dossiers/generic_form.html',
632
        success_url = '../view#tab=6',
633
        form_class=forms.MDPHRequestForm)
634
update_mdph_request = \
635
    UpdateMDPHRequestView.as_view(model=MDPHRequest,
636
        template_name = 'dossiers/generic_form.html',
637
        success_url = '../../view#tab=6',
638
        form_class=forms.MDPHRequestForm)
639
delete_mdph_request = \
640
    cbv.DeleteView.as_view(model=MDPHRequest,
641
        template_name = 'dossiers/generic_confirm_delete.html',
642
        success_url = '../../view#tab=6')
643

    
644
class NewMDPHResponseView(cbv.CreateView):
645
    def get(self, request, *args, **kwargs):
646
        if kwargs.has_key('patientrecord_id'):
647
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
648
        return super(NewMDPHResponseView, self).get(request, *args, **kwargs)
649

    
650
    def form_valid(self, form):
651
        response = form.save()
652
        patientrecord = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
653
        patientrecord.mdph_responses.add(response)
654
        return HttpResponseRedirect(self.success_url)
655

    
656
class UpdateMDPHResponseView(cbv.UpdateView):
657
    def get(self, request, *args, **kwargs):
658
        if kwargs.has_key('patientrecord_id'):
659
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
660
        return super(UpdateMDPHResponseView, self).get(request, *args, **kwargs)
661

    
662

    
663
new_mdph_response = \
664
    NewMDPHResponseView.as_view(model=MDPHResponse,
665
        template_name = 'dossiers/generic_form.html',
666
        success_url = '../view#tab=6',
667
        form_class=forms.MDPHResponseForm)
668
update_mdph_response = \
669
    UpdateMDPHResponseView.as_view(model=MDPHResponse,
670
        template_name = 'dossiers/generic_form.html',
671
        success_url = '../../view#tab=6',
672
        form_class=forms.MDPHResponseForm)
673
delete_mdph_response = \
674
    cbv.DeleteView.as_view(model=MDPHResponse,
675
        template_name = 'dossiers/generic_confirm_delete.html',
676
        success_url = '../../view#tab=6')
677

    
678

    
679
class UpdatePatientStateView(cbv.ServiceFormMixin, cbv.UpdateView):
680

    
681
    def get_initial(self):
682
        initial = super(UpdatePatientStateView, self).get_initial()
683
        initial['date_selected'] = self.object.date_selected.date()
684
        return initial
685

    
686
    def get(self, request, *args, **kwargs):
687
        if kwargs.has_key('patientrecord_id'):
688
            request.session['patientrecord_id'] = kwargs['patientrecord_id']
689
        return super(UpdatePatientStateView, self).get(request, *args, **kwargs)
690

    
691
class DeletePatientView(cbv.DeleteView):
692

    
693
    def delete(self, request, *args, **kwargs):
694
        self.object = self.get_object()
695
        if self.object == self.object.patient.last_state:
696
            status = self.object.patient.filestate_set.all().order_by('-created')
697
            if len(status) > 1:
698
                self.object.patient.last_state = status[1]
699
                self.object.patient.save()
700
            else:
701
                # TODO return an error here
702
                return HttpResponseRedirect(self.get_success_url())
703
        self.object.delete()
704
        return HttpResponseRedirect(self.get_success_url())
705

    
706

    
707
update_patient_state = \
708
    UpdatePatientStateView.as_view(model=FileState,
709
        template_name = 'dossiers/generic_form.html',
710
        success_url = '../../view#tab=0',
711
        form_class=forms.PatientStateForm)
712
delete_patient_state = \
713
    DeletePatientView.as_view(model=FileState,
714
        template_name = 'dossiers/generic_confirm_delete.html',
715
        success_url = '../../view#tab=0')
716

    
717

    
718
class GenerateRtfFormView(cbv.FormView):
719
    template_name = 'dossiers/generate_rtf_form.html'
720
    form_class = forms.GenerateRtfForm
721
    success_url = './view#tab=0'
722

    
723
    def get_context_data(self, **kwargs):
724
        ctx = super(GenerateRtfFormView, self).get_context_data(**kwargs)
725
        ctx['object'] = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
726
        ctx['service_id'] = self.service.id
727
        if self.request.GET.get('event-id'):
728
            date = self.request.GET.get('date')
729
            date = datetime.strptime(date, '%Y-%m-%d').date()
730
            appointment = Appointment()
731
            event = EventWithAct.objects.get(id=self.request.GET.get('event-id'))
732
            event = event.today_occurrence(date)
733
            appointment.init_from_event(event, self.service)
734
            ctx['event'] = event
735
            ctx['appointment'] = appointment
736
        return ctx
737

    
738
    def form_valid(self, form, **kwargs):
739
        ctx = self.get_context_data(**kwargs)
740
        patient = ctx['object']
741
        appointment = ctx['appointment']
742
        event = ctx['event']
743
        template_filename = form.cleaned_data.get('template_filename')
744
        dest_filename = datetime.now().strftime('%Y-%m-%d--%H:%M:%S') + '--' + template_filename
745
        from_path = os.path.join(settings.RTF_TEMPLATES_DIRECTORY, template_filename)
746
        to_path = ''
747
        persistent = True
748
        if settings.USE_PATIENT_FILE_RTF_REPOSITORY_DIRECTORY \
749
                or settings.RTF_REPOSITORY_DIRECTORY:
750
            if settings.USE_PATIENT_FILE_RTF_REPOSITORY_DIRECTORY:
751
                to_path = patient.get_ondisk_directory(self.service.name)
752
            if settings.RTF_REPOSITORY_DIRECTORY:
753
                to_path = os.path.join(to_path,
754
                    settings.RTF_REPOSITORY_DIRECTORY)
755
            to_path = os.path.join(to_path, dest_filename)
756
        else:
757
            # else : use temporary files
758
            persistent = False
759
            to_path = dest_filename
760
        variables = {'AD11': '', 'AD12': '', 'AD13': '', 'AD14': '',
761
            'AD15': '', 'AD18': '',
762
            'JOU1': formats.date_format(datetime.today(), "DATE_FORMAT"),
763
            'VIL1': u'Saint-Étienne',
764
            'RDV1': '', 'HEU1': '', 'THE1': '', 'DPA1': '',
765
            'NOM1': '', 'PRE1': '', 'NAI1': '', 'NUM2': '',
766
            'NOM2': '', 'PRE2': '', 'TPA1': '', 'NSS1': '',
767
            'TR01': '', 'TR02': '', 'TR03': '', 'TR04': '', 'TR05': '',
768
            'AD16': '', 'AD17': '', 'AD19': '',
769
            'AD21': '', 'AD22': '', 'AD23': '', 'AD24': '', 'AD25': '',
770
            'AD26': '', 'AD27': '', 'AD28': '', 'AD29': '',
771
            'RDV2': '' ,
772
        }
773
        list_rdvs = []
774
        for act in Act.objects.last_acts(patient):
775
            state = act.get_state()
776
            if state and state.state_name in ('VALIDE', 'ACT_DOUBLE'):
777
                rdv = "\t- %s" % formats.date_format(act.date, "DATE_FORMAT")
778
                if act.time:
779
                    rdv += " à %s" % formats.date_format(act.time, "TIME_FORMAT")
780
                list_rdvs.append(rdv)
781
        variables['RDV2'] = '\par'.join(list_rdvs)
782
        if appointment:
783
            variables['RDV1'] = formats.date_format(appointment.date, "DATE_FORMAT")
784
            variables['HEU1'] = appointment.begin_hour
785
            variables['THE1'] = ' '.join([str(i) for i in appointment.workers])# ou DPA1?
786
            variables['DPA1'] = variables['THE1']
787
        if patient:
788
            variables['NOM1'] = patient.last_name
789
            variables['PRE1'] = patient.first_name
790
            if patient.birthdate :
791
                variables['NAI1'] = patient.birthdate.strftime('%d/%m/%Y')
792
            variables['NUM2'] = patient.paper_id
793
            if patient.policyholder:
794
                variables['NOM2'] = patient.policyholder.last_name
795
                variables['PRE2'] = patient.policyholder.first_name
796
                if patient.policyholder.health_center:
797
                    variables['TPA1'] = patient.policyholder.health_center.name
798
                if patient.policyholder.social_security_id:
799
                    key = str(patient.policyholder.get_control_key())
800
                    if len(key) == 1:
801
                        key = '0' + key
802
                    variables['NSS1'] = \
803
                        ' '.join([patient.policyholder.social_security_id,
804
                            key])
805
            if patient.transportcompany:
806
                variables['TR01'] = patient.transportcompany.name
807
                variables['TR02'] = patient.transportcompany.address
808
                variables['TR03'] = patient.transportcompany.address_complement
809
                variables['TR04'] = patient.transportcompany.zip_code
810
                variables['TR05'] = patient.transportcompany.city
811
        variables['AD18'] = form.cleaned_data.get('phone_address') or ''
812
        for i, line in enumerate(form.cleaned_data.get('address').splitlines()):
813
            variables['AD%d' % (11+i)] = line
814
            if i == 4:
815
                break
816

    
817
        filename = make_doc_from_template(from_path, to_path, variables,
818
            persistent)
819

    
820
        client_dir = patient.get_client_side_directory(self.service.name)
821
        event.convocation_sent = True
822
        event.save()
823
        if not client_dir:
824
            content = File(file(filename))
825
            response = HttpResponse(content,'text/rtf')
826
            response['Content-Length'] = content.size
827
            response['Content-Disposition'] = 'attachment; filename="%s"' \
828
                % dest_filename.encode('utf-8')
829
            return response
830
        else:
831
            class LocalFileHttpResponseRedirect(HttpResponseRedirect):
832
                allowed_schemes = ['file']
833
            client_filepath = os.path.join(client_dir, dest_filename)
834
            return LocalFileHttpResponseRedirect('file://' + client_filepath)
835

    
836
generate_rtf_form = GenerateRtfFormView.as_view()
837

    
838

    
839
class PatientRecordsQuotationsView(cbv.ListView):
840
    model = PatientRecord
841
    template_name = 'dossiers/quotations.html'
842

    
843
    def _get_search_result(self, paginate_patient_records):
844
        patient_records = []
845
        for patient_record in paginate_patient_records:
846
            current_state = patient_record.get_current_state() or patient_record.get_state()
847
            state = current_state.status.name
848
            state_class = current_state.status.type.lower()
849
            patient_records.append(
850
                    {
851
                        'object': patient_record,
852
                        'state': state,
853
                        'state_class': state_class
854
                        }
855
                    )
856
        return patient_records
857

    
858
    def get_queryset(self):
859
        form = forms.QuotationsForm(data=self.request.GET or None)
860
        qs = super(PatientRecordsQuotationsView, self).get_queryset()
861
        without_quotations = self.request.GET.get('without_quotations')
862
        if without_quotations:
863
            qs = qs.filter(mises_1=None).filter(mises_2=None).filter(mises_3=None)
864
        states = self.request.GET.getlist('states')
865
        qs = qs.filter(last_state__status__id__in=states)
866

    
867
        try:
868
            date_actes_start = datetime.strptime(form.data['date_actes_start'], "%d/%m/%Y")
869
            qs = qs.filter(act__date__gte=date_actes_start.date()).distinct()
870
        except (ValueError, KeyError):
871
            pass
872
        try:
873
            date_actes_end = datetime.strptime(form.data['date_actes_end'], "%d/%m/%Y")
874
            qs = qs.filter(act__date__lte=date_actes_end.date()).distinct()
875
        except (ValueError, KeyError):
876
            pass
877
        qs = qs.filter(service=self.service).order_by('last_name').prefetch_related()
878
        return qs
879

    
880
    def get_context_data(self, **kwargs):
881
        ctx = super(PatientRecordsQuotationsView, self).get_context_data(**kwargs)
882
        ctx['search_form'] = forms.QuotationsForm(data=self.request.GET or None,
883
                service=self.service)
884
        patient_records = []
885
        page = self.request.GET.get('page')
886
        paginator = Paginator(ctx['object_list'].filter(), 50)
887
        try:
888
            paginate_patient_records = paginator.page(page)
889
        except PageNotAnInteger:
890
            paginate_patient_records = paginator.page(1)
891
        except EmptyPage:
892
            paginate_patient_records = paginator.page(paginator.num_pages)
893

    
894
        ctx['patient_records'] = self._get_search_result(paginate_patient_records)
895
        ctx['paginate_patient_records'] = paginate_patient_records
896

    
897
        query = self.request.GET.copy()
898
        if 'page' in query:
899
            del query['page']
900
        ctx['query'] = query.urlencode()
901

    
902
        return ctx
903

    
904
patientrecord_quotations = PatientRecordsQuotationsView.as_view()
905

    
906
class NewProtectionStateView(cbv.CreateView):
907
    model = ProtectionState
908
    template_name = 'dossiers/generic_form.html'
909
    success_url = '../view#tab=1'
910
    form_class = forms.ProtectionStateForm
911

    
912
    def form_valid(self, form):
913
        self.patient = get_object_or_404(PatientRecord, id=self.kwargs.get('patientrecord_id',None))
914
        form.instance.patient = self.patient
915
        return super(NewProtectionStateView, self).form_valid(form)
916

    
917
new_protection = NewProtectionStateView.as_view()
918

    
919
class UpdateProtectionStateView(cbv.UpdateView):
920
    model = ProtectionState
921
    template_name = 'dossiers/generic_form.html'
922
    success_url = '../../view#tab=1'
923
    form_class = forms.ProtectionStateForm
924

    
925
    def form_valid(self, form):
926
        self.patient = get_object_or_404(PatientRecord, id=self.kwargs.get('patientrecord_id',None))
927
        form.instance.patient = self.patient
928
        return super(UpdateProtectionStateView, self).form_valid(form)
929

    
930
update_protection = UpdateProtectionStateView.as_view()
931

    
932
class DeleteProtectionStateView(cbv.DeleteView):
933
    model = ProtectionState
934
    template_name = 'dossiers/protection_confirm_delete.html'
935
    success_url = '../../view#tab=1'
936

    
937
delete_protection = DeleteProtectionStateView.as_view()
938

    
939
class PatientRecordsWaitingQueueView(cbv.ListView):
940
    model = PatientRecord
941
    template_name = 'dossiers/waiting_queue.html'
942

    
943
    def _get_search_result(self, paginate_patient_records,
944
            all_patient_records):
945
        patient_records = []
946
        if paginate_patient_records:
947
            position = 1
948
            for patient_record in paginate_patient_records:
949
                while patient_record.id != all_patient_records[position - 1].id:
950
                    position += 1
951
                patient_records.append(
952
                        {
953
                            'object': patient_record,
954
                            'position': position,
955
                            }
956
                        )
957
        return patient_records
958

    
959
    def get_queryset(self):
960
        form = forms.QuotationsForm(data=self.request.GET or None)
961
        qs = super(PatientRecordsWaitingQueueView, self).get_queryset()
962
        first_name = self.request.GET.get('first_name')
963
        last_name = self.request.GET.get('last_name')
964
        paper_id = self.request.GET.get('paper_id')
965
        id = self.request.GET.get('id')
966
        social_security_id = self.request.GET.get('social_security_id')
967
        qs = qs.filter(service=self.service,
968
            last_state__status__type='ACCUEIL')
969
        if last_name:
970
            qs = qs.filter(last_name__istartswith=last_name)
971
        if first_name:
972
            qs = qs.filter(first_name__istartswith=first_name)
973
        if paper_id:
974
            qs = qs.filter(paper_id__startswith=paper_id)
975
        if id:
976
            qs = qs.filter(id__startswith=id)
977
        if social_security_id:
978
            qs = qs.filter(models.Q(
979
                social_security_id__startswith=social_security_id)
980
                | models.Q(
981
                contacts__social_security_id__startswith=social_security_id))
982
        qs = qs.order_by('last_state__date_selected', 'created')
983
        return qs
984

    
985
    def get_context_data(self, **kwargs):
986
        ctx = super(PatientRecordsWaitingQueueView, self).get_context_data(**kwargs)
987
        ctx['search_form'] = forms.QuotationsForm(data=self.request.GET or None,
988
                service=self.service)
989
        patient_records = []
990
        page = self.request.GET.get('page')
991
        paginator = Paginator(ctx['object_list'].filter(), 50)
992
        try:
993
            paginate_patient_records = paginator.page(page)
994
        except PageNotAnInteger:
995
            paginate_patient_records = paginator.page(1)
996
        except EmptyPage:
997
            paginate_patient_records = paginator.page(paginator.num_pages)
998

    
999
        all_patient_records = PatientRecord.objects.filter(
1000
                service=self.service,
1001
                last_state__status__type='ACCUEIL').order_by(
1002
                'last_state__date_selected', 'created')
1003
        ctx['patient_records'] = self._get_search_result(
1004
            paginate_patient_records, all_patient_records)
1005
        ctx['paginate_patient_records'] = paginate_patient_records
1006
        ctx['len_patient_records'] = all_patient_records.count()
1007

    
1008
        query = self.request.GET.copy()
1009
        if 'page' in query:
1010
            del query['page']
1011
        ctx['query'] = query.urlencode()
1012

    
1013
        return ctx
1014

    
1015
patientrecord_waiting_queue = PatientRecordsWaitingQueueView.as_view()
1016

    
1017
class CreateDirectoryView(View, cbv.ServiceViewMixin):
1018
    def post(self, request, *args, **kwargs):
1019
        patient = PatientRecord.objects.get(id=kwargs['patientrecord_id'])
1020
        service = Service.objects.get(slug=kwargs['service'])
1021
        patient.get_ondisk_directory(service.name)
1022
        messages.add_message(self.request, messages.INFO, u'Répertoire patient créé.')
1023
        return HttpResponseRedirect('view')
1024

    
1025
create_directory = CreateDirectoryView.as_view()
1026

    
1027
class GenerateTransportPrescriptionFormView(cbv.FormView):
1028
    template_name = 'dossiers/generate_transport_prescription_form.html'
1029
    form_class = Form
1030
    success_url = './view#tab=1'
1031

    
1032
    def get_context_data(self, **kwargs):
1033
        ctx = super(GenerateTransportPrescriptionFormView, self).get_context_data(**kwargs)
1034
        ctx['lieu'] = 'Saint-Etienne'
1035
        ctx['date'] = formats.date_format(datetime.today(), "SHORT_DATE_FORMAT")
1036
        ctx['id_etab'] = '''%s SAINT ETIENNE
1037
66/68, RUE MARENGO
1038
42000 SAINT ETIENNE''' % ctx['service'].upper()
1039
        try:
1040
            patient = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
1041
            ctx['object'] = patient
1042
            last_log = TransportPrescriptionLog.objects.filter(patient=patient).latest('created')
1043
            if last_log:
1044
                ctx['choices'] = last_log.get_choices()
1045
                if 'lieu' in ctx['choices'] and ctx['choices']['lieu']:
1046
                    ctx['lieu'] = ctx['choices']['lieu']
1047
                if 'date' in ctx['choices'] and ctx['choices']['date']:
1048
                    ctx['date'] = ctx['choices']['date']
1049
                if 'id_etab' in ctx['choices'] and ctx['choices']['id_etab']:
1050
                    ctx['id_etab'] = ctx['choices']['id_etab']
1051
        except:
1052
            pass
1053
        return ctx
1054

    
1055
    def form_valid(self, form):
1056
        patient = PatientRecord.objects.get(id=self.kwargs['patientrecord_id'])
1057
        address = PatientAddress.objects.get(id=form.data['address_id'])
1058
        path = render_transport(patient, address, form.data)
1059
        content = File(file(path))
1060
        log = TransportPrescriptionLog(patient=patient)
1061
        log.set_choices(form.data)
1062
        log.save()
1063
        response = HttpResponse(content,'application/pdf')
1064
        response['Content-Length'] = content.size
1065
        dest_filename = "%s--prescription-transport-%s-%s.pdf" \
1066
            % (datetime.now().strftime('%Y-%m-%d--%H:%M:%S'),
1067
            patient.last_name.upper().encode('utf-8'),
1068
            patient.first_name.encode('utf-8'))
1069
        response['Content-Disposition'] = \
1070
            'attachment; filename="%s"' % dest_filename
1071
        return response
1072

    
1073
prescription_transport = GenerateTransportPrescriptionFormView.as_view()
(11-11/12)