0004-maelis-decompose-units-related-to-moments-of-the-day.patch
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 |
- |