Projet

Général

Profil

0001-agoraplus-add-periscol-inscriptions-endpoints-17429.patch

Serghei Mihai, 21 juillet 2017 17:06

Télécharger (15,2 ko)

Voir les différences:

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(-)
passerelle/contrib/agoraplus/models.py
34 34
from .normalize import normalize_reference, normalize_family, \
35 35
        normalize_school, normalize_person, denormalize_date, PROVISIONING_DOMAIN, \
36 36
        normalize_invoice, normalize_planning, normalize_date, normalize_nursery_enroll_results, \
37
        normalize_school_enrollment
37
        normalize_school_enrollment, normalize_periscol_enrollment, \
38
        normalize_periscol_enrollment_planning, normalize_periscol_enrollment_reservation
38 39
from .finalize import finalize_family
39 40
from .agoraize import agoraize_family, agoraize_child, agoraize_contact, \
40 41
    agoraize_address
......
87 88
def wrap_agora_array(response, msg):
88 89
    return wrap_agora(response, msg, expected_type=list)
89 90

  
91
@contextmanager
92
def wrap_agora_periscol(response, msg):
93
    with wrap_agora_dict(response, msg):
94
        if response['TYPE_RESULT'] == 1:
95
            yield response['DATA']
96
        elif response['TYPE_RESULT'] == -1:
97
            yield []
98
        else:
99
            raise AgoraAPIError('failure %s: %r(%r)' % (msg, response['ERROR']['ID'], response['ERROR']['MESSAGE']))
100

  
90 101

  
91 102
class AgoraPlus(BaseResource):
92 103
    url = models.CharField(max_length=128, blank=False,
......
779 790
        if child_id.startswith('sas_'):
780 791
            return []
781 792

  
782
        with wrap_agora_array(self.request('enfants/%s/inscriptions_pe/' % child_id), 
793
        with wrap_agora_array(self.request('enfants/%s/inscriptions_pe/' % child_id),
783 794
                              'to get plannings') as regs:
784 795
            plannings = []
785 796
            now = datetime.now()
......
807 818
                return []
808 819
            return [normalize_school_enrollment(e) for e in enrollments]
809 820

  
821
    def get_periscol_enrollments(self, child_id, service_id=7, name_id=None, date=None):
822
        if name_id and not self.is_child_in_name_id_family(child, name_id):
823
            raise AgoraAPIError('child not in this family')
824

  
825
        url = 'children/%s/inscriptions_periscol/' % child_id
826
        if service_id:
827
            url += '?p_id_service=' + service_id
828
            if date:
829
                url += '&%s' % urlencode({'p_date': date})
830
        with wrap_agora_periscol(self.request(url),
831
                        'to get periscol enrollments') as enrollments:
832
            if not isinstance(enrollments, dict):
833
                return []
834
            return [normalize_periscol_enrollment(e) for e in enrollments['INSCRIPTION_INFO']]
835

  
836
    def get_periscol_enrollment_planning(self, enrollment_id):
837
        url = 'activities/%s/planning/' % enrollment_id
838
        with wrap_agora_periscol(self.request(url),
839
                        'to get periscol enrollment planning') as planning:
840
            if not isinstance(planning, dict):
841
                return []
842
            return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']]
843

  
844
    def get_periscol_child_enrollment_planning(self, child_id, enrollment_id, reserved_day=-1, name_id=None,
845
                            start_date=None, end_date=None):
846
        if name_id and not self.is_child_in_name_id_family(child_id, name_id):
847
            raise AgoraAPIError('child not in this family')
848

  
849
        url = 'children/%s/inscriptions_periscol/%s/planning/?reserved_day=%s' % (child_id, enrollment_id, reserved_day)
850
        if start_date and end_date:
851
            url += '&%s' % urlencode((('start_date', start_date), ('end_date', end_date)))
852
        with wrap_agora_periscol(self.request(url),
853
                        'to get periscol child enrollment planning') as planning:
854
            if not isinstance(planning, dict):
855
                return []
856
            return [normalize_periscol_enrollment_planning(p) for p in planning['PLANNING_DAYS']]
857

  
858
    def create_periscol_reservation(self, enrollment_id, date, tarif_id, majored):
859
        url = 'reservations_periscol/'
860
        data = {'ID_INSCRIPTION': enrollment_id,
861
                'DAY': date,
862
                'ID_DEF_TARIF': tarif_id,
863
                'MAJORED': majored}
864
        with wrap_agora_periscol(self.request(url, json=data), 'to add reservation') as reservation_add_result:
865
            return reservation_add_result
866

  
867
    def get_periscol_enrollment_reservations(self, enrollment_id):
868
        url = 'inscriptions_periscol/%s/reservations/' % enrollment_id
869
        with wrap_agora_periscol(self.request(url),
870
                        'to get periscol enrollment reservations') as reservations:
871
            if not isinstance(reservations, dict):
872
                return []
873
            return [normalize_periscol_enrollment_reservation(r) for r in reservations['RESERVATION_LIST']]
874

  
875
    def delete_periscol_enrollment_reservation(self, reservation_id):
876
        url = 'reservations_periscol/'
877
        data = {"ID": int(reservation_id)}
878
        with wrap_agora_periscol(self.request(url, method='delete', json=data),
879
                                 'to delete periscol reservation') as result:
880
            return result
881

  
810 882
    def get_invoices(self, login):
811 883
        if not login: # unlinked account
812 884
            return []
......
878 950
                return adult['original_id']
879 951
        raise ObjectDoesNotExist(_('adult not in Agora+'))
880 952

  
953
    def is_child_in_name_id_family(self, child_id, name_id):
954
        family = self.get_family(name_id=name_id)
955
        for child in family['children']:
956
            if child_id == child['id']:
957
                return True
958
        return False
959

  
881 960
    def update_phone_numbers(self, login, name_id, adult_id,
882 961
                             new_phone_number, new_cellphone_number):
883 962
        family = self.get_agoraplus_family(login, raise_error=True)
passerelle/contrib/agoraplus/normalize.py
366 366
            'text': '%s, %s / %s, %s' % (child_fullname, school['name'],
367 367
                            enrollment_level['name'], year['name']),
368 368
            }
369

  
370
def normalize_periscol_enrollment(enrollment):
371
    return {'id': u'%s' % enrollment['ID'],
372
            'text': enrollment['ACTIVITY']['DESCRIPTION'],
373
            'url': '/periscol/enrollment/%s/planning/' % enrollment['ID'],
374
            'start_date': enrollment['START_DATE'],
375
            'end_date': enrollment['END_DATE']}
376

  
377
def normalize_periscol_enrollment_planning(planning):
378
    # remove hour from planning date to be able to format it
379
    date, hour = planning['DAY'].split('T')
380
    text = '%s (%s-%s)' % (denormalize_date(date), planning['START_TIME'], planning['END_TIME'])
381
    return {'id': planning['DAY'], 'text': text}
382

  
383
def normalize_periscol_enrollment_reservation(reservation):
384
    # remove hour from planning date to be able to format it
385
    date, hour = reservation['DAY'].split('T')
386
    return {'id': str(reservation['ID']), 'text': denormalize_date(date)}
passerelle/contrib/agoraplus/templates/passerelle/contrib/agoraplus/detail.html
203 203
    </ul>
204 204
</li>
205 205
</ul>
206

  
207
<h4>{% trans 'Periscol enrollments' %}</h4>
208
<ul>
209
  <li>
210
    {% url 'agoraplus-child-periscol-enrollments' slug=object.slug child_id='child_id' as periscol_enrollments_url %}
211
    {% trans 'Get child periscol enrollments:' %} <a href="{{ periscol_enrollments_url }}">{{ site_base_uri }}{{ periscol_enrollments_url }}?service_id=7&NameID=…&date=2017-01-01</a>
212
  </li>
213
  <li>
214
    {% url 'agoraplus-enrollment-planning' slug=object.slug enrollment_id='enrollment_id' as periscol_enrollment_planning_url %}
215
    {% trans 'Get enrollment planning:' %} <a href="{{ periscol_enrollment_planning_url }}">{{ site_base_uri }}{{ periscol_enrollment_planning_url }}</a>
216
  </li>
217
  <li>
218
    {% url 'agoraplus-periscol-child-enrollment-planning' slug=object.slug child_id='child_id' enrollment_id='enrollment_id' as periscol_child_enrollment_planning_url %}
219
    {% trans 'Get child enrollment planning:' %} <a href="{{ periscol_child_enrollment_planning_url }}">{{ site_base_uri }}{{ periscol_child_enrollment_planning_url }}?NameID=…&reserved_day=-1&start_date=2017-01-01&end_date=2017-12-31</a> —
220
    {% trans 'days:' %}
221
    <ul>
222
      <li><em>-1</em>: {% trans "all days" %}</li>
223
      <li><em>0</em>: {% trans "not reserved days" %}</li>
224
      <li><em>1</em>: {% trans "reserved days" %}</li>
225
    </ul>
226
  </li>
227
  <li>
228
    {% url 'agoraplus-periscol-add-reservation' slug=object.slug as periscol_add_reservation_url %}
229
    {% trans 'Add periscol reservation:' %} POST <a href="{{ periscol_add_reservation_url }}">{{ site_base_uri }}{{ periscol_add_reservation_url }}</a> —
230
    {% trans 'JSON payload:' %}
231
    <ul>
232
      <li><em>enrollment_id</em> {% trans 'enrollment id for a child' %}</li>
233
      <li><em>date</em> {% trans 'a date of enrollment planning' %}</li>
234
      <li><em>tarif_id</em> {% trans 'tarif identifier for this reservation' %}</li>
235
      <li><em>majored</em> {% trans 'boolean specifying if the tarif is majored' %}</li>
236
    </ul>
237
  </li>
238
  <li>
239
    {% url 'agoraplus-periscol-enrollment-reservations' slug=object.slug enrollment_id='enrollment_id' as periscol_enrollment_reservations_url %}
240
    {% trans 'Get enrollment reservations:' %} <a href="{{ periscol_enrollment_reservations_url }}">{{ site_base_uri }}{{ periscol_enrollment_reservations_url }}</a>
241
  </li>
242
  <li>
243
    {% url 'agoraplus-periscol-reservation-delete' slug=object.slug reservation_id=4242 as periscol_enrollment_reservation_delete_url %}
244
    {% trans 'Delete enrollment reservation:' %} <a href="{{ periscol_enrollment_reservation_delete_url }}">{{ site_base_uri }}{{ periscol_enrollment_reservation_delete_url }}</a>
245
  </li>
246
</ul>
206 247
{% endblock %}
207 248

  
208 249
{% block security %}
passerelle/contrib/agoraplus/urls.py
114 114
    url(r'^(?P<slug>[\w-]+)/regie/invoice/(?P<invoice_id>[\w,-]+)/$', InvoiceView.as_view(), name='agoraplus-invoice'),
115 115
    url(r'^(?P<slug>[\w-]+)/regie/invoice/(?P<invoice_id>[\w,-]+)/pdf/$', InvoicePDFView.as_view(), name='agoraplus-invoice-pdf'),
116 116
    url(r'^(?P<slug>[\w-]+)/document/?$', DocumentView.as_view(), name='agoraplus-document'),
117
    url(r'^(?P<slug>[\w-]+)/periscol/enrollments/(?P<child_id>[\w-]+)/$',
118
        PeriscolChildEnrollmentsView.as_view(),
119
        name='agoraplus-child-periscol-enrollments'),
120
    url(r'^(?P<slug>[\w-]+)/periscol/enrollment/(?P<enrollment_id>[\w-]+)/planning/$',
121
        PeriscolEnrollmentPlanningView.as_view(),
122
        name='agoraplus-enrollment-planning'),
123
    url(r'^(?P<slug>[\w-]+)/periscol/child/(?P<child_id>[\w-]+)/enrollment/(?P<enrollment_id>[\w-]+)/planning/$',
124
        PeriscolChildEnrollmentPlanningView.as_view(),
125
        name='agoraplus-periscol-child-enrollment-planning'),
126
    url(r'^(?P<slug>[\w-]+)/periscol/reservation/add/$',
127
        PeriscolAddReservationView.as_view(),
128
        name='agoraplus-periscol-add-reservation'),
129
    url(r'^(?P<slug>[\w-]+)/periscol/reservations/(?P<enrollment_id>[\w-]+)/$',
130
        PeriscolEnrollmentReservationsView.as_view(),
131
        name='agoraplus-periscol-enrollment-reservations'),
132
    url(r'^(?P<slug>[\w-]+)/periscol/reservation/(?P<reservation_id>\d+)/delete/$',
133
        PeriscolDeleteReservationView.as_view(),
134
        name='agoraplus-periscol-reservation-delete')
117 135
)
passerelle/contrib/agoraplus/views.py
509 509
        return self.object.get_nursery_enrollment_result(enroll_id)
510 510

  
511 511

  
512
class PeriscolChildEnrollmentsView(DetailView):
513
    def get_data(self, request, child_id, *args, **kwargs):
514
        return self.object.get_periscol_enrollments(child_id, request.GET.get('service_id'),
515
                                    request.GET.get('NameID'), request.GET.get('date'))
516

  
517
class PeriscolEnrollmentPlanningView(DetailView):
518
    def get_data(self, request, enrollment_id, *args, **kwargs):
519
        return self.object.get_periscol_enrollment_planning(enrollment_id)
520

  
521

  
522
class PeriscolChildEnrollmentPlanningView(DetailView):
523
    def get_data(self, request, child_id, enrollment_id, *args, **kwargs):
524
        return self.object.get_periscol_child_enrollment_planning(child_id, enrollment_id,
525
                                request.GET.get('reserved_day'), request.GET.get('NameID'),
526
                                request.GET.get('start_date'), request.GET.get('end_date'))
527

  
528

  
529
class PeriscolAddReservationView(DetailView):
530
    @method_decorator(csrf_exempt)
531
    def dispatch(self, *args, **kwargs):
532
        return super(PeriscolAddReservationView, self).dispatch(*args, **kwargs)
533

  
534
    @utils.to_json()
535
    @utils.protected_api('can_access')
536
    def post(self, request, *args, **kwargs):
537
        self.object = self.get_object()
538
        try:
539
            data = json.loads(request.body)
540
            enrollment_id = int(data['enrollment_id'])
541
            date = data['date']
542
            tarif_id = int(data['tarif_id'])
543
            majored = data['majored']
544
        except (ValueError, TypeError, KeyError) as e:
545
            return HttpResponseBadRequest()
546
        return self.object.create_periscol_reservation(enrollment_id, date, tarif_id, majored)
547

  
548

  
549
class PeriscolEnrollmentReservationsView(DetailView):
550
    def get_data(self, request, enrollment_id, *args, **kwargs):
551
        return self.object.get_periscol_enrollment_reservations(enrollment_id)
552

  
553

  
554
class PeriscolDeleteReservationView(DetailView):
555
    def get_data(self, request, reservation_id, *args, **kwargs):
556
        return self.object.delete_periscol_enrollment_reservation(reservation_id)
557

  
558

  
512 559
class InvoicesView(DetailView):
513 560
    def get_data(self, request, **kwargs):
514 561
        if not self.login: # unlinked account: no invoice
515
-