Project

General

Profile

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

calebasse / calebasse / facturation / list_acts.py @ 25d36369

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_billable = {}
70
    locked = False
71
    for act in acts:
72
        current_day = datetime(act.date.year, act.date.month, act.date.day)
73
        locked = are_all_acts_of_the_day_locked(current_day)
74
        if not locked:
75
            if not current_day in days_not_locked:
76
                days_not_locked.append(current_day)
77
            if act.patient in acts_not_locked:
78
                acts_not_locked[act.patient].append((act, act.date))
79
            else:
80
                acts_not_locked[act.patient] = [(act, act.date)]
81
        elif not act.is_state('VALIDE'):
82
            if act.patient in acts_not_valide:
83
                acts_not_valide[act.patient].append((act, act.get_state()))
84
            else:
85
                acts_not_valide[act.patient] = [(act, act.get_state())]
86
        elif not act.is_billable():
87
            if act.patient in acts_not_billable:
88
                acts_not_billable[act.patient].append(act)
89
            else:
90
                acts_not_billable[act.patient] = [act]
91
        else:
92
            if act.patient in acts_billable:
93
                acts_billable[act.patient].append(act)
94
            else:
95
                acts_billable[act.patient] = [act]
96
    return (acts_not_locked, days_not_locked, acts_not_valide,
97
        acts_not_billable, acts_billable)
98

    
99

    
100
def list_acts_for_billing_CAMSP(start_day, end_day, service, acts=None):
101
    """Used to sort acts billable by specific service requirements.
102

    
103
    For the CAMSP, only the state of the patient record 'CAMSP_STATE_SUIVI'
104
        at the date of the act determine if the acte is billable.
105

    
106
    acts = acts_not_locked + \
107
        acts_not_valide + \
108
            acts_not_billable + \
109
                acts_bad_state + \
110
                    acts_accepted
111

    
112
    :param end_day: formatted date that gives the last day when acts are taken
113
        in account.
114
    :type end_day: datetime
115
    :param service: service in which acts are dealt with.
116
    :type service: calebasse.ressources.Service
117

    
118
    :returns: a list of dictionnaries where patients are the keys and values
119
        are lists of acts. The second element of this list in not a dict but
120
        a list of the days where are all days are not locked.
121
    :rtype: list
122
    """
123

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

    
148

    
149
def list_acts_for_billing_SESSAD(start_day, end_day, service, acts=None):
150
    """Used to sort acts billable by specific service requirements.
151

    
152
    For the SESSAD, acts are billable if the state of the patient record at
153
        the date of the act is 'SESSAD_STATE_TRAITEMENT' and there was also a
154
        valid notification at that date.
155

    
156
    acts = acts_not_locked + \
157
        acts_not_valide + \
158
            acts_not_billable + \
159
                acts_bad_state + \
160
                    acts_missing_valid_notification + \
161
                        acts_accepted
162

    
163
    :param end_day: formatted date that gives the last day when acts are taken
164
        in account.
165
    :type end_day: datetime
166
    :param service: service in which acts are dealt with.
167
    :type service: calebasse.ressources.Service
168

    
169
    :returns: a list of dictionnaries where patients are the keys and values
170
        are lists of acts. The second element of this list in not a dict but
171
        a list of the days where are all days are not locked.
172
    :rtype: list
173
    """
174

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

    
208

    
209
def list_acts_for_billing_CMPP(end_day, service, acts=None):
210
    """Used to sort acts billable by specific service requirements.
211

    
212
    For the CMPP, acts are billable if
213

    
214
    acts = acts_not_locked + \
215
        acts_not_valide + \
216
            acts_not_billable + \
217
                acts_diagnostic + \
218
                    acts_treatment + \
219
                        acts_losts
220

    
221
    :param end_day: formatted date that gives the last day when acts are taken
222
        in account.
223
    :type end_day: datetime
224
    :param service: service in which acts are dealt with.
225
    :type service: calebasse.ressources.Service
226

    
227
    :returns: a list of dictionnaries where patients are the keys and values
228
        are lists of acts. The second element of this list in not a dict but
229
        a list of the days where are all days are not locked.
230
    :rtype: list
231
    """
232

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

    
266
def list_acts_for_billing_CMPP_2(end_day, service, acts=None):
267
    """Used to sort acts billable by specific service requirements.
268

    
269
    For the CMPP, acts are billable if
270

    
271
    acts = acts_not_locked + \
272
        acts_not_valide + \
273
            acts_not_billable + \
274
                acts_diagnostic + \
275
                    acts_treatment + \
276
                        acts_losts
277

    
278
    :param end_day: formatted date that gives the last day when acts are taken
279
        in account.
280
    :type end_day: datetime
281
    :param service: service in which acts are dealt with.
282
    :type service: calebasse.ressources.Service
283

    
284
    :returns: a list of dictionnaries where patients are the keys and values
285
        are lists of acts. The second element of this list in not a dict but
286
        a list of the days where are all days are not locked.
287
    :rtype: list
288
    """
289

    
290
    acts_not_locked, days_not_locked, acts_not_valide, \
291
        acts_not_billable, acts_billable = \
292
            list_acts_for_billing_first_round(end_day, service, acts=acts)
293

    
294
    acts_diagnostic = {}
295
    acts_treatment = {}
296
    acts_losts = {}
297
    for patient, acts in acts_billable.items():
298
        hcd = None
299
        len_acts_cared_diag = 0
300
        try:
301
            hcd = CmppHealthCareDiagnostic.objects.\
302
                filter(patient=patient).latest('start_date')
303
            # actes prise en charge par ce hc
304
            len_acts_cared_diag = len(hcd.act_set.all())
305
        except:
306
            pass
307
        hct = None
308
        len_acts_cared_trait = 0
309
        try:
310
            hct = CmppHealthCareTreatment.objects.\
311
                filter(patient=patient).latest('start_date')
312
            len_acts_cared_trait = len(hct.act_set.all())
313
        except:
314
            pass
315
        # acts are all billable and chronologically ordered
316
        count_hcd = 0
317
        count_hct = 0
318
        for act in acts:
319
            cared = False
320
            if hcd and hcd.start_date <= act.date:
321
                # Ce qui seraient prise en charge
322
                nb_acts_cared = len_acts_cared_diag + count_hcd
323
                # Ne doit pas dépasser la limite de prise en charge du hc
324
                if nb_acts_cared < hcd.get_act_number() :
325
                    if nb_acts_cared < hcd.get_act_number():
326
                        if act.patient in acts_diagnostic:
327
                            acts_diagnostic[act.patient]. \
328
                                append((act, hcd))
329
                        else:
330
                            acts_diagnostic[act.patient] = [(act, hcd)]
331
                        count_hcd = count_hcd + 1
332
                        cared = True
333
            if not cared and hct and hct.start_date <= act.date and hct.end_date >= act.date:
334
                # Ce qui seraient prise en charge
335
                nb_acts_cared = len_acts_cared_trait + count_hct
336
                # Ne doit pas dépasser la limite de prise en charge du hc
337
                if nb_acts_cared < hct.get_act_number() :
338
                    if nb_acts_cared < hct.get_act_number():
339
                        if act.patient in acts_treatment:
340
                            acts_treatment[act.patient]. \
341
                                append((act, hct))
342
                        else:
343
                            acts_treatment[act.patient] = [(act, hct)]
344
                        count_hct = count_hct + 1
345
                        cared = True
346
            if not cared:
347
                if act.patient in acts_losts:
348
                    acts_losts[act.patient]. \
349
                        append(act)
350
                else:
351
                    # TODO: give details about rejection
352
                    acts_losts[act.patient] = [act]
353
    return (acts_not_locked, days_not_locked, acts_not_valide,
354
        acts_not_billable, acts_diagnostic, acts_treatment,
355
        acts_losts)
(4-4/8)