Project

General

Profile

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

calebasse / calebasse / facturation / list_acts.py @ e4de318c

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

    
106

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

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

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

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

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

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

    
155

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

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

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

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

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

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

    
215

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

    
219
    For the CMPP, acts are billable if
220

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

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

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

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

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

    
276
    For the CMPP, acts are billable if
277

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

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

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

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

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