Projet

Général

Profil

0004-maelis-decompose-units-related-to-moments-of-the-day.patch

Nicolas Roche, 23 décembre 2020 17:35

Télécharger (25,3 ko)

Voir les différences:

Subject: [PATCH 4/4] maelis: decompose units related to moments of the day
 (#48480)

 passerelle/apps/maelis/models.py              |   7 +-
 passerelle/apps/maelis/utils.py               |  57 +++
 .../child_planning_after_decomposition.json   | 383 ++++++++++++++++++
 tests/test_maelis.py                          |  47 ++-
 4 files changed, 485 insertions(+), 9 deletions(-)
 create mode 100644 tests/data/maelis/child_planning_after_decomposition.json
passerelle/apps/maelis/models.py
404 404
        display_order=3,
405 405
        description=_('Read child planning'),
406 406
        name='child-planning',
407 407
        parameters={
408 408
            'NameID': {'description': _('Publik ID')},
409 409
            'childID': {'description': _('Child ID')},
410 410
            'start_date': {'description': _('Start date (YYYY-MM-DD format)')},
411 411
            'end_date': {'description': _('End date (YYYY-MM-DD format)')},
412
            'legacy': {'description': _('Decompose events releted to parts of the day if set')},
412 413
    })
413
    def child_planning(self, request, NameID, childID, start_date=None, end_date=None):
414
    def child_planning(self, request, NameID, childID, start_date=None, end_date=None, legacy=None):
414 415
        """ Return an events list sorted by id """
415 416
        link = self.get_link(NameID)
416 417
        family_data = self.get_family_data(link.family_id)
417 418
        if childID not in [c['id'] for c in family_data['childInfoList']]:
418 419
            raise APIError('Child not found', err_code='not-found')
419 420
        if start_date and end_date:
420 421
            start = utils.get_datetime(start_date)
421 422
            end = utils.get_datetime(end_date)
......
436 437
            r = self.call('ActivityService?wsdl', 'readChildMonthPlanning',
437 438
                          year=date.year,
438 439
                          numMonth=date.month,
439 440
                          numPerson=childID)
440 441
            planning = serialize_object(r['calendList'])
441 442
            for schedule in planning:
442 443
                utils.book_event(events, schedule, start, end)
443 444

  
445
        if not legacy:
446
            events = {x['id']: x  # dictionary is used de remove dupplicated events
447
                      for e in events.values()
448
                      for x in utils.decompose_event(e)}
444 449
        return {'data': [s[1] for s in sorted(events.items())]}
445 450

  
446 451

  
447 452
class Link(models.Model):
448 453
    resource = models.ForeignKey(Maelis, on_delete=models.CASCADE)
449 454
    name_id = models.CharField(blank=False, max_length=256)
450 455
    family_id = models.CharField(blank=False, max_length=128)
451 456
    created = models.DateTimeField(auto_now_add=True)
passerelle/apps/maelis/utils.py
12 12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 13
# GNU Affero General Public License for more details.
14 14
#
15 15
# You should have received a copy of the GNU Affero General Public License
16 16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 17

  
18 18
from __future__ import unicode_literals
19 19

  
20
from copy import copy
20 21
from datetime import datetime
21 22
from dateutil.relativedelta import relativedelta
22 23

  
23 24
from django.utils import timezone
24 25
from django.utils.dateparse import parse_date
25 26

  
26 27
from passerelle.utils.jsonresponse import APIError
27 28

  
28 29
DATE_FORMAT = '%Y-%m-%d'
29 30
TIME_FORMAT = '%H:%M:%S'
30 31
DATETIME_FORMAT = DATE_FORMAT + ' ' + TIME_FORMAT
31 32

  
33
COMPONENTS = {
34
    'PART01': {
35
        'text': 'Matinée',
36
        'time': '08:00:00',
37
    },
38
    'PART02': {
39
        'text': 'Repas',
40
        'time': '12:00:00',
41
    },
42
    'PART03': {
43
        'text': 'Après-midi',
44
        'time': '14:00:00',
45
    }
46
}
47

  
48
COMPOSED_UNITS = {
49
    'A10003132034': {  # JOURNEE
50
        'virtual_unit': 'EO0001',
51
        'components': ['PART01', 'PART02', 'PART03'],
52
    },
53
    'A10003132036': {  # MATIN
54
        'virtual_unit': 'EO0001',
55
        'components': ['PART01'],
56
    },
57
    'A10003132038': {  # MATIN ET REPAS
58
        'virtual_unit': 'EO0001',
59
        'components': ['PART01', 'PART02'],
60
    },
61
    'A10003132040': {  # APRES MIDI
62
        'virtual_unit': 'EO0001',
63
        'components': ['PART03'],
64
    },
65
}
66

  
32 67

  
33 68
def normalize_invoice(invoice):
34 69
    data = {
35 70
        'id': '%s-%s' % (invoice.numFamily, invoice.numInvoice),
36 71
        'display_id': str(invoice.numInvoice),
37 72
        'label': invoice.TTFInfo.libelle,
38 73
        'created': invoice.dateInvoice.strftime(DATETIME_FORMAT),
39 74
        'amount': invoice.amountInvoice - invoice.amountPaid,
......
142 177
        # database may be corrupted by using updateScheduleCalendars
143 178
        try:
144 179
            event = events[event_id]
145 180
        except KeyError:
146 181
            raise APIError('The planning returns an unknow day on activities: %s'
147 182
                           % day['datePlanning'])
148 183

  
149 184
        event['user_booking_status'] = 'booked'
185

  
186

  
187
def decompose_event(event):
188
    """ Break down 'JOURNEE', 'MATIN', 'MATIN ET REPAS' and APRES MIDI' units
189
    into 'Matin', 'Repas' and 'Après-midi' virtual units.  """
190
    if event['slot_id'] not in COMPOSED_UNITS.keys():
191
        yield event
192
        return
193

  
194
    date_time = datetime.strptime(event['datetime'], DATETIME_FORMAT)
195
    date_string = date_time.strftime(DATE_FORMAT)
196
    composition = COMPOSED_UNITS[event['slot_id']]
197

  
198
    for component_id in composition['components']:
199
        component = COMPONENTS[component_id]
200
        new_event = copy(event)
201
        new_event['datetime'] = '%s %s' % (date_string, component['time'])
202
        new_event['slot_id'] = "%s%s" % (composition['virtual_unit'], component_id)
203
        new_event['id'] = '%s-%s-%s' % (
204
            date_string, event['category_id'], new_event['slot_id'])
205
        new_event['text'] = component['text']
206
        yield new_event
tests/data/maelis/child_planning_after_decomposition.json
1
{
2
   "data" : [
3
      {
4
         "category" : "MULTI ACCUEIL LES OLIVIERS",
5
         "category_id" : "A10000003840",
6
         "datetime" : "2020-12-14 00:00:00",
7
         "id" : "2020-12-14-A10000003840-A10000003844",
8
         "slot_id" : "A10000003844",
9
         "text" : "MULTI ACCUEIL LES OLIVIERS - Réguliers",
10
         "user_booking_status" : "not-booked"
11
      },
12
      {
13
         "category" : "MULTI ACCUEIL LES OLIVIERS",
14
         "category_id" : "A10000003840",
15
         "datetime" : "2020-12-14 00:00:00",
16
         "id" : "2020-12-14-A10000003840-A10000003845",
17
         "slot_id" : "A10000003845",
18
         "text" : "MULTI ACCUEIL LES OLIVIERS - Occasionnels",
19
         "user_booking_status" : "not-booked"
20
      },
21
      {
22
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
23
         "category_id" : "A10000006100",
24
         "datetime" : "2020-12-14 00:00:00",
25
         "id" : "2020-12-14-A10000006100-A10000006104",
26
         "slot_id" : "A10000006104",
27
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Réguliers",
28
         "user_booking_status" : "not-booked"
29
      },
30
      {
31
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
32
         "category_id" : "A10000006100",
33
         "datetime" : "2020-12-14 00:00:00",
34
         "id" : "2020-12-14-A10000006100-A10000006105",
35
         "slot_id" : "A10000006105",
36
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Occasionnels",
37
         "user_booking_status" : "not-booked"
38
      },
39
      {
40
         "category" : "1 2020-2021 GARDERIE MATIN",
41
         "category_id" : "A10003121692",
42
         "datetime" : "2020-12-14 00:00:00",
43
         "id" : "2020-12-14-A10003121692-A10003121694",
44
         "slot_id" : "A10003121694",
45
         "text" : "1 2020-2021 GARDERIE MATIN",
46
         "user_booking_status" : "booked"
47
      },
48
      {
49
         "category" : "2 2020-2021  RESTAURATION SCOLAIRE",
50
         "category_id" : "A10003123490",
51
         "datetime" : "2020-12-14 00:00:00",
52
         "id" : "2020-12-14-A10003123490-A10003123492",
53
         "slot_id" : "A10003123492",
54
         "text" : "2 2020-2021  RESTAURATION SCOLAIRE",
55
         "user_booking_status" : "booked"
56
      },
57
      {
58
         "category" : "3 2020-2021 GARDERIE SOIR",
59
         "category_id" : "A10003123507",
60
         "datetime" : "2020-12-14 00:00:00",
61
         "id" : "2020-12-14-A10003123507-A10003123509",
62
         "slot_id" : "A10003123509",
63
         "text" : "3 2020-2021 GARDERIE SOIR",
64
         "user_booking_status" : "not-booked"
65
      },
66
      {
67
         "category" : "COURS DE DANSE",
68
         "category_id" : "A10003132090",
69
         "datetime" : "2020-12-14 00:00:00",
70
         "id" : "2020-12-14-A10003132090-A10003132091",
71
         "slot_id" : "A10003132091",
72
         "text" : "COURS DE DANSE",
73
         "user_booking_status" : "not-booked"
74
      },
75
      {
76
         "category" : "ATELIER D'EXPRESSION THEATRALE",
77
         "category_id" : "A10003132293",
78
         "datetime" : "2020-12-14 00:00:00",
79
         "id" : "2020-12-14-A10003132293-A10003132295",
80
         "slot_id" : "A10003132295",
81
         "text" : "ATELIER D'EXPRESSION THEATRALE",
82
         "user_booking_status" : "not-booked"
83
      },
84
      {
85
         "category" : "MULTI ACCUEIL LES OLIVIERS",
86
         "category_id" : "A10000003840",
87
         "datetime" : "2020-12-15 00:00:00",
88
         "id" : "2020-12-15-A10000003840-A10000003844",
89
         "slot_id" : "A10000003844",
90
         "text" : "MULTI ACCUEIL LES OLIVIERS - Réguliers",
91
         "user_booking_status" : "not-booked"
92
      },
93
      {
94
         "category" : "MULTI ACCUEIL LES OLIVIERS",
95
         "category_id" : "A10000003840",
96
         "datetime" : "2020-12-15 00:00:00",
97
         "id" : "2020-12-15-A10000003840-A10000003845",
98
         "slot_id" : "A10000003845",
99
         "text" : "MULTI ACCUEIL LES OLIVIERS - Occasionnels",
100
         "user_booking_status" : "not-booked"
101
      },
102
      {
103
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
104
         "category_id" : "A10000006100",
105
         "datetime" : "2020-12-15 00:00:00",
106
         "id" : "2020-12-15-A10000006100-A10000006104",
107
         "slot_id" : "A10000006104",
108
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Réguliers",
109
         "user_booking_status" : "not-booked"
110
      },
111
      {
112
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
113
         "category_id" : "A10000006100",
114
         "datetime" : "2020-12-15 00:00:00",
115
         "id" : "2020-12-15-A10000006100-A10000006105",
116
         "slot_id" : "A10000006105",
117
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Occasionnels",
118
         "user_booking_status" : "not-booked"
119
      },
120
      {
121
         "category" : "1 2020-2021 GARDERIE MATIN",
122
         "category_id" : "A10003121692",
123
         "datetime" : "2020-12-15 00:00:00",
124
         "id" : "2020-12-15-A10003121692-A10003121694",
125
         "slot_id" : "A10003121694",
126
         "text" : "1 2020-2021 GARDERIE MATIN",
127
         "user_booking_status" : "booked"
128
      },
129
      {
130
         "category" : "2 2020-2021  RESTAURATION SCOLAIRE",
131
         "category_id" : "A10003123490",
132
         "datetime" : "2020-12-15 00:00:00",
133
         "id" : "2020-12-15-A10003123490-A10003123492",
134
         "slot_id" : "A10003123492",
135
         "text" : "2 2020-2021  RESTAURATION SCOLAIRE",
136
         "user_booking_status" : "booked"
137
      },
138
      {
139
         "category" : "3 2020-2021 GARDERIE SOIR",
140
         "category_id" : "A10003123507",
141
         "datetime" : "2020-12-15 00:00:00",
142
         "id" : "2020-12-15-A10003123507-A10003123509",
143
         "slot_id" : "A10003123509",
144
         "text" : "3 2020-2021 GARDERIE SOIR",
145
         "user_booking_status" : "not-booked"
146
      },
147
      {
148
         "category" : "COURS DE DANSE",
149
         "category_id" : "A10003132090",
150
         "datetime" : "2020-12-15 00:00:00",
151
         "id" : "2020-12-15-A10003132090-A10003132091",
152
         "slot_id" : "A10003132091",
153
         "text" : "COURS DE DANSE",
154
         "user_booking_status" : "not-booked"
155
      },
156
      {
157
         "category" : "MULTI ACCUEIL LES OLIVIERS",
158
         "category_id" : "A10000003840",
159
         "datetime" : "2020-12-16 00:00:00",
160
         "id" : "2020-12-16-A10000003840-A10000003844",
161
         "slot_id" : "A10000003844",
162
         "text" : "MULTI ACCUEIL LES OLIVIERS - Réguliers",
163
         "user_booking_status" : "not-booked"
164
      },
165
      {
166
         "category" : "MULTI ACCUEIL LES OLIVIERS",
167
         "category_id" : "A10000003840",
168
         "datetime" : "2020-12-16 00:00:00",
169
         "id" : "2020-12-16-A10000003840-A10000003845",
170
         "slot_id" : "A10000003845",
171
         "text" : "MULTI ACCUEIL LES OLIVIERS - Occasionnels",
172
         "user_booking_status" : "not-booked"
173
      },
174
      {
175
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
176
         "category_id" : "A10000006100",
177
         "datetime" : "2020-12-16 00:00:00",
178
         "id" : "2020-12-16-A10000006100-A10000006104",
179
         "slot_id" : "A10000006104",
180
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Réguliers",
181
         "user_booking_status" : "not-booked"
182
      },
183
      {
184
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
185
         "category_id" : "A10000006100",
186
         "datetime" : "2020-12-16 00:00:00",
187
         "id" : "2020-12-16-A10000006100-A10000006105",
188
         "slot_id" : "A10000006105",
189
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Occasionnels",
190
         "user_booking_status" : "not-booked"
191
      },
192
      {
193
         "category" : "2020-2021 CENTRE DE LOISIRS MERCREDI",
194
         "category_id" : "A10003132030",
195
         "datetime" : "2020-12-16 00:00:00",
196
         "id" : "2020-12-16-A10003132030-A10003132032",
197
         "slot_id" : "A10003132032",
198
         "text" : "2020-2021 CENTRE DE LOISIRS MERCREDI",
199
         "user_booking_status" : "booked"
200
      },
201
      {
202
         "category" : "2020-2021 CENTRE DE LOISIRS MERCREDI",
203
         "category_id" : "A10003132030",
204
         "datetime" : "2020-12-16 08:00:00",
205
         "id" : "2020-12-16-A10003132030-EO0001PART01",
206
         "slot_id" : "EO0001PART01",
207
         "text" : "Matinée",
208
         "user_booking_status" : "not-booked"
209
      },
210
      {
211
         "category" : "2020-2021 CENTRE DE LOISIRS MERCREDI",
212
         "category_id" : "A10003132030",
213
         "datetime" : "2020-12-16 12:00:00",
214
         "id" : "2020-12-16-A10003132030-EO0001PART02",
215
         "slot_id" : "EO0001PART02",
216
         "text" : "Repas",
217
         "user_booking_status" : "not-booked"
218
      },
219
      {
220
         "category" : "2020-2021 CENTRE DE LOISIRS MERCREDI",
221
         "category_id" : "A10003132030",
222
         "datetime" : "2020-12-16 14:00:00",
223
         "id" : "2020-12-16-A10003132030-EO0001PART03",
224
         "slot_id" : "EO0001PART03",
225
         "text" : "Après-midi",
226
         "user_booking_status" : "not-booked"
227
      },
228
      {
229
         "category" : "COURS DE DANSE",
230
         "category_id" : "A10003132090",
231
         "datetime" : "2020-12-16 00:00:00",
232
         "id" : "2020-12-16-A10003132090-A10003132091",
233
         "slot_id" : "A10003132091",
234
         "text" : "COURS DE DANSE",
235
         "user_booking_status" : "not-booked"
236
      },
237
      {
238
         "category" : "MULTI ACCUEIL LES OLIVIERS",
239
         "category_id" : "A10000003840",
240
         "datetime" : "2020-12-17 00:00:00",
241
         "id" : "2020-12-17-A10000003840-A10000003844",
242
         "slot_id" : "A10000003844",
243
         "text" : "MULTI ACCUEIL LES OLIVIERS - Réguliers",
244
         "user_booking_status" : "not-booked"
245
      },
246
      {
247
         "category" : "MULTI ACCUEIL LES OLIVIERS",
248
         "category_id" : "A10000003840",
249
         "datetime" : "2020-12-17 00:00:00",
250
         "id" : "2020-12-17-A10000003840-A10000003845",
251
         "slot_id" : "A10000003845",
252
         "text" : "MULTI ACCUEIL LES OLIVIERS - Occasionnels",
253
         "user_booking_status" : "not-booked"
254
      },
255
      {
256
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
257
         "category_id" : "A10000006100",
258
         "datetime" : "2020-12-17 00:00:00",
259
         "id" : "2020-12-17-A10000006100-A10000006104",
260
         "slot_id" : "A10000006104",
261
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Réguliers",
262
         "user_booking_status" : "not-booked"
263
      },
264
      {
265
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
266
         "category_id" : "A10000006100",
267
         "datetime" : "2020-12-17 00:00:00",
268
         "id" : "2020-12-17-A10000006100-A10000006105",
269
         "slot_id" : "A10000006105",
270
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Occasionnels",
271
         "user_booking_status" : "not-booked"
272
      },
273
      {
274
         "category" : "1 2020-2021 GARDERIE MATIN",
275
         "category_id" : "A10003121692",
276
         "datetime" : "2020-12-17 00:00:00",
277
         "id" : "2020-12-17-A10003121692-A10003121694",
278
         "slot_id" : "A10003121694",
279
         "text" : "1 2020-2021 GARDERIE MATIN",
280
         "user_booking_status" : "booked"
281
      },
282
      {
283
         "category" : "2 2020-2021  RESTAURATION SCOLAIRE",
284
         "category_id" : "A10003123490",
285
         "datetime" : "2020-12-17 00:00:00",
286
         "id" : "2020-12-17-A10003123490-A10003123492",
287
         "slot_id" : "A10003123492",
288
         "text" : "2 2020-2021  RESTAURATION SCOLAIRE",
289
         "user_booking_status" : "booked"
290
      },
291
      {
292
         "category" : "3 2020-2021 GARDERIE SOIR",
293
         "category_id" : "A10003123507",
294
         "datetime" : "2020-12-17 00:00:00",
295
         "id" : "2020-12-17-A10003123507-A10003123509",
296
         "slot_id" : "A10003123509",
297
         "text" : "3 2020-2021 GARDERIE SOIR",
298
         "user_booking_status" : "not-booked"
299
      },
300
      {
301
         "category" : "COURS DE DANSE",
302
         "category_id" : "A10003132090",
303
         "datetime" : "2020-12-17 00:00:00",
304
         "id" : "2020-12-17-A10003132090-A10003132091",
305
         "slot_id" : "A10003132091",
306
         "text" : "COURS DE DANSE",
307
         "user_booking_status" : "not-booked"
308
      },
309
      {
310
         "category" : "MULTI ACCUEIL LES OLIVIERS",
311
         "category_id" : "A10000003840",
312
         "datetime" : "2020-12-18 00:00:00",
313
         "id" : "2020-12-18-A10000003840-A10000003844",
314
         "slot_id" : "A10000003844",
315
         "text" : "MULTI ACCUEIL LES OLIVIERS - Réguliers",
316
         "user_booking_status" : "not-booked"
317
      },
318
      {
319
         "category" : "MULTI ACCUEIL LES OLIVIERS",
320
         "category_id" : "A10000003840",
321
         "datetime" : "2020-12-18 00:00:00",
322
         "id" : "2020-12-18-A10000003840-A10000003845",
323
         "slot_id" : "A10000003845",
324
         "text" : "MULTI ACCUEIL LES OLIVIERS - Occasionnels",
325
         "user_booking_status" : "not-booked"
326
      },
327
      {
328
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
329
         "category_id" : "A10000006100",
330
         "datetime" : "2020-12-18 00:00:00",
331
         "id" : "2020-12-18-A10000006100-A10000006104",
332
         "slot_id" : "A10000006104",
333
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Réguliers",
334
         "user_booking_status" : "not-booked"
335
      },
336
      {
337
         "category" : "HALTE GARDERIE LES MAGNOLIAS",
338
         "category_id" : "A10000006100",
339
         "datetime" : "2020-12-18 00:00:00",
340
         "id" : "2020-12-18-A10000006100-A10000006105",
341
         "slot_id" : "A10000006105",
342
         "text" : "HALTE GARDERIE LES MAGNOLIAS - Occasionnels",
343
         "user_booking_status" : "not-booked"
344
      },
345
      {
346
         "category" : "1 2020-2021 GARDERIE MATIN",
347
         "category_id" : "A10003121692",
348
         "datetime" : "2020-12-18 00:00:00",
349
         "id" : "2020-12-18-A10003121692-A10003121694",
350
         "slot_id" : "A10003121694",
351
         "text" : "1 2020-2021 GARDERIE MATIN",
352
         "user_booking_status" : "booked"
353
      },
354
      {
355
         "category" : "2 2020-2021  RESTAURATION SCOLAIRE",
356
         "category_id" : "A10003123490",
357
         "datetime" : "2020-12-18 00:00:00",
358
         "id" : "2020-12-18-A10003123490-A10003123492",
359
         "slot_id" : "A10003123492",
360
         "text" : "2 2020-2021  RESTAURATION SCOLAIRE",
361
         "user_booking_status" : "booked"
362
      },
363
      {
364
         "category" : "3 2020-2021 GARDERIE SOIR",
365
         "category_id" : "A10003123507",
366
         "datetime" : "2020-12-18 00:00:00",
367
         "id" : "2020-12-18-A10003123507-A10003123509",
368
         "slot_id" : "A10003123509",
369
         "text" : "3 2020-2021 GARDERIE SOIR",
370
         "user_booking_status" : "not-booked"
371
      },
372
      {
373
         "category" : "COURS DE DANSE",
374
         "category_id" : "A10003132090",
375
         "datetime" : "2020-12-18 00:00:00",
376
         "id" : "2020-12-18-A10003132090-A10003132091",
377
         "slot_id" : "A10003132091",
378
         "text" : "COURS DE DANSE",
379
         "user_booking_status" : "not-booked"
380
      }
381
   ],
382
   "err" : 0
383
}
tests/test_maelis.py
5 5
import os
6 6
import pytest
7 7

  
8 8
from django.test import override_settings
9 9
from django.utils.dateparse import parse_date
10 10

  
11 11
from passerelle.apps.maelis.models import Maelis, Link
12 12
from passerelle.apps.maelis.utils import (
13
    get_school_year,  week_boundaries_datetimes,  month_range)
13
    get_school_year,  week_boundaries_datetimes,  month_range, decompose_event)
14 14

  
15 15
from passerelle.utils.jsonresponse import APIError
16 16

  
17 17
import utils
18 18

  
19 19
pytestmark = pytest.mark.django_db
20 20

  
21 21
TEST_BASE_DIR = os.path.join(os.path.dirname(__file__), 'data', 'maelis')
......
242 242
    ('2021-01-03', '2020-12-01', []),
243 243
])
244 244
def test_month_range(start, end, items):
245 245
    start = parse_date(start)
246 246
    end = parse_date(end)
247 247
    assert [x.strftime('%Y-%m-%d') for x in month_range(start, end)] == items
248 248

  
249 249

  
250
def test_decompose_event():
251
    resp = get_json_file('child_planning_before_decomposition')
252
    data = resp['data']
253
    assert len(data) == 43
254
    assert data[22]['text'] == 'JOURNEE'
255
    assert data[23]['text'] == 'MATIN'
256
    assert data[24]['text'] == 'MATIN ET REPAS'
257
    assert data[25]['text'] == 'APRES MIDI'
258
    assert not [x for x in data if x['text'] == 'REPAS']
259

  
260
    # unit is break down into its components
261
    assert [x['text'] for x in decompose_event(data[22])] == [
262
        'Matinée', 'Repas', 'Après-midi']
263
    assert [x['text'] for x in decompose_event(data[23])] == [
264
        'Matinée']
265
    assert [x['text'] for x in decompose_event(data[24])] == [
266
        'Matinée', 'Repas']
267
    assert [x['text'] for x in decompose_event(data[25])] == [
268
        'Après-midi']
269

  
270
    # child_planning function use a dict to remove dupplicated components
271
    data = {x['id']: x for e in data for x in decompose_event(e)}.values()
272
    assert len(data) == 42
273
    assert len([x for x in data if x['text'] == 'Repas']) == 1
274
    assert len([x for x in data if 'EO0001' in x['slot_id']]) == 3
275

  
276

  
250 277
@override_settings(TIME_ZONE='Europe/Paris')
278
@pytest.mark.parametrize('legacy, nb_events, nb_booked, response', [
279
    ('please', 43, 9, 'child_planning_before_decomposition'),
280
    ('', 42, 9, 'child_planning_after_decomposition'),
281
])
251 282
@mock.patch('passerelle.utils.Request.get')
252 283
@mock.patch('passerelle.utils.Request.post')
253
def test_get_child_planning(mocked_post, mocked_get,
284
def test_get_child_planning(mocked_post, mocked_get, legacy, nb_events, nb_booked, response,
254 285
                            family_service_wsdl, activity_service_wsdl, app, connector):
255 286
    mocked_get.side_effect = (
256 287
        utils.FakedResponse(
257 288
            content=family_service_wsdl,
258 289
            status_code=200,
259 290
            headers={'Content-Type': 'text/xml'}),
260 291
        utils.FakedResponse(
261 292
            content=activity_service_wsdl,
......
276 307
            status_code=200,
277 308
            headers={'Content-Type': 'text/xml'}),
278 309
        utils.FakedResponse(
279 310
            content=get_xml_file('child_planning_readChildMonthPlanningResponse.xml'),
280 311
            status_code=200,
281 312
            headers={'Content-Type': 'text/xml'})
282 313
    )
283 314
    Link.objects.create(resource=connector, family_id='3264', name_id='local')
284
    resp = app.get(
285
        '/maelis/test/child-planning?NameID=local&childID=21293&start_date=2020-12-19')
315
    url = '/maelis/test/child-planning?NameID=local&childID=21293&start_date=2020-12-19'
316
    url += '&legacy=' + legacy
317
    resp = app.get(url)
286 318
    data = resp.json['data']
287 319
    previous_event = {}
288 320
    for event in data:
289 321
        assert event['category']
290 322
        assert event['text']
291 323
        if previous_event:
292 324
            assert previous_event['id'] <= event['id']
293 325
        previous_event = event
294
    assert len(data) == 43
295
    assert len([s for s in data if s['user_booking_status'] == 'not-booked']) == 34
296
    assert len([s for s in data if s['user_booking_status'] == 'booked']) == 9
297
    assert resp.json == get_json_file('child_planning_before_decomposition')
326
    assert len(data) == nb_events
327
    assert len([s for s in data if s['user_booking_status'] == 'booked']) == nb_booked
328
    assert resp.json == get_json_file(response)
298
-