From 806f6f4bcdd5e77223e988f8816c685f5cf5509b Mon Sep 17 00:00:00 2001 From: Serghei Date: Fri, 7 Jul 2017 11:02:01 +0200 Subject: [PATCH] agoraplus: add periscol inscriptions endpoints (#17429) --- passerelle/contrib/agoraplus/models.py | 83 +++++++++++++++++++++- passerelle/contrib/agoraplus/normalize.py | 18 +++++ .../passerelle/contrib/agoraplus/detail.html | 41 +++++++++++ passerelle/contrib/agoraplus/urls.py | 18 +++++ passerelle/contrib/agoraplus/views.py | 47 ++++++++++++ 5 files changed, 205 insertions(+), 2 deletions(-) diff --git a/passerelle/contrib/agoraplus/models.py b/passerelle/contrib/agoraplus/models.py index 7d43f2d..a2e0ec6 100644 --- a/passerelle/contrib/agoraplus/models.py +++ b/passerelle/contrib/agoraplus/models.py @@ -34,7 +34,8 @@ from passerelle.utils.jsonresponse import APIError from .normalize import normalize_reference, normalize_family, \ normalize_school, normalize_person, denormalize_date, PROVISIONING_DOMAIN, \ normalize_invoice, normalize_planning, normalize_date, normalize_nursery_enroll_results, \ - normalize_school_enrollment + normalize_school_enrollment, normalize_periscol_enrollment, \ + normalize_periscol_enrollment_planning, normalize_periscol_enrollment_reservation from .finalize import finalize_family from .agoraize import agoraize_family, agoraize_child, agoraize_contact, \ agoraize_address @@ -87,6 +88,16 @@ def wrap_agora_dict(response, msg): def wrap_agora_array(response, msg): return wrap_agora(response, msg, expected_type=list) +@contextmanager +def wrap_agora_periscol(response, msg): + with wrap_agora_dict(response, msg): + if response['TYPE_RESULT'] == 1: + yield response['DATA'] + elif response['TYPE_RESULT'] == -1: + yield [] + else: + raise AgoraAPIError('failure %s: %r(%r)' % (msg, response['ERROR']['ID'], response['ERROR']['MESSAGE'])) + class AgoraPlus(BaseResource): url = models.CharField(max_length=128, blank=False, @@ -779,7 +790,7 @@ class AgoraPlus(BaseResource): if child_id.startswith('sas_'): return [] - with wrap_agora_array(self.request('enfants/%s/inscriptions_pe/' % child_id), + with wrap_agora_array(self.request('enfants/%s/inscriptions_pe/' % child_id), 'to get plannings') as regs: plannings = [] now = datetime.now() @@ -807,6 +818,67 @@ class AgoraPlus(BaseResource): return [] return [normalize_school_enrollment(e) for e in enrollments] + def get_periscol_enrollments(self, child_id, service_id=7, name_id=None, date=None): + if name_id and not self.is_child_in_name_id_family(child, name_id): + raise AgoraAPIError('child not in this family') + + url = 'children/%s/inscriptions_periscol/' % child_id + if service_id: + url += '?p_id_service=' + service_id + if date: + url += '&%s' % urlencode({'p_date': date}) + with wrap_agora_periscol(self.request(url), + 'to get periscol enrollments') as enrollments: + if not isinstance(enrollments, dict): + return [] + return [normalize_periscol_enrollment(e) for e in enrollments['INSCRIPTION_INFO']] + + def get_periscol_enrollment_planning(self, enrollment_id): + url = 'activities/%s/planning/' % enrollment_id + with wrap_agora_periscol(self.request(url), + 'to get periscol enrollment planning') as planning: + if not isinstance(planning, dict): + return [] + return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']] + + def get_periscol_child_enrollment_planning(self, child_id, enrollment_id, reserved_day=-1, name_id=None, + start_date=None, end_date=None): + if name_id and not self.is_child_in_name_id_family(child_id, name_id): + raise AgoraAPIError('child not in this family') + + url = 'children/%s/inscriptions_periscol/%s/planning/?reserved_day=%s' % (child_id, enrollment_id, reserved_day) + if start_date and end_date: + url += '&%s' % urlencode((('start_date', start_date), ('end_date', end_date))) + with wrap_agora_periscol(self.request(url), + 'to get periscol child enrollment planning') as planning: + if not isinstance(planning, dict): + return [] + return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']] + + def create_periscol_reservation(self, enrollment_id, date, tarif_id, majored): + url = 'reservations_periscol/' + data = {'ID_INSCRIPTION': enrollment_id, + 'DAY': date, + 'ID_DEF_TARIF': tarif_id, + 'MAJORED': majored} + with wrap_agora_periscol(self.request(url, json=data), 'to add reservation') as reservation_add_result: + return reservation_add_result + + def get_periscol_enrollment_reservations(self, enrollment_id): + url = 'inscriptions_periscol/%s/reservations/' % enrollment_id + with wrap_agora_periscol(self.request(url), + 'to get periscol enrollment reservations') as reservations: + if not isinstance(reservations, dict): + return [] + return [normalize_periscol_enrollment_reservation(r) for r in reservations['RESERVATION_LIST']] + + def delete_periscol_enrollment_reservation(self, reservation_id): + url = 'reservations_periscol/' + data = {"ID": int(reservation_id)} + with wrap_agora_periscol(self.request(url, method='delete', json=data), + 'to delete periscol reservation') as result: + return result + def get_invoices(self, login): if not login: # unlinked account return [] @@ -878,6 +950,13 @@ class AgoraPlus(BaseResource): return adult['original_id'] raise ObjectDoesNotExist(_('adult not in Agora+')) + def is_child_in_name_id_family(self, child_id, name_id): + family = self.get_family(name_id=name_id) + for child in family['children']: + if child_id == child['id']: + return True + return False + def update_phone_numbers(self, login, name_id, adult_id, new_phone_number, new_cellphone_number): family = self.get_agoraplus_family(login, raise_error=True) diff --git a/passerelle/contrib/agoraplus/normalize.py b/passerelle/contrib/agoraplus/normalize.py index a4c25b1..00fdb81 100644 --- a/passerelle/contrib/agoraplus/normalize.py +++ b/passerelle/contrib/agoraplus/normalize.py @@ -366,3 +366,21 @@ def normalize_school_enrollment(enrollment): 'text': '%s, %s / %s, %s' % (child_fullname, school['name'], enrollment_level['name'], year['name']), } + +def normalize_periscol_enrollment(enrollment): + return {'id': u'%s' % enrollment['ID'], + 'text': enrollment['ACTIVITY']['DESCRIPTION'], + 'url': '/periscol/enrollment/%s/planning/' % enrollment['ID'], + 'start_date': enrollment['START_DATE'], + 'end_date': enrollment['END_DATE']} + +def normalize_periscol_enrollment_planning(planning): + # remove hour from planning date to be able to format it + date, hour = planning['DAY'].split('T') + text = '%s (%s-%s)' % (denormalize_date(date), planning['START_TIME'], planning['END_TIME']) + return {'id': planning['DAY'], 'text': text} + +def normalize_periscol_enrollment_reservation(reservation): + # remove hour from planning date to be able to format it + date, hour = reservation['DAY'].split('T') + return {'id': str(reservation['ID']), 'text': denormalize_date(date)} diff --git a/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html b/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html index cb59569..441d90d 100644 --- a/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html +++ b/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html @@ -203,6 +203,47 @@ + +

{% trans 'Periscol enrollments' %}

+ {% endblock %} {% block security %} diff --git a/passerelle/contrib/agoraplus/urls.py b/passerelle/contrib/agoraplus/urls.py index bd6b31e..54c474e 100644 --- a/passerelle/contrib/agoraplus/urls.py +++ b/passerelle/contrib/agoraplus/urls.py @@ -114,4 +114,22 @@ urlpatterns = patterns('', url(r'^(?P[\w-]+)/regie/invoice/(?P[\w,-]+)/$', InvoiceView.as_view(), name='agoraplus-invoice'), url(r'^(?P[\w-]+)/regie/invoice/(?P[\w,-]+)/pdf/$', InvoicePDFView.as_view(), name='agoraplus-invoice-pdf'), url(r'^(?P[\w-]+)/document/?$', DocumentView.as_view(), name='agoraplus-document'), + url(r'^(?P[\w-]+)/periscol/enrollments/(?P[\w-]+)/$', + PeriscolChildEnrollmentsView.as_view(), + name='agoraplus-child-periscol-enrollments'), + url(r'^(?P[\w-]+)/periscol/enrollment/(?P[\w-]+)/planning/$', + PeriscolEnrollmentPlanningView.as_view(), + name='agoraplus-enrollment-planning'), + url(r'^(?P[\w-]+)/periscol/child/(?P[\w-]+)/enrollment/(?P[\w-]+)/planning/$', + PeriscolChildEnrollmentPlanningView.as_view(), + name='agoraplus-periscol-child-enrollment-planning'), + url(r'^(?P[\w-]+)/periscol/reservation/add/$', + PeriscolAddReservationView.as_view(), + name='agoraplus-periscol-add-reservation'), + url(r'^(?P[\w-]+)/periscol/reservations/(?P[\w-]+)/$', + PeriscolEnrollmentReservationsView.as_view(), + name='agoraplus-periscol-enrollment-reservations'), + url(r'^(?P[\w-]+)/periscol/reservation/(?P\d+)/delete/$', + PeriscolDeleteReservationView.as_view(), + name='agoraplus-periscol-reservation-delete') ) diff --git a/passerelle/contrib/agoraplus/views.py b/passerelle/contrib/agoraplus/views.py index b5f4741..45300ee 100644 --- a/passerelle/contrib/agoraplus/views.py +++ b/passerelle/contrib/agoraplus/views.py @@ -509,6 +509,53 @@ class NurseryEnrollmentResultView(DetailView): return self.object.get_nursery_enrollment_result(enroll_id) +class PeriscolChildEnrollmentsView(DetailView): + def get_data(self, request, child_id, *args, **kwargs): + return self.object.get_periscol_enrollments(child_id, request.GET.get('service_id'), + request.GET.get('NameID'), request.GET.get('date')) + +class PeriscolEnrollmentPlanningView(DetailView): + def get_data(self, request, enrollment_id, *args, **kwargs): + return self.object.get_periscol_enrollment_planning(enrollment_id) + + +class PeriscolChildEnrollmentPlanningView(DetailView): + def get_data(self, request, child_id, enrollment_id, *args, **kwargs): + return self.object.get_periscol_child_enrollment_planning(child_id, enrollment_id, + request.GET.get('reserved_day'), request.GET.get('NameID'), + request.GET.get('start_date'), request.GET.get('end_date')) + + +class PeriscolAddReservationView(DetailView): + @method_decorator(csrf_exempt) + def dispatch(self, *args, **kwargs): + return super(PeriscolAddReservationView, self).dispatch(*args, **kwargs) + + @utils.to_json() + @utils.protected_api('can_access') + def post(self, request, *args, **kwargs): + self.object = self.get_object() + try: + data = json.loads(request.body) + enrollment_id = int(data['enrollment_id']) + date = data['date'] + tarif_id = int(data['tarif_id']) + majored = data['majored'] + except (ValueError, TypeError, KeyError) as e: + return HttpResponseBadRequest() + return self.object.create_periscol_reservation(enrollment_id, date, tarif_id, majored) + + +class PeriscolEnrollmentReservationsView(DetailView): + def get_data(self, request, enrollment_id, *args, **kwargs): + return self.object.get_periscol_enrollment_reservations(enrollment_id) + + +class PeriscolDeleteReservationView(DetailView): + def get_data(self, request, reservation_id, *args, **kwargs): + return self.object.delete_periscol_enrollment_reservation(reservation_id) + + class InvoicesView(DetailView): def get_data(self, request, **kwargs): if not self.login: # unlinked account: no invoice -- 2.13.3