Project

General

Profile

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

calebasse / calebasse / facturation / list_acts.py @ 76974b6f

1
# -*- coding: utf-8 -*-
2
from datetime import datetime, timedelta
3

    
4
from calebasse.actes.validation import are_all_acts_of_the_day_locked
5
from calebasse.dossiers.models import (CmppHealthCareDiagnostic,
6
    CmppHealthCareTreatment)
7

    
8

    
9
def list_acts_for_billing_first_round(end_day, service, start_day=None, acts=None):
10
    """Used to sort acts and extract acts billable before specific service
11
        requirements.
12

    
13
    At first, all acts not billed are listed per patient.
14
    Then acts are sorted.
15
    Each sorting split the acts in two sets, one set for rejected acts,
16
        on set for selected sets.
17
    First sort rejects acts days where all acts are not locked:
18
        acts_not_locked
19
    Second sort rejects acts not in state 'VALIDE':
20
        acts_not_valide
21
    Third sort rejects acts not billable:
22
        acts_not_billable
23
    Acts billable in :
24
        acts_billable
25

    
26
    acts = acts_not_locked + \
27
        acts_not_valide + \
28
            acts_not_billable + \
29
                acts_billable
30

    
31
    :param end_day: formatted date that gives the last day when acts are taken
32
        in account.
33
    :type end_day: datetime
34
    :param service: service in which acts are dealt with.
35
    :type service: calebasse.ressources.Service
36

    
37
    :returns: a list of dictionnaries where patients are the keys and values
38
        are lists of acts. The second element of this list in not a dict but
39
        a list of the days where are all days are not locked.
40
    :rtype: list
41
    """
42

    
43
    from calebasse.actes.models import EventAct
44
    if acts is None:
45
        acts = EventAct.objects.filter(is_billed=False,
46
            patient__service=service).order_by('date')
47
    # Filter acts according to the date
48
    i = 0
49
    for act in acts:
50
        # On enlève tous les acts sup au jour de l'end_date
51
        if datetime(act.date.year, act.date.month, act.date.day) > \
52
                datetime(end_day.year, end_day.month, end_day.day):
53
            acts = acts[:i]
54
            break
55
        i = i + 1
56
    if start_day:
57
        i = 0
58
        for act in acts:
59
            # On enlève tous les acts inf au jour de la start_date
60
            if datetime(act.date.year, act.date.month, act.date.day) < \
61
                    datetime(start_day.year, start_day.month, start_day.day):
62
                break
63
            i = i + 1
64
        acts = acts[:i]
65
    acts_not_locked = {}
66
    days_not_locked = []
67
    acts_not_valide = {}
68
    acts_not_billable = {}
69
    acts_pause = {}
70
    acts_billable = {}
71
    locked = False
72
    for act in acts:
73
        current_day = datetime(act.date.year, act.date.month, act.date.day)
74
        locked = are_all_acts_of_the_day_locked(current_day, service)
75
        if not locked:
76
            if not current_day in days_not_locked:
77
                days_not_locked.append(current_day)
78
            if act.patient in acts_not_locked:
79
                acts_not_locked[act.patient].append((act, act.date))
80
            else:
81
                acts_not_locked[act.patient] = [(act, act.date)]
82
        elif not act.is_state('VALIDE'):
83
            if act.patient in acts_not_valide:
84
                acts_not_valide[act.patient].append((act, act.get_state()))
85
            else:
86
                acts_not_valide[act.patient] = [(act, act.get_state())]
87
        elif not act.is_billable():
88
            if act.patient in acts_not_billable:
89
                acts_not_billable[act.patient].append(act)
90
            else:
91
                acts_not_billable[act.patient] = [act]
92
        elif act.pause:
93
            if act.patient in acts_pause:
94
                acts_pause[act.patient].append(act)
95
            else:
96
                acts_pause[act.patient] = [act]
97
        else:
98
            if act.patient in acts_billable:
99
                acts_billable[act.patient].append(act)
100
            else:
101
                acts_billable[act.patient] = [act]
102
    return (acts_not_locked, days_not_locked, acts_not_valide,
103
        acts_not_billable, acts_pause, acts_billable)
104

    
105

    
106
def list_acts_for_billing_CAMSP(start_day, end_day, service, acts=None):
107
    """Used to sort acts billable by specific service requirements.
108

    
109
    For the CAMSP, only the state of the patient record 'CAMSP_STATE_SUIVI'
110
        at the date of the act determine if the acte is billable.
111

    
112
    acts = acts_not_locked + \
113
        acts_not_valide + \
114
            acts_not_billable + \
115
                acts_bad_state + \
116
                    acts_accepted
117

    
118
    :param end_day: formatted date that gives the last day when acts are taken
119
        in account.
120
    :type end_day: datetime
121
    :param service: service in which acts are dealt with.
122
    :type service: calebasse.ressources.Service
123

    
124
    :returns: a list of dictionnaries where patients are the keys and values
125
        are lists of acts. The second element of this list in not a dict but
126
        a list of the days where are all days are not locked.
127
    :rtype: list
128
    """
129

    
130
    acts_not_locked, days_not_locked, acts_not_valide, \
131
        acts_not_billable, acts_pause, acts_billable = \
132
            list_acts_for_billing_first_round(end_day, service,
133
                start_day, acts=acts)
134
    acts_bad_state = {}
135
    acts_accepted = {}
136
    for patient, acts in acts_billable.items():
137
        for act in acts:
138
            if patient.was_in_state_at_day(act.date, 'SUIVI'):
139
                if act.patient in acts_accepted:
140
                    acts_accepted[act.patient].append(act)
141
                else:
142
                    acts_accepted[act.patient] = [act]
143
            else:
144
                if act.patient in acts_bad_state:
145
                    acts_bad_state[act.patient]. \
146
                        append((act, 'NOT_ACCOUNTABLE_STATE'))
147
                else:
148
                    acts_bad_state[act.patient] = \
149
                        [(act, 'NOT_ACCOUNTABLE_STATE')]
150
    return (acts_not_locked, days_not_locked, acts_not_valide,
151
        acts_not_billable, acts_pause, acts_bad_state,
152
        acts_accepted)
153

    
154

    
155
def list_acts_for_billing_SESSAD(start_day, end_day, service, acts=None):
156
    """Used to sort acts billable by specific service requirements.
157

    
158
    For the SESSAD, acts are billable if the state of the patient record at
159
        the date of the act is 'SESSAD_STATE_TRAITEMENT' and there was also a
160
        valid notification at that date.
161

    
162
    acts = acts_not_locked + \
163
        acts_not_valide + \
164
            acts_not_billable + \
165
                acts_bad_state + \
166
                    acts_missing_valid_notification + \
167
                        acts_accepted
168

    
169
    :param end_day: formatted date that gives the last day when acts are taken
170
        in account.
171
    :type end_day: datetime
172
    :param service: service in which acts are dealt with.
173
    :type service: calebasse.ressources.Service
174

    
175
    :returns: a list of dictionnaries where patients are the keys and values
176
        are lists of acts. The second element of this list in not a dict but
177
        a list of the days where are all days are not locked.
178
    :rtype: list
179
    """
180

    
181
    acts_not_locked, days_not_locked, acts_not_valide, \
182
        acts_not_billable, acts_pause, acts_billable = \
183
            list_acts_for_billing_first_round(end_day, service,
184
                start_day=start_day, acts=acts)
185
    acts_bad_state = {}
186
    acts_missing_valid_notification = {}
187
    acts_accepted = {}
188
    for patient, acts in acts_billable.items():
189
        for act in acts:
190
            if patient.was_in_state_at_day(act.date,
191
                    'TRAITEMENT'):
192
                if not act.was_covered_by_notification():
193
                    if act.patient in acts_missing_valid_notification:
194
                        acts_missing_valid_notification[act.patient]. \
195
                            append(act)
196
                    else:
197
                        acts_missing_valid_notification[act.patient] = [act]
198
                else:
199
                    if act.patient in acts_accepted:
200
                        acts_accepted[act.patient].append(act)
201
                    else:
202
                        acts_accepted[act.patient] = [act]
203
            else:
204
                if act.patient in acts_bad_state:
205
                    acts_bad_state[act.patient]. \
206
                        append((act, 'NOT_ACCOUNTABLE_STATE'))
207
                else:
208
                    acts_bad_state[act.patient] = \
209
                        [(act, 'NOT_ACCOUNTABLE_STATE')]
210
    return (acts_not_locked, days_not_locked, acts_not_valide,
211
        acts_not_billable, acts_pause, acts_bad_state,
212
        acts_missing_valid_notification, acts_accepted)
213

    
214

    
215
def list_acts_for_billing_CMPP(end_day, service, acts=None):
216
    """Used to sort acts billable by specific service requirements.
217

    
218
    For the CMPP, acts are billable if
219

    
220
    acts = acts_not_locked + \
221
        acts_not_valide + \
222
            acts_not_billable + \
223
                acts_diagnostic + \
224
                    acts_treatment + \
225
                        acts_losts
226

    
227
    :param end_day: formatted date that gives the last day when acts are taken
228
        in account.
229
    :type end_day: datetime
230
    :param service: service in which acts are dealt with.
231
    :type service: calebasse.ressources.Service
232

    
233
    :returns: a list of dictionnaries where patients are the keys and values
234
        are lists of acts. The second element of this list in not a dict but
235
        a list of the days where are all days are not locked.
236
    :rtype: list
237
    """
238

    
239
    acts_not_locked, days_not_locked, acts_not_valide, \
240
        acts_not_billable, acts_pause, acts_billable = \
241
            list_acts_for_billing_first_round(end_day, service, acts=acts)
242
    acts_diagnostic = {}
243
    acts_treatment = {}
244
    acts_losts = {}
245
    for patient, acts in acts_billable.items():
246
        for act in acts:
247
            cared, hc = act.is_act_covered_by_diagnostic_healthcare()
248
            if cared:
249
                if act.patient in acts_diagnostic:
250
                    acts_diagnostic[act.patient]. \
251
                        append((act, hc))
252
                else:
253
                    acts_diagnostic[act.patient] = [(act, hc)]
254
            else:
255
                cared, hc = act.is_act_covered_by_treatment_healthcare()
256
                if cared:
257
                    if act.patient in acts_treatment:
258
                        acts_treatment[act.patient]. \
259
                            append((act, hc))
260
                    else:
261
                        acts_treatment[act.patient] = [(act, hc)]
262
                else:
263
                    if act.patient in acts_losts:
264
                        acts_losts[act.patient]. \
265
                            append(act)
266
                    else:
267
                        acts_losts[act.patient] = [act]
268
    return (acts_not_locked, days_not_locked, acts_not_valide,
269
        acts_not_billable, acts_pause, acts_diagnostic,
270
        acts_treatment, acts_losts)
271

    
272
def list_acts_for_billing_CMPP_2(end_day, service, acts=None):
273
    """Used to sort acts billable by specific service requirements.
274

    
275
    For the CMPP, acts are billable if
276

    
277
    acts = acts_not_locked + \
278
        acts_not_valide + \
279
            acts_not_billable + \
280
                acts_diagnostic + \
281
                    acts_treatment + \
282
                        acts_losts
283

    
284
    :param end_day: formatted date that gives the last day when acts are taken
285
        in account.
286
    :type end_day: datetime
287
    :param service: service in which acts are dealt with.
288
    :type service: calebasse.ressources.Service
289

    
290
    :returns: a list of dictionnaries where patients are the keys and values
291
        are lists of acts. The second element of this list in not a dict but
292
        a list of the days where are all days are not locked.
293
    :rtype: list
294
    """
295

    
296
    acts_not_locked, days_not_locked, acts_not_valide, \
297
        acts_not_billable, acts_pause, acts_billable = \
298
            list_acts_for_billing_first_round(end_day, service, acts=acts)
299

    
300
    acts_diagnostic = {}
301
    acts_treatment = {}
302
    acts_losts = {}
303
    for patient, acts in acts_billable.items():
304
        hcd = None
305
        len_acts_cared_diag = 0
306
        try:
307
            hcd = CmppHealthCareDiagnostic.objects.\
308
                filter(patient=patient).latest('start_date')
309
            # actes prise en charge par ce hc
310
            len_acts_cared_diag = len(hcd.act_set.all())
311
        except:
312
            pass
313
        '''
314
            We take in account the two last treatment healthcare
315
        '''
316
        hcts = None
317
        len_acts_cared_trait = 0
318
        try:
319
            hcts = CmppHealthCareTreatment.objects.\
320
                filter(patient=patient).order_by('-start_date')
321
        except:
322
            pass
323
        # acts are all billable and chronologically ordered
324
        count_hcd = 0
325
        count_hct_1 = 0
326
        count_hct_2 = 0
327
        for act in acts:
328
            cared = False
329
            if hcd and hcd.start_date <= act.date.date():
330
                # Ce qui seraient prise en charge
331
                nb_acts_cared = len_acts_cared_diag + count_hcd
332
                # Ne doit pas dépasser la limite de prise en charge du hc
333
                if nb_acts_cared < hcd.get_act_number() :
334
                    if nb_acts_cared < hcd.get_act_number():
335
                        if act.patient in acts_diagnostic:
336
                            acts_diagnostic[act.patient]. \
337
                                append((act, hcd))
338
                        else:
339
                            acts_diagnostic[act.patient] = [(act, hcd)]
340
                        count_hcd = count_hcd + 1
341
                        cared = True
342
            # The one before the last may be not full.
343
            if not cared and len(hcts) > 1 and hcts[1] and hcts[1].start_date <= act.date.date() and hcts[1].end_date >= act.date.date():
344
                # Ce qui seraient prise en charge
345
                # ne doit pas dépasser la limite de prise en charge du hc
346
                if count_hct_1 < hcts[1].get_act_number() - hcts[1].get_nb_acts_cared():
347
                    if act.patient in acts_treatment:
348
                        acts_treatment[act.patient]. \
349
                            append((act, hcts[1]))
350
                    else:
351
                        acts_treatment[act.patient] = [(act, hcts[1])]
352
                    count_hct_1 = count_hct_1 + 1
353
                    cared = True
354
            if not cared and len(hcts) > 0 and hcts[0] and hcts[0].start_date <= act.date.date() and hcts[0].end_date >= act.date.date():
355
                if count_hct_2 < hcts[0].get_act_number() - hcts[0].get_nb_acts_cared():
356
                    if act.patient in acts_treatment:
357
                        acts_treatment[act.patient]. \
358
                            append((act, hcts[0]))
359
                    else:
360
                        acts_treatment[act.patient] = [(act, hcts[0])]
361
                    count_hct_2 = count_hct_2 + 1
362
                    cared = True
363
            if not cared:
364
                if act.patient in acts_losts:
365
                    acts_losts[act.patient]. \
366
                        append(act)
367
                else:
368
                    # TODO: give details about rejection
369
                    acts_losts[act.patient] = [act]
370
    return (acts_not_locked, days_not_locked, acts_not_valide,
371
        acts_not_billable, acts_pause, acts_diagnostic,
372
        acts_treatment, acts_losts)
(4-4/8)