diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py index a984624c..14bf9746 100644 --- a/passerelle/contrib/toulouse_maelis/models.py +++ b/passerelle/contrib/toulouse_maelis/models.py @@ -529,6 +529,17 @@ class ToulouseMaelis(BaseResource, HTTPResource): data = serialize_object(response) return data + def get_basket_raw(self, family_id): + response = self.call( + 'Activity', + 'getFamilyBasket', + getFamilyBasketRequestBean={ + 'numFamily': family_id, + }, + ) + data = serialize_object(response) + return data + @endpoint( display_category='Famille', description='Liste des catégories', @@ -2521,6 +2532,125 @@ class ToulouseMaelis(BaseResource, HTTPResource): raise APIError(response['controlResult']['message']) return {'data': serialize_object(response)} + @endpoint( + display_category='Inscriptions', + description="Lecture du panier de la famille", + name='get-basket', + perm='can_access', + parameters={ + 'NameID': {'description': 'Publik NameID'}, + 'family_id': {'description': 'Numéro de DUI'}, + }, + ) + def get_basket(self, request, NameID=None, family_id=None): + family_id = family_id or self.get_link(NameID).family_id + return {'data': self.get_basket_raw(family_id)} + + @endpoint( + display_category='Inscriptions', + description="Prolonge la durée de vie du panier", + name='update-basket-time', + perm='can_access', + parameters={ + 'NameID': {'description': 'Publik NameID'}, + 'family_id': {'description': 'Numéro de DUI'}, + }, + methods=['post'], + ) + def update_basket_time(self, request, NameID=None, family_id=None): + family_id = family_id or self.get_link(NameID).family_id + basket = self.get_basket_raw(family_id) + if not basket or not basket.get('id'): + raise APIError("no basket on '%s' family" % family_id) + + self.call('Activity', 'updateBasketTime', idBasket=basket['id']) + return {'data': 'ok'} + + @endpoint( + display_category='Inscriptions', + description="Suppression d'une ligne du panier", + name='delete-basket-line', + perm='can_access', + parameters={ + 'NameID': {'description': 'Publik NameID'}, + 'family_id': {'description': 'Numéro de DUI'}, + 'line_id': {'description': 'Numéro de ligne du panier'}, + }, + methods=['post'], + ) + def delete_basket_line(self, request, line_id, NameID=None, family_id=None): + family_id = family_id or self.get_link(NameID).family_id + basket = self.get_basket_raw(family_id) + if not basket or not basket.get('id'): + raise APIError("no basket on '%s' family" % family_id) + for line in basket['lignes']: + if line['id'] == line_id: + break + else: + raise APIError("no '%s' basket line on '%s' family" % (line_id, family_id)) + + response = self.call( + 'Activity', + 'deletePersonUnitBasket', + deletePersonUnitBasketRequestBean={ + 'idBasketLine': line_id, + }, + ) + return {'data': serialize_object(response)} + + @endpoint( + display_category='Inscriptions', + description="Suppression du panier de la famille", + name='delete-basket', + perm='can_access', + parameters={ + 'NameID': {'description': 'Publik NameID'}, + 'family_id': {'description': 'Numéro de DUI'}, + }, + methods=['post'], + ) + def delete_basket(self, request, NameID=None, family_id=None): + family_id = family_id or self.get_link(NameID).family_id + basket = self.get_basket_raw(family_id) + if not basket or not basket.get('id'): + raise APIError("no basket on '%s' family" % family_id) + + self.call( + 'Activity', + 'deleteBasket', + deleteBasketRequestBean={ + 'idBasket': basket['id'], + 'idUtilisat': NameID or 'Middle-office', + }, + ) + return {'data': 'ok'} + + @endpoint( + display_category='Inscriptions', + description="Validation du panier de la famille", + name='validate-basket', + perm='can_access', + parameters={ + 'NameID': {'description': 'Publik NameID'}, + 'family_id': {'description': 'Numéro de DUI'}, + }, + methods=['post'], + ) + def validate_basket(self, request, NameID=None, family_id=None): + family_id = family_id or self.get_link(NameID).family_id + basket = self.get_basket_raw(family_id) + if not basket or not basket.get('id'): + raise APIError("no basket on '%s' family" % family_id) + + response = self.call( + 'Activity', + 'validateBasket', + validateBasketRequestBean={ + 'idBasket': basket['id'], + }, + ) + return {'data': serialize_object(response)} + class Link(models.Model): resource = models.ForeignKey(ToulouseMaelis, on_delete=models.CASCADE) diff --git a/tests/data/toulouse_maelis/R_delete_basket.xml b/tests/data/toulouse_maelis/R_delete_basket.xml new file mode 100644 index 00000000..d4d0fac4 --- /dev/null +++ b/tests/data/toulouse_maelis/R_delete_basket.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/toulouse_maelis/R_delete_person_unit_basket.xml b/tests/data/toulouse_maelis/R_delete_person_unit_basket.xml new file mode 100644 index 00000000..b8165319 --- /dev/null +++ b/tests/data/toulouse_maelis/R_delete_person_unit_basket.xml @@ -0,0 +1,70 @@ + + + + + + + 2023-01-30T00:42:48+01:00 + 2023-01-30T00:42:48+01:00 + 0 + S10053200723 + S10053183425 + + 2023-01-28T23:50:34+01:00 + S10053203105 + S10053203103 + S10053203104 + S10053200723 + + 2023-02-01T00:00:00+01:00 + 2023-06-30T00:00:00+02:00 + A10051141965 + S10053203103 + S10053203104 + A10053179226 + A10049327675 + A10051141970 + Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h + Centre Culturel ALBAN MINVILLE + Inscription 2ème semestre + + + 2014-04-01T00:00:00+02:00 + BART + NICO + 246711 + M + + + + 2023-01-26T17:39:40+01:00 + S10053200724 + S10053200721 + S10053200722 + S10053200723 + + 2022-09-01T00:00:00+02:00 + 2023-08-31T00:00:00+02:00 + A10051141965 + S10053200721 + S10053200722 + A10053179226 + A10049327675 + A10051141990 + Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h + Centre Culturel ALBAN MINVILLE + Inscription 1er semestre + + + 2014-04-01T00:00:00+02:00 + BART + NICO + 246711 + M + + + + + + + diff --git a/tests/data/toulouse_maelis/R_get_family_basket.xml b/tests/data/toulouse_maelis/R_get_family_basket.xml new file mode 100644 index 00000000..1bc9180a --- /dev/null +++ b/tests/data/toulouse_maelis/R_get_family_basket.xml @@ -0,0 +1,97 @@ + + + + + + + 2023-01-28T23:56:23+01:00 + 2023-01-28T23:56:23+01:00 + 0 + S10053200723 + S10053183425 + + 2023-01-28T23:56:23+01:00 + S10053203120 + S10053203118 + S10053203119 + S10053200723 + + 2023-02-20T00:00:00+01:00 + 2023-02-24T00:00:00+01:00 + A10053187065 + S10053203118 + S10053203119 + A10053179604 + A10049327667 + A10053187085 + Vacances Hivers 2023 + ALEX JANY + Semaine 1 + + + 2014-04-01T00:00:00+02:00 + BART + NICO + 246711 + M + + + + 2023-01-28T23:50:34+01:00 + S10053203105 + S10053203103 + S10053203104 + S10053200723 + + 2023-02-01T00:00:00+01:00 + 2023-06-30T00:00:00+02:00 + A10051141965 + S10053203103 + S10053203104 + A10053179226 + A10049327675 + A10051141970 + Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h + Centre Culturel ALBAN MINVILLE + Inscription 2ème semestre + + + 2014-04-01T00:00:00+02:00 + BART + NICO + 246711 + M + + + + 2023-01-26T17:39:40+01:00 + S10053200724 + S10053200721 + S10053200722 + S10053200723 + + 2022-09-01T00:00:00+02:00 + 2023-08-31T00:00:00+02:00 + A10051141965 + S10053200721 + S10053200722 + A10053179226 + A10049327675 + A10051141990 + Vitrail Fusing 1/2 Je Adultes 2022/2023 - Mardi 14h-17h + Centre Culturel ALBAN MINVILLE + Inscription 1er semestre + + + 2014-04-01T00:00:00+02:00 + BART + NICO + 246711 + M + + + + + + + diff --git a/tests/data/toulouse_maelis/R_get_family_basket_empty.xml b/tests/data/toulouse_maelis/R_get_family_basket_empty.xml new file mode 100644 index 00000000..85bfc153 --- /dev/null +++ b/tests/data/toulouse_maelis/R_get_family_basket_empty.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/data/toulouse_maelis/R_update_basket_time.xml b/tests/data/toulouse_maelis/R_update_basket_time.xml new file mode 100644 index 00000000..282e50ce --- /dev/null +++ b/tests/data/toulouse_maelis/R_update_basket_time.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/toulouse_maelis/R_validate_basket.xml b/tests/data/toulouse_maelis/R_validate_basket.xml new file mode 100644 index 00000000..1ae30f1a --- /dev/null +++ b/tests/data/toulouse_maelis/R_validate_basket.xml @@ -0,0 +1,12 @@ + + + + + + S10053183425 + S10053203103 + S10053200721 + + + + diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py index 04003f5f..ca92f323 100644 --- a/tests/test_toulouse_maelis.py +++ b/tests/test_toulouse_maelis.py @@ -5740,3 +5740,205 @@ def test_add_person_basket_subscription_not_linked_error(con, app): resp = app.post_json(url + '?NameID=local', params=params) assert resp.json['err'] == 'not-linked' assert resp.json['err_desc'] == 'User not linked to family' + + +def test_get_basket(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + url = get_endpoint('get-basket') + + resp = app.get(url + '?family_id=311352') + assert resp.json['err'] == 0 + Link.objects.create(resource=con, family_id='311352', name_id='local') + + resp = app.get(url + '?NameID=local') + assert resp.json['err'] == 0 + data = resp.json['data'] + assert len(data['lignes']) == 3 + del data['lignes'][2] + del data['lignes'][1] + assert data == { + 'dateAdd': '2023-01-28T23:56:23+01:00', + 'dateMaj': '2023-01-28T23:56:23+01:00', + 'delai': 0, + 'id': 'S10053200723', + 'idFam': 'S10053183425', + 'lignes': [ + { + 'datEchn': None, + 'dateMaj': '2023-01-28T23:56:23+01:00', + 'id': 'S10053203120', + 'idIns': 'S10053203118', + 'idInsLieu': 'S10053203119', + 'idPanier': 'S10053200723', + 'inscription': { + 'dateDeb': '2023-02-20T00:00:00+01:00', + 'dateFin': '2023-02-24T00:00:00+01:00', + 'idAct': 'A10053187065', + 'idInsAct': 'S10053203118', + 'idInsLieu': 'S10053203119', + 'idLieu': 'A10053179604', + 'idRegie': 'A10049327667', + 'idUnit': 'A10053187085', + 'libAct': 'Vacances Hivers 2023', + 'libLieu': 'ALEX JANY', + 'libUnit': 'Semaine 1', + }, + 'montant': None, + 'personneInfo': { + 'dateBirth': '2014-04-01T00:00:00+02:00', + 'firstname': 'BART', + 'lastname': 'NICO', + 'numPerson': 246711, + 'sexe': 'M', + }, + 'prixUnit': None, + 'qte': None, + }, + ], + } + + +def test_get_basket_not_linked_error(con, app): + url = get_endpoint('get-basket') + resp = app.get(url + '?NameID=local') + assert resp.json['err'] == 'not-linked' + assert resp.json['err_desc'] == 'User not linked to family' + + +def test_update_basket_time(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + activity_service.add_soap_response('updateBasketTime', get_xml_file('R_update_basket_time.xml')) + url = get_endpoint('update-basket-time') + + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 0 + Link.objects.create(resource=con, family_id='311352', name_id='local') + + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 0 + assert resp.json['data'] == 'ok' + + +def test_update_basket_time_not_linked_error(con, app): + url = get_endpoint('update-basket-time') + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 'not-linked' + assert resp.json['err_desc'] == 'User not linked to family' + + +def test_update_basket_time_basket_not_found(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml')) + url = get_endpoint('update-basket-time') + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == "no basket on '311352' family" + + +def test_delete_basket_line(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + activity_service.add_soap_response( + 'deletePersonUnitBasket', get_xml_file('R_delete_person_unit_basket.xml') + ) + url = get_endpoint('delete-basket-line') + + resp = app.post(url + '?family_id=311352&line_id=S10053203120') + assert resp.json['err'] == 0 + Link.objects.create(resource=con, family_id='311352', name_id='local') + + resp = app.post(url + '?NameID=local&line_id=S10053203120') + assert resp.json['err'] == 0 + assert len(resp.json['data']['lignes']) == 2 + assert 'S10053203120' not in [x['id'] for x in resp.json['data']['lignes']] + + +def test_delete_basket_line_not_linked_error(con, app): + url = get_endpoint('delete-basket-line') + resp = app.post(url + '?NameID=local&line_id=S10053203120') + assert resp.json['err'] == 'not-linked' + assert resp.json['err_desc'] == 'User not linked to family' + + +def test_update_basket_line_basket_not_found(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml')) + url = get_endpoint('delete-basket-line') + resp = app.post(url + '?family_id=311352&line_id=S10053203120') + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == "no basket on '311352' family" + + +def test_delete_basket_line_line_not_found(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + url = get_endpoint('delete-basket-line') + resp = app.post(url + '?family_id=311352&line_id=plop') + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == "no 'plop' basket line on '311352' family" + + +def test_delete_basket(activity_service, con, app): + def request_check(request): + assert request.idUtilisat in ('local', 'Middle-office') + + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + activity_service.add_soap_response( + 'deleteBasket', + get_xml_file('R_delete_basket.xml'), + request_check=request_check, + ) + url = get_endpoint('delete-basket') + + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 0 + Link.objects.create(resource=con, family_id='311352', name_id='local') + + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 0 + assert resp.json['data'] == 'ok' + + +def test_delete_basket_not_linked_error(con, app): + url = get_endpoint('delete-basket') + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 'not-linked' + assert resp.json['err_desc'] == 'User not linked to family' + + +def test_delete_basket_not_found(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml')) + url = get_endpoint('delete-basket') + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == "no basket on '311352' family" + + +def test_validate_basket(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml')) + activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml')) + url = get_endpoint('validate-basket') + + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 0 + Link.objects.create(resource=con, family_id='311352', name_id='local') + + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 0 + assert resp.json['data'] == { + 'idFam': 'S10053183425', + 'idFactureLst': [], + 'idInsLst': ['S10053203103', 'S10053200721'], + 'paramUrlReglement': [], + } + + +def test_validate_basket_not_linked_error(con, app): + url = get_endpoint('validate-basket') + resp = app.post(url + '?NameID=local') + assert resp.json['err'] == 'not-linked' + assert resp.json['err_desc'] == 'User not linked to family' + + +def test_validate_basket_not_found(activity_service, con, app): + activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml')) + url = get_endpoint('validate-basket') + resp = app.post(url + '?family_id=311352') + assert resp.json['err'] == 1 + assert resp.json['err_desc'] == "no basket on '311352' family"