0001-toulouse-axel-endpoint-to-get-bookable-years-44451.patch
passerelle/contrib/toulouse_axel/models.py | ||
---|---|---|
964 | 964 |
@endpoint( |
965 | 965 |
display_category='CAN-CLA', |
966 | 966 |
display_order=1, |
967 |
description=_("Get the list of reference years available for bookings"), |
|
968 |
perm='can_access', |
|
969 |
parameters={ |
|
970 |
'NameID': {'description': _('Publik ID')}, |
|
971 |
'pivot_date': {'description': _('Pivot date (format MM-DD). After this date, next year is available.')}, |
|
972 |
}) |
|
973 |
def clae_years(self, request, NameID, pivot_date): |
|
974 |
link = self.get_link(NameID) |
|
975 | ||
976 |
today = datetime.date.today() |
|
977 |
reference_year = utils.get_reference_year_from_date(today) |
|
978 | ||
979 |
# get pivot date |
|
980 |
try: |
|
981 |
pivot_date = datetime.datetime.strptime('%s-%s' % (reference_year, pivot_date), utils.json_date_format).date() |
|
982 |
except ValueError: |
|
983 |
raise APIError('bad date format, should be MM-DD', err_code='bad-request', http_status=400) |
|
984 |
# adjust pivot year |
|
985 |
if pivot_date.month <= 7: |
|
986 |
# between january and july, reference year is the year just before |
|
987 |
pivot_date = pivot_date.replace(year=reference_year + 1) |
|
988 | ||
989 |
data = [{ |
|
990 |
'id': 1, |
|
991 |
'text': '%s/%s' % (reference_year, reference_year + 1), |
|
992 |
'type': 'encours', |
|
993 |
'refdate': today.strftime(utils.json_date_format) |
|
994 |
}] |
|
995 |
if today < pivot_date: |
|
996 |
# date pivot not in the past, return only current year |
|
997 |
return {'data': data} |
|
998 |
children_activities = self.get_children_activities(dui=link.dui, reference_year=reference_year + 1) |
|
999 |
if not children_activities: |
|
1000 |
# no activities for next year, return only current year |
|
1001 |
return {'data': data} |
|
1002 |
try: |
|
1003 |
next_ref_date = today.replace(year=today.year + 1) |
|
1004 |
except ValueError: |
|
1005 |
# 02/29 ? |
|
1006 |
next_ref_date = today + datetime.timedelta(days=366) |
|
1007 |
# return also next year |
|
1008 |
data.append({ |
|
1009 |
'id': 2, |
|
1010 |
'text': '%s/%s' % (reference_year + 1, reference_year + 2), |
|
1011 |
'type': 'suivante', |
|
1012 |
'refdate': next_ref_date.strftime(utils.json_date_format) |
|
1013 |
}) |
|
1014 |
return {'data': data} |
|
1015 | ||
1016 |
@endpoint( |
|
1017 |
display_category='CAN-CLA', |
|
1018 |
display_order=2, |
|
967 | 1019 |
description=_("Get information about CLAE activities of all children for the year"), |
968 | 1020 |
perm='can_access', |
969 | 1021 |
parameters={ |
... | ... | |
986 | 1038 | |
987 | 1039 |
@endpoint( |
988 | 1040 |
display_category='CAN-CLA', |
989 |
display_order=2,
|
|
1041 |
display_order=3,
|
|
990 | 1042 |
description=_("Get the list of CLAE booked activities of a child, for a period"), |
991 | 1043 |
perm='can_access', |
992 | 1044 |
parameters={ |
... | ... | |
1059 | 1111 | |
1060 | 1112 |
@endpoint( |
1061 | 1113 |
display_category='CAN-CLA', |
1062 |
display_order=3,
|
|
1114 |
display_order=4,
|
|
1063 | 1115 |
description=_("Get possible days to book an activity of a child, for a period"), |
1064 | 1116 |
perm='can_access', |
1065 | 1117 |
parameters={ |
... | ... | |
1135 | 1187 | |
1136 | 1188 |
@endpoint( |
1137 | 1189 |
display_category='CAN-CLA', |
1138 |
display_order=4,
|
|
1190 |
display_order=5,
|
|
1139 | 1191 |
description=_("Get annual possible days to book an activity of a child"), |
1140 | 1192 |
perm='can_access', |
1141 | 1193 |
parameters={ |
... | ... | |
1179 | 1231 | |
1180 | 1232 |
@endpoint( |
1181 | 1233 |
display_category='CAN-CLA', |
1182 |
display_order=5,
|
|
1234 |
display_order=6,
|
|
1183 | 1235 |
description=_("Get booked days for an activity of a child, for a period"), |
1184 | 1236 |
perm='can_access', |
1185 | 1237 |
parameters={ |
... | ... | |
1195 | 1247 | |
1196 | 1248 |
@endpoint( |
1197 | 1249 |
display_category='CAN-CLA', |
1198 |
display_order=6,
|
|
1250 |
display_order=7,
|
|
1199 | 1251 |
description=_("CLAE/Cantine booking"), |
1200 | 1252 |
perm='can_access', |
1201 | 1253 |
parameters={ |
... | ... | |
1320 | 1372 | |
1321 | 1373 |
@endpoint( |
1322 | 1374 |
display_category='CAN-CLA', |
1323 |
display_order=7,
|
|
1375 |
display_order=8,
|
|
1324 | 1376 |
description=_("CLAE/Cantine annual booking"), |
1325 | 1377 |
perm='can_access', |
1326 | 1378 |
parameters={ |
passerelle/contrib/toulouse_axel/utils.py | ||
---|---|---|
210 | 210 |
def get_reference_year_from_date(booking_date): |
211 | 211 |
if booking_date.month <= 7: |
212 | 212 |
# between january and july, reference year is the year just before |
213 |
# (september) |
|
214 | 213 |
return booking_date.year - 1 |
215 | 214 |
return booking_date.year |
216 | 215 |
tests/test_toulouse_axel.py | ||
---|---|---|
2266 | 2266 |
} |
2267 | 2267 | |
2268 | 2268 | |
2269 |
def test_clae_years_endpoint_axel_error(app, resource): |
|
2270 |
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') |
|
2271 |
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation: |
|
2272 |
operation.side_effect = AxelError('FooBar') |
|
2273 |
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15') |
|
2274 |
assert resp.json['err_desc'] == "Axel error: FooBar" |
|
2275 |
assert resp.json['err'] == 'error' |
|
2276 | ||
2277 | ||
2278 |
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '15/06', '06']) |
|
2279 |
def test_clae_years_endpoint_bad_date_format(app, resource, value): |
|
2280 |
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') |
|
2281 |
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=%s' % value, status=400) |
|
2282 |
assert resp.json['err_desc'] == "bad date format, should be MM-DD" |
|
2283 |
assert resp.json['err'] == 'bad-request' |
|
2284 | ||
2285 | ||
2286 |
def test_clae_years_endpoint_no_result(app, resource): |
|
2287 |
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15') |
|
2288 |
assert resp.json['err_desc'] == "Person not found" |
|
2289 |
assert resp.json['err'] == 'not-found' |
|
2290 | ||
2291 | ||
2292 |
@pytest.mark.parametrize('today,pivot,next_year,next_date', [ |
|
2293 |
('2019-08-01', '08-01', True, '2020-08-01'), |
|
2294 |
('2019-08-01', '08-02', False, None), |
|
2295 |
('2020-07-31', '07-31', True, '2021-07-31'), |
|
2296 |
('2020-07-30', '07-31', False, None), |
|
2297 |
('2020-06-14', '06-15', False, None), |
|
2298 |
('2020-06-15', '06-15', True, '2021-06-15'), |
|
2299 |
('2020-06-16', '06-15', True, '2021-06-16'), |
|
2300 |
('2020-02-29', '02-01', True, '2021-03-01'), |
|
2301 |
]) |
|
2302 |
def test_clae_years_endpoint(app, resource, today, pivot, next_year, next_date): |
|
2303 |
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') |
|
2304 |
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml') |
|
2305 |
with open(filepath) as xml: |
|
2306 |
content = xml.read() |
|
2307 |
with mock_getdata(content, 'EnfantsActivites'): |
|
2308 |
with freezegun.freeze_time(today): |
|
2309 |
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=%s' % pivot) |
|
2310 |
assert resp.json['data'][0] == {'id': 1, 'text': '2019/2020', 'type': 'encours', 'refdate': today} |
|
2311 |
if next_year: |
|
2312 |
assert len(resp.json['data']) == 2 |
|
2313 |
assert resp.json['data'][1] == {'id': 2, 'text': '2020/2021', 'type': 'suivante', 'refdate': next_date} |
|
2314 |
else: |
|
2315 |
assert len(resp.json['data']) == 1 |
|
2316 | ||
2317 | ||
2318 |
@freezegun.freeze_time('2020-06-30') |
|
2319 |
def test_clae_years_endpoint_noactivities(app, resource): |
|
2320 |
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') |
|
2321 |
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_children_activities', return_value={}) as mock_activities: |
|
2322 |
resp = app.get('/toulouse-axel/test/clae_years?NameID=yyy&pivot_date=06-15') |
|
2323 |
assert mock_activities.call_args_list == [mock.call(dui='XXX', reference_year=2020)] |
|
2324 |
assert len(resp.json['data']) == 1 |
|
2325 |
# TODO check IRL |
|
2326 | ||
2327 | ||
2269 | 2328 |
def test_clae_children_activities_info_endpoint_axel_error(app, resource): |
2270 | 2329 |
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42') |
2271 | 2330 |
with mock.patch('passerelle.contrib.toulouse_axel.schemas.enfants_activites') as operation: |
2272 |
- |