Project

General

Profile

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

calebasse / calebasse / facturation / list_acts.py @ b5f052b7

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
        get_days_with_acts_not_locked)
6
from calebasse.dossiers.models import (CmppHealthCareDiagnostic,
7
    CmppHealthCareTreatment)
8

    
9

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

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

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

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

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

    
44
    from calebasse.actes.models import Act
45
    if isinstance(end_day, datetime):
46
        end_day = end_day.date()
47
    if start_day and isinstance(start_day, datetime):
48
        start_day = start_day.date()
49

    
50
    #if acts is None:
51
    acts = Act.objects.filter(validation_locked=False,
52
        patient__service=service, date__lte=end_day)
53
    if start_day:
54
        acts = acts.filter(date__gte=start_day)
55
    days_not_locked = sorted(set(acts.values_list('date', flat=True)))
56

    
57
    acts = Act.objects.filter(validation_locked=True,
58
        is_billed=False, valide=True, is_lost=False,
59
        patient__service=service, date__lte=end_day)
60
    if start_day:
61
        acts = acts.filter(date__gte=start_day)
62
    acts = acts.exclude(date__in=days_not_locked)
63
    acts = acts.order_by('date')
64

    
65
    # deprecated
66
    acts_not_locked = {}
67
    acts_not_valide = {}
68

    
69
    acts_pause = {}
70
    acts_not_billable = {}
71
    acts_billable = {}
72
    for act in acts:
73
        if act.pause:
74
            acts_pause.setdefault(act.patient, []).append(act)
75
        elif not act.is_billable():
76
            acts_not_billable.setdefault(act.patient, []).append(act)
77
        else:
78
            acts_billable.setdefault(act.patient, []).append(act)
79
    return (acts_not_locked, days_not_locked, acts_not_valide,
80
        acts_not_billable, acts_pause, acts_billable)
81

    
82

    
83
def list_acts_for_billing_CAMSP(start_day, end_day, service, acts=None):
84
    """Used to sort acts billable by specific service requirements.
85

    
86
    For the CAMSP, only the state of the patient record 'CAMSP_STATE_SUIVI'
87
        at the date of the act determine if the acte is billable.
88

    
89
    acts = acts_not_locked + \
90
        acts_not_valide + \
91
            acts_not_billable + \
92
                acts_bad_state + \
93
                    acts_accepted
94

    
95
    :param end_day: formatted date that gives the last day when acts are taken
96
        in account.
97
    :type end_day: datetime
98
    :param service: service in which acts are dealt with.
99
    :type service: calebasse.ressources.Service
100

    
101
    :returns: a list of dictionnaries where patients are the keys and values
102
        are lists of acts. The second element of this list in not a dict but
103
        a list of the days where are all days are not locked.
104
    :rtype: list
105
    """
106

    
107
    acts_not_locked, days_not_locked, acts_not_valide, \
108
        acts_not_billable, acts_pause, acts_billable = \
109
            list_acts_for_billing_first_round(end_day, service,
110
                start_day, acts=acts)
111
    acts_bad_state = {}
112
    acts_accepted = {}
113
    for patient, acts in acts_billable.items():
114
        for act in acts:
115
            if patient.was_in_state_at_day(act.date, 'SUIVI'):
116
                if act.patient in acts_accepted:
117
                    acts_accepted[act.patient].append(act)
118
                else:
119
                    acts_accepted[act.patient] = [act]
120
            else:
121
                if act.patient in acts_bad_state:
122
                    acts_bad_state[act.patient]. \
123
                        append((act, 'NOT_ACCOUNTABLE_STATE'))
124
                else:
125
                    acts_bad_state[act.patient] = \
126
                        [(act, 'NOT_ACCOUNTABLE_STATE')]
127
    return (acts_not_locked, days_not_locked, acts_not_valide,
128
        acts_not_billable, acts_pause, acts_bad_state,
129
        acts_accepted)
130

    
131

    
132
def list_acts_for_billing_SESSAD(start_day, end_day, service, acts=None):
133
    """Used to sort acts billable by specific service requirements.
134

    
135
    For the SESSAD, acts are billable if the state of the patient record at
136
        the date of the act is 'SESSAD_STATE_TRAITEMENT' and there was also a
137
        valid notification at that date.
138

    
139
    acts = acts_not_locked + \
140
        acts_not_valide + \
141
            acts_not_billable + \
142
                acts_bad_state + \
143
                    acts_missing_valid_notification + \
144
                        acts_accepted
145

    
146
    :param end_day: formatted date that gives the last day when acts are taken
147
        in account.
148
    :type end_day: datetime
149
    :param service: service in which acts are dealt with.
150
    :type service: calebasse.ressources.Service
151

    
152
    :returns: a list of dictionnaries where patients are the keys and values
153
        are lists of acts. The second element of this list in not a dict but
154
        a list of the days where are all days are not locked.
155
    :rtype: list
156
    """
157

    
158
    acts_not_locked, days_not_locked, acts_not_valide, \
159
        acts_not_billable, acts_pause, acts_billable = \
160
            list_acts_for_billing_first_round(end_day, service,
161
                start_day=start_day, acts=acts)
162
    acts_bad_state = {}
163
    acts_missing_valid_notification = {}
164
    acts_accepted = {}
165
    for patient, acts in acts_billable.items():
166
        for act in acts:
167
            if patient.was_in_state_at_day(act.date,
168
                    'TRAITEMENT'):
169
                if not act.was_covered_by_notification():
170
                    if act.patient in acts_missing_valid_notification:
171
                        acts_missing_valid_notification[act.patient]. \
172
                            append(act)
173
                    else:
174
                        acts_missing_valid_notification[act.patient] = [act]
175
                else:
176
                    if act.patient in acts_accepted:
177
                        acts_accepted[act.patient].append(act)
178
                    else:
179
                        acts_accepted[act.patient] = [act]
180
            else:
181
                if act.patient in acts_bad_state:
182
                    acts_bad_state[act.patient]. \
183
                        append((act, 'NOT_ACCOUNTABLE_STATE'))
184
                else:
185
                    acts_bad_state[act.patient] = \
186
                        [(act, 'NOT_ACCOUNTABLE_STATE')]
187
    return (acts_not_locked, days_not_locked, acts_not_valide,
188
        acts_not_billable, acts_pause, acts_bad_state,
189
        acts_missing_valid_notification, acts_accepted)
190

    
191

    
192
def list_acts_for_billing_CMPP(end_day, service, acts=None):
193
    """Used to sort acts billable by specific service requirements.
194

    
195
    For the CMPP, acts are billable if
196

    
197
    acts = acts_not_locked + \
198
        acts_not_valide + \
199
            acts_not_billable + \
200
                acts_diagnostic + \
201
                    acts_treatment + \
202
                        acts_losts
203

    
204
    :param end_day: formatted date that gives the last day when acts are taken
205
        in account.
206
    :type end_day: datetime
207
    :param service: service in which acts are dealt with.
208
    :type service: calebasse.ressources.Service
209

    
210
    :returns: a list of dictionnaries where patients are the keys and values
211
        are lists of acts. The second element of this list in not a dict but
212
        a list of the days where are all days are not locked.
213
    :rtype: list
214
    """
215

    
216
    acts_not_locked, days_not_locked, acts_not_valide, \
217
        acts_not_billable, acts_pause, acts_billable = \
218
            list_acts_for_billing_first_round(end_day, service, acts=acts)
219
    acts_diagnostic = {}
220
    acts_treatment = {}
221
    acts_losts = {}
222
    for patient, acts in acts_billable.items():
223
        for act in acts:
224
            cared, hc = act.is_act_covered_by_diagnostic_healthcare()
225
            if cared:
226
                if act.patient in acts_diagnostic:
227
                    acts_diagnostic[act.patient]. \
228
                        append((act, hc))
229
                else:
230
                    acts_diagnostic[act.patient] = [(act, hc)]
231
            else:
232
                cared, hc = act.is_act_covered_by_treatment_healthcare()
233
                if cared:
234
                    if act.patient in acts_treatment:
235
                        acts_treatment[act.patient]. \
236
                            append((act, hc))
237
                    else:
238
                        acts_treatment[act.patient] = [(act, hc)]
239
                else:
240
                    if act.patient in acts_losts:
241
                        acts_losts[act.patient]. \
242
                            append(act)
243
                    else:
244
                        acts_losts[act.patient] = [act]
245
    return (acts_not_locked, days_not_locked, acts_not_valide,
246
        acts_not_billable, acts_pause, acts_diagnostic,
247
        acts_treatment, acts_losts)
248

    
249
def list_acts_for_billing_CMPP_2(end_day, service, acts=None):
250
    """Used to sort acts billable by specific service requirements.
251

    
252
    For the CMPP, acts are billable if
253

    
254
    acts = acts_not_locked + \
255
        acts_not_valide + \
256
            acts_not_billable + \
257
                acts_diagnostic + \
258
                    acts_treatment + \
259
                        acts_losts
260

    
261
    :param end_day: formatted date that gives the last day when acts are taken
262
        in account.
263
    :type end_day: datetime
264
    :param service: service in which acts are dealt with.
265
    :type service: calebasse.ressources.Service
266

    
267
    :returns: a list of dictionnaries where patients are the keys and values
268
        are lists of acts. The second element of this list in not a dict but
269
        a list of the days where are all days are not locked.
270
    :rtype: list
271
    """
272

    
273
    acts_not_locked, days_not_locked, acts_not_valide, \
274
        acts_not_billable, acts_pause, acts_billable = \
275
            list_acts_for_billing_first_round(end_day, service, acts=acts)
276

    
277
    acts_diagnostic = {}
278
    acts_treatment = {}
279
    acts_losts = {}
280
    for patient, acts in acts_billable.items():
281
        hcd = None
282
        len_acts_cared_diag = 0
283
        try:
284
            hcd = CmppHealthCareDiagnostic.objects.\
285
                filter(patient=patient).latest('start_date')
286
            # actes prise en charge par ce hc
287
            len_acts_cared_diag = len(hcd.act_set.all())
288
        except:
289
            pass
290
        '''
291
            We take in account the two last treatment healthcare
292
        '''
293
        hcts = None
294
        len_acts_cared_trait = 0
295
        try:
296
            hcts = CmppHealthCareTreatment.objects.\
297
                filter(patient=patient).order_by('-start_date')
298
        except:
299
            pass
300
        # acts are all billable and chronologically ordered
301
        count_hcd = 0
302
        count_hct_1 = 0
303
        count_hct_2 = 0
304
        for act in acts:
305
            cared = False
306
            if hcd and hcd.start_date <= act.date:
307
                # Ce qui seraient prise en charge
308
                nb_acts_cared = len_acts_cared_diag + count_hcd
309
                # Ne doit pas dépasser la limite de prise en charge du hc
310
                if nb_acts_cared < hcd.get_act_number() :
311
                    if nb_acts_cared < hcd.get_act_number():
312
                        if act.patient in acts_diagnostic:
313
                            acts_diagnostic[act.patient]. \
314
                                append((act, hcd))
315
                        else:
316
                            acts_diagnostic[act.patient] = [(act, hcd)]
317
                        count_hcd = count_hcd + 1
318
                        cared = True
319
            # The one before the last may be not full.
320
            if not cared and len(hcts) > 1 and hcts[1] and hcts[1].start_date <= act.date and hcts[1].end_date >= act.date:
321
                # Ce qui seraient prise en charge
322
                # ne doit pas dépasser la limite de prise en charge du hc
323
                if count_hct_1 < hcts[1].get_act_number() - hcts[1].get_nb_acts_cared():
324
                    if act.patient in acts_treatment:
325
                        acts_treatment[act.patient]. \
326
                            append((act, hcts[1]))
327
                    else:
328
                        acts_treatment[act.patient] = [(act, hcts[1])]
329
                    count_hct_1 = count_hct_1 + 1
330
                    cared = True
331
            if not cared and len(hcts) > 0 and hcts[0] and hcts[0].start_date <= act.date and hcts[0].end_date >= act.date:
332
                if count_hct_2 < hcts[0].get_act_number() - hcts[0].get_nb_acts_cared():
333
                    if act.patient in acts_treatment:
334
                        acts_treatment[act.patient]. \
335
                            append((act, hcts[0]))
336
                    else:
337
                        acts_treatment[act.patient] = [(act, hcts[0])]
338
                    count_hct_2 = count_hct_2 + 1
339
                    cared = True
340
            if not cared:
341
                if act.patient in acts_losts:
342
                    acts_losts[act.patient]. \
343
                        append(act)
344
                else:
345
                    # TODO: give details about rejection
346
                    acts_losts[act.patient] = [act]
347
    return (acts_not_locked, days_not_locked, acts_not_valide,
348
        acts_not_billable, acts_pause, acts_diagnostic,
349
        acts_treatment, acts_losts)
(4-4/8)