From ac693476b75d10186a730b32f9ddf87d54f94255 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 | 72 +++++++++++++++++++++- passerelle/contrib/agoraplus/normalize.py | 10 +++ .../passerelle/contrib/agoraplus/detail.html | 41 ++++++++++++ passerelle/contrib/agoraplus/urls.py | 18 ++++++ passerelle/contrib/agoraplus/views.py | 44 +++++++++++++ 5 files changed, 184 insertions(+), 1 deletion(-) diff --git a/passerelle/contrib/agoraplus/models.py b/passerelle/contrib/agoraplus/models.py index 7d43f2d..8b0500b 100644 --- a/passerelle/contrib/agoraplus/models.py +++ b/passerelle/contrib/agoraplus/models.py @@ -87,6 +87,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 +789,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 +817,59 @@ class AgoraPlus(BaseResource): return [] return [normalize_school_enrollment(e) for e in enrollments] + def get_periscol_enrollments(self, child, service, name_id=None, date=None): + if name_id and not self.is_child_in_name_id_family(name_id=name_id): + raise AgoraAPIError('child not in this family') + + url = 'children/%s/inscriptions_periscol/' % child + if service: + url += '?p_id_service=' + service + if date: + url += '&%s' % urlencode({'p_date': date}) + with wrap_agora_periscol(self.request(url), + 'to get periscol enrollments') as enrollments: + 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: + return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']] + + def get_periscol_child_enrollment_planning(self, child_id, enrollment_id, which=-1, name_id=None, + start_date=None, end_date=None): + if name_id and not self.is_child_in_name_id_family(name_id=name_id): + raise AgoraAPIError('child not in this family') + + url = 'children/%s/inscriptions_periscol/%s/planning/?reserved_day=%s' % (child_id, enrollment_id, which) + 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: + return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']] + + def create_periscol_reservation(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 = 'reservations_periscol/%s/reservations/' % enrollment_id + with wrap_agora_periscol(self.request(url), + 'to get periscol enrollment reservations') as reservations: + return [{'id': u'%s' % r['ID'], 'text': r['DAY']} 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'), + 'to delete periscol reservation') as result: + return result + def get_invoices(self, login): if not login: # unlinked account return [] @@ -878,6 +941,13 @@ class AgoraPlus(BaseResource): return adult['original_id'] raise ObjectDoesNotExist(_('adult not in Agora+')) + def is_child_in_name_id_family(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..b292170 100644 --- a/passerelle/contrib/agoraplus/normalize.py +++ b/passerelle/contrib/agoraplus/normalize.py @@ -366,3 +366,13 @@ 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['ACTIVITY']['ID'], + 'text': enrollment['ACTIVITY']['DESCRIPTION'], + 'start_date': enrollment['START_DATE'], + 'end_date': enrollment['END_DATE']} + +def normalize_periscol_enrollment_planning(planning): + text = '%s (%s-%s)' % (planning['DAY'], planning['START_TIME'], planning['END_TIME']) + return {'id': planning['DAY'], 'text': text} diff --git a/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html b/passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html index cb59569..00a5eb7 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..e713016 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-]+)/(?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/(?P[\w-]+)/$', + 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 b48b6e2..f24d638 100644 --- a/passerelle/contrib/agoraplus/views.py +++ b/passerelle/contrib/agoraplus/views.py @@ -506,6 +506,50 @@ class NurseryEnrollmentResultView(DetailView): return self.object.get_nursery_enrollment_result(enroll_id) +class PeriscolChildEnrollmentsView(DetailView): + def get_data(self, request, child_id, service_id, *args, **kwargs): + return self.object.get_periscol_enrollments(child_id, 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, which, *args, **kwargs): + return self.object.get_periscol_child_enrollment_planning(child_id, enrollment_id, which, request.GET.get('NameID')) + + +class PeriscolAddReservationView(DetailView): + @method_decorator(csrf_exempt) + def dispatch(self, *args, **kwargs): + return super(PeriscolAddReservationView, self).dispatch(*args, **kwargs) + + @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.2