toulouse_axel: booking_info endpoint (#39126)
This commit is contained in:
parent
bb4161fd22
commit
a1e17662bb
|
@ -211,6 +211,8 @@ form_paiement_dui = Operation('FormPaiementDui')
|
|||
ref_facture_a_payer = Operation('RefFactureAPayer')
|
||||
ref_facture_pdf = Operation('RefFacturePDF', prefix='')
|
||||
list_dui_factures = Operation('ListeDuiFacturesPayeesRecettees', request_root_element='LISTFACTURE')
|
||||
enfants_activites = Operation('EnfantsActivites', request_root_element='DUI')
|
||||
reservation_periode = Operation('ReservationPeriode')
|
||||
|
||||
|
||||
class ToulouseAxel(BaseResource):
|
||||
|
@ -882,6 +884,108 @@ class ToulouseAxel(BaseResource):
|
|||
'xml_response': e.xml_response})
|
||||
return {'data': True}
|
||||
|
||||
def get_child_activities(self, dui, reference_year, child_id):
|
||||
try:
|
||||
result = enfants_activites(self, {
|
||||
'DUI': {
|
||||
'IDDUI': dui,
|
||||
'ANNEEREFERENCE': str(reference_year),
|
||||
'TYPESACTIVITES': 'MAT,MIDI,SOIR,GARD',
|
||||
}
|
||||
})
|
||||
except AxelError as e:
|
||||
raise APIError(
|
||||
'Axel error: %s' % e,
|
||||
err_code='error',
|
||||
data={'xml_request': e.xml_request,
|
||||
'xml_response': e.xml_response})
|
||||
|
||||
child_activities_data = result.json_response['DATA']['PORTAIL']['DUI'].get('ENFANT', [])
|
||||
for child in child_activities_data:
|
||||
if child['IDPERSONNE'] == child_id:
|
||||
return child
|
||||
|
||||
raise APIError('Child not found', err_code='not-found')
|
||||
|
||||
@endpoint(
|
||||
description=_("Get information about CLAE booking"),
|
||||
perm='can_access',
|
||||
parameters={
|
||||
'NameID': {'description': _('Publik ID')},
|
||||
'idpersonne': {'description': _('Child ID')},
|
||||
'booking_date': {'description': _('Booking date')},
|
||||
})
|
||||
def clae_booking_info(self, request, NameID, idpersonne, booking_date):
|
||||
link = self.get_link(NameID)
|
||||
try:
|
||||
booking_date = datetime.datetime.strptime(booking_date, utils.json_date_format)
|
||||
except ValueError:
|
||||
raise APIError('bad date format', err_code='bad-request', http_status=400)
|
||||
|
||||
reference_year = utils.get_reference_year_from_date(booking_date)
|
||||
|
||||
# first get activities information for the child
|
||||
child_activities = self.get_child_activities(
|
||||
dui=link.dui,
|
||||
reference_year=reference_year,
|
||||
child_id=idpersonne)
|
||||
|
||||
# then get booking of the requested week for the child
|
||||
activity_ids = [act['IDACTIVITE'] for act in child_activities.get('ACTIVITE', [])]
|
||||
start_date, end_date = utils.get_week_dates_from_date(booking_date)
|
||||
activity_data = []
|
||||
for activity_id in activity_ids:
|
||||
activity_data.append({
|
||||
'IDACTIVITE': activity_id,
|
||||
'ANNEEREFERENCE': str(reference_year),
|
||||
'DATEDEBUT': start_date.strftime(utils.xml_date_format),
|
||||
'DATEDFIN': end_date.strftime(utils.xml_date_format),
|
||||
})
|
||||
try:
|
||||
data = reservation_periode(self, {'PORTAIL': {
|
||||
'DUI': {
|
||||
'IDDUI': link.dui,
|
||||
'ENFANT': {
|
||||
'IDPERSONNE': idpersonne,
|
||||
'ACTIVITE': activity_data,
|
||||
}
|
||||
}
|
||||
}})
|
||||
except AxelError as e:
|
||||
raise APIError(
|
||||
'Axel error: %s' % e,
|
||||
err_code='error',
|
||||
data={'xml_request': e.xml_request,
|
||||
'xml_response': e.xml_response})
|
||||
|
||||
child_booking = None
|
||||
for child in data.json_response['DATA']['PORTAIL']['DUI'].get('ENFANT', []):
|
||||
if child['IDPERSONNE'] == idpersonne:
|
||||
child_booking = child
|
||||
break
|
||||
if child_booking is None:
|
||||
# should not happen
|
||||
raise APIError('Child not found', err_code='not-found')
|
||||
|
||||
# build the response payload: add booking to activities information
|
||||
booking_days = {}
|
||||
for booking in child_booking.get('ACTIVITE', []):
|
||||
booking_days[booking['IDACTIVITE']] = {
|
||||
'raw_value': booking['JOUR'],
|
||||
'days': {
|
||||
'monday': utils.get_booking(booking['JOUR'][0]),
|
||||
'tuesday': utils.get_booking(booking['JOUR'][1]),
|
||||
'wednesday': utils.get_booking(booking['JOUR'][2]),
|
||||
'thursday': utils.get_booking(booking['JOUR'][3]),
|
||||
'friday': utils.get_booking(booking['JOUR'][4]),
|
||||
}
|
||||
}
|
||||
|
||||
for activity in child_activities.get('ACTIVITE', []):
|
||||
activity['booking'] = booking_days.get(activity['IDACTIVITE'], {})
|
||||
|
||||
return {'data': child_activities}
|
||||
|
||||
|
||||
class Link(models.Model):
|
||||
resource = models.ForeignKey(ToulouseAxel, on_delete=models.CASCADE)
|
||||
|
|
|
@ -122,3 +122,29 @@ def normalize_invoice(invoice, dui, historical=False, vendor_base=None):
|
|||
pay_limit_date = datetime.datetime.strptime(invoice['DATEECHEANCE'], '%Y-%m-%d').date()
|
||||
data['online_payment'] = data['amount'] > 0 and pay_limit_date >= datetime.date.today()
|
||||
return data
|
||||
|
||||
|
||||
def get_reference_year_from_date(booking_date):
|
||||
if booking_date.month <= 7:
|
||||
# between january and july, reference year is the year just before
|
||||
# (september)
|
||||
return booking_date.year - 1
|
||||
return booking_date.year
|
||||
|
||||
|
||||
def get_week_dates_from_date(booking_date):
|
||||
day = booking_date.weekday()
|
||||
# return monday and friday of the week
|
||||
return (
|
||||
booking_date - datetime.timedelta(days=day),
|
||||
booking_date + datetime.timedelta(days=4 - day)
|
||||
)
|
||||
|
||||
|
||||
def get_booking(value):
|
||||
# 0: no registration
|
||||
# 1: registration
|
||||
# 2: not applicable (example: GARDERIE is applicable only on wednesday)
|
||||
if value == '2':
|
||||
return None
|
||||
return value == '1'
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:all="urn:AllAxelTypes">
|
||||
|
||||
<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes" />
|
||||
|
||||
|
||||
<xsd:element name="IDDUI" type="all:IDENTREQUIREDType" />
|
||||
<xsd:element name="ANNEEREFERENCE" type="all:ANNEEType" />
|
||||
<xsd:element name="TYPESACTIVITES" type="xsd:string" />
|
||||
|
||||
|
||||
<xsd:element name="DUI">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDDUI" minOccurs="1" maxOccurs="1" />
|
||||
<xsd:element ref="ANNEEREFERENCE" minOccurs="1"
|
||||
maxOccurs="1" />
|
||||
<xsd:element ref="TYPESACTIVITES" minOccurs="1"
|
||||
maxOccurs="1" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xsd:schema xmlns:all="urn:AllAxelTypes" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
|
||||
|
||||
<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes" />
|
||||
|
||||
<xsd:complexType name="activite">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="ANNEEREFERENCE" />
|
||||
<xsd:element ref="IDACTIVITE" />
|
||||
<xsd:element ref="DATEDEBUT" />
|
||||
<xsd:element ref="DATEDFIN" />
|
||||
<xsd:element ref="FILTRESD" minOccurs="0"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="enfant">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDPERSONNE" />
|
||||
<xsd:element ref="ACTIVITE" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="DUIType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDDUI" />
|
||||
<xsd:element ref="ENFANT" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="PORTAILType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="DUI"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="filtresd">
|
||||
<xsd:union memberTypes="all:ONType all:empty-string" />
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:element name="IDDUI" type="all:IDENTREQUIREDType"/>
|
||||
<xsd:element name="ENFANT" type="enfant"/>
|
||||
|
||||
<xsd:element name="IDPERSONNE" type="all:IDENTREQUIREDType"/>
|
||||
|
||||
<xsd:element name="ANNEEREFERENCE" type="all:ANNEEType"/>
|
||||
<xsd:element name="IDACTIVITE" type="all:IDREQUIREDType"/>
|
||||
<xsd:element name="DATEDEBUT" type="all:DATEREQUIREDType"/>
|
||||
<xsd:element name="DATEDFIN" type="all:DATEREQUIREDType"/>
|
||||
<xsd:element name="FILTRESD" type="filtresd"/>
|
||||
|
||||
<xsd:element name="ACTIVITE" type="activite"/>
|
||||
<xsd:element name="DUI" type="DUIType"/>
|
||||
|
||||
<xsd:element name="PORTAIL" type="PORTAILType"/>
|
||||
</xsd:schema>
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:all="urn:AllAxelTypes">
|
||||
|
||||
<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes" />
|
||||
|
||||
<xsd:redefine schemaLocation="../R_ShemaResultat.xsd">
|
||||
<xsd:simpleType name="TYPEType">
|
||||
<xsd:restriction base="TYPEType">
|
||||
<xsd:enumeration value="EnfantsActivites" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="PORTAILType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="PORTAILType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="DUI" />
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:redefine>
|
||||
|
||||
<xsd:simpleType name="typeactivite">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:minLength value="1"/>
|
||||
<xsd:maxLength value="4"/>
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="dui">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDDUI" />
|
||||
<xsd:element ref="NBENFANTINSCRIT" />
|
||||
<xsd:element ref="ENFANT" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="enfant">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="NOM" />
|
||||
<xsd:element ref="PRENOM" />
|
||||
<xsd:element ref="DATENAISSANCE" />
|
||||
<xsd:element ref="IDPERSONNE" />
|
||||
<xsd:element ref="REGIME" />
|
||||
<xsd:element ref="LIBELLEECOLE" />
|
||||
<xsd:element ref="ACTIVITE" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="activite">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="TYPEACTIVITE" />
|
||||
<xsd:element ref="IDACTIVITE" />
|
||||
<xsd:element ref="LIBELLEACTIVITE" />
|
||||
<xsd:element ref="DATEENTREE" />
|
||||
<xsd:element ref="DATESORTIE" />
|
||||
<xsd:element ref="TARIF" />
|
||||
<xsd:element ref="ISPAI" />
|
||||
<xsd:element ref="COUTREVIENT" />
|
||||
<xsd:element ref="DATEDEBUT" />
|
||||
<xsd:element ref="DATEFIN" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="regime">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:maxLength value="4" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:element name="IDDUI" type="all:IDENTREQUIREDType"/>
|
||||
<xsd:element name="NBENFANTINSCRIT" type="xsd:positiveInteger"/>
|
||||
<xsd:element name="NOM" type="all:NOMREQUIREDType"/>
|
||||
<xsd:element name="PRENOM" type="all:PRENOMREQUIREDType"/>
|
||||
<xsd:element name="DATENAISSANCE" type="all:DATEType"/>
|
||||
<xsd:element name="IDPERSONNE" type="all:IDENTREQUIREDType"/>
|
||||
<xsd:element name="REGIME" type="regime" />
|
||||
<xsd:element name="LIBELLEECOLE" type="xsd:string"/>
|
||||
|
||||
<xsd:element name="TYPEACTIVITE" type="typeactivite"/>
|
||||
<xsd:element name="IDACTIVITE" type="all:IDREQUIREDType"/>
|
||||
<xsd:element name="LIBELLEACTIVITE" type="xsd:string"/>
|
||||
<xsd:element name="DATEENTREE" type="all:DATEType"/>
|
||||
<xsd:element name="DATESORTIE" type="all:DATEType"/>
|
||||
<xsd:element name="TARIF" type="all:MONTANTType"/>
|
||||
<xsd:element name="ISPAI" type="all:OUINONType"/>
|
||||
<xsd:element name="COUTREVIENT" type="all:MONTANTType"/>
|
||||
<xsd:element name="DATEDEBUT" type="all:DATEREQUIREDType"/>
|
||||
<xsd:element name="DATEFIN" type="all:DATEREQUIREDType"/>
|
||||
|
||||
<xsd:element name="ENFANT" type="enfant" />
|
||||
<xsd:element name="ACTIVITE" type="activite" />
|
||||
<xsd:element name="DUI" type="dui" />
|
||||
|
||||
</xsd:schema>
|
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xsd:schema xmlns:all="urn:AllAxelTypes" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes" />
|
||||
|
||||
|
||||
<xsd:redefine schemaLocation="../R_ShemaResultat.xsd">
|
||||
<xsd:simpleType name="TYPEType">
|
||||
<xsd:restriction base="TYPEType">
|
||||
<xsd:enumeration value="ReservationPeriode" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:complexType name="PORTAILType">
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="PORTAILType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="DUI" minOccurs="1" maxOccurs="1"/>
|
||||
</xsd:sequence>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:redefine>
|
||||
|
||||
<xsd:complexType name="activite">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="ANNEEREFERENCE" />
|
||||
<xsd:element ref="IDACTIVITE" />
|
||||
<xsd:element ref="JOUR" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="enfant">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDPERSONNE" />
|
||||
<xsd:element ref="ACTIVITE" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="DUIType">
|
||||
<xsd:sequence>
|
||||
<xsd:element ref="IDDUI" />
|
||||
<xsd:element ref="ENFANT" minOccurs="1" maxOccurs="unbounded"/>
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:element name="IDDUI" type="all:IDENTREQUIREDType"/>
|
||||
<xsd:element name="ENFANT" type="enfant"/>
|
||||
|
||||
<xsd:element name="IDPERSONNE" type="all:IDENTREQUIREDType"/>
|
||||
|
||||
<xsd:element name="ANNEEREFERENCE" type="all:ANNEEType"/>
|
||||
<xsd:element name="IDACTIVITE" type="all:IDREQUIREDType"/>
|
||||
<xsd:element name="JOUR" type="xsd:string"/>
|
||||
|
||||
<xsd:element name="ACTIVITE" type="activite"/>
|
||||
<xsd:element name="DUI" type="DUIType"/>
|
||||
|
||||
</xsd:schema>
|
|
@ -0,0 +1,28 @@
|
|||
<PORTAIL>
|
||||
<DUI>
|
||||
<IDDUI>XXX</IDDUI>
|
||||
<ENFANT>
|
||||
<IDPERSONNE>3535</IDPERSONNE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
||||
<JOUR>00000</JOUR>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>A19P1M2</IDACTIVITE>
|
||||
<JOUR>11111</JOUR>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>A19P1M3</IDACTIVITE>
|
||||
<JOUR>11211</JOUR>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>A19P1M4</IDACTIVITE>
|
||||
<JOUR>22122</JOUR>
|
||||
</ACTIVITE>
|
||||
</ENFANT>
|
||||
</DUI>
|
||||
</PORTAIL>
|
|
@ -0,0 +1,62 @@
|
|||
<PORTAIL>
|
||||
<DUI>
|
||||
<IDDUI>XXX</IDDUI>
|
||||
<NBENFANTINSCRIT>1</NBENFANTINSCRIT>
|
||||
<ENFANT>
|
||||
<NOM>foo</NOM>
|
||||
<PRENOM>foo</PRENOM>
|
||||
<DATENAISSANCE>01/01/2019</DATENAISSANCE>
|
||||
<IDPERSONNE>3535</IDPERSONNE>
|
||||
<REGIME>SV</REGIME>
|
||||
<LIBELLEECOLE>MATERNELLE 1</LIBELLEECOLE>
|
||||
<ACTIVITE>
|
||||
<TYPEACTIVITE>MAT</TYPEACTIVITE>
|
||||
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
||||
<LIBELLEACTIVITE>Temps du matin</LIBELLEACTIVITE>
|
||||
<DATEENTREE>01/08/2019</DATEENTREE>
|
||||
<DATESORTIE>31/07/2020</DATESORTIE>
|
||||
<TARIF>0.42</TARIF>
|
||||
<ISPAI>NON</ISPAI>
|
||||
<COUTREVIENT>99999</COUTREVIENT>
|
||||
<DATEDEBUT>01/08/2019</DATEDEBUT>
|
||||
<DATEFIN>31/07/2020</DATEFIN>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<TYPEACTIVITE>MIDI</TYPEACTIVITE>
|
||||
<IDACTIVITE>A19P1M2</IDACTIVITE>
|
||||
<LIBELLEACTIVITE>Temps du midi</LIBELLEACTIVITE>
|
||||
<DATEENTREE>01/08/2019</DATEENTREE>
|
||||
<DATESORTIE>31/07/2020</DATESORTIE>
|
||||
<TARIF>0.43</TARIF>
|
||||
<ISPAI>NON</ISPAI>
|
||||
<COUTREVIENT>99999</COUTREVIENT>
|
||||
<DATEDEBUT>01/08/2019</DATEDEBUT>
|
||||
<DATEFIN>31/07/2020</DATEFIN>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<TYPEACTIVITE>SOIR</TYPEACTIVITE>
|
||||
<IDACTIVITE>A19P1M3</IDACTIVITE>
|
||||
<LIBELLEACTIVITE>Temps du soir</LIBELLEACTIVITE>
|
||||
<DATEENTREE>01/08/2019</DATEENTREE>
|
||||
<DATESORTIE>31/07/2020</DATESORTIE>
|
||||
<TARIF>0.44</TARIF>
|
||||
<ISPAI>NON</ISPAI>
|
||||
<COUTREVIENT>99999</COUTREVIENT>
|
||||
<DATEDEBUT>01/08/2019</DATEDEBUT>
|
||||
<DATEFIN>31/07/2020</DATEFIN>
|
||||
</ACTIVITE>
|
||||
<ACTIVITE>
|
||||
<TYPEACTIVITE>GARD</TYPEACTIVITE>
|
||||
<IDACTIVITE>A19P1M4</IDACTIVITE>
|
||||
<LIBELLEACTIVITE>Temps mercredi après midi</LIBELLEACTIVITE>
|
||||
<DATEENTREE>01/08/2019</DATEENTREE>
|
||||
<DATESORTIE>31/07/2020</DATESORTIE>
|
||||
<TARIF>0.45</TARIF>
|
||||
<ISPAI>NON</ISPAI>
|
||||
<COUTREVIENT>99999</COUTREVIENT>
|
||||
<DATEDEBUT>01/08/2019</DATEDEBUT>
|
||||
<DATEFIN>31/07/2020</DATEFIN>
|
||||
</ACTIVITE>
|
||||
</ENFANT>
|
||||
</DUI>
|
||||
</PORTAIL>
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# passerelle - uniform access to multiple data sources and services
|
||||
# Copyright (C) 2019 Entr'ouvert
|
||||
# Copyright (C) 2020 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
|
@ -32,6 +33,7 @@ from passerelle.contrib.toulouse_axel.models import (
|
|||
Lock,
|
||||
OperationResult,
|
||||
ToulouseAxel,
|
||||
enfants_activites,
|
||||
form_maj_famille_dui,
|
||||
form_paiement_dui,
|
||||
list_dui_factures,
|
||||
|
@ -40,6 +42,7 @@ from passerelle.contrib.toulouse_axel.models import (
|
|||
ref_facture_a_payer,
|
||||
ref_facture_pdf,
|
||||
ref_verif_dui,
|
||||
reservation_periode,
|
||||
)
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
import utils
|
||||
|
@ -93,6 +96,28 @@ def family_data():
|
|||
return ref_famille_dui.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL']['DUI']
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def child_activities_data():
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
||||
with open(filepath) as xml:
|
||||
content = xml.read()
|
||||
resp = '''
|
||||
<?xml version="1.0"?>
|
||||
<PORTAILSERVICE>
|
||||
<RESULTAT>
|
||||
<TYPE>EnfantsActivites</TYPE>
|
||||
<STATUS>OK</STATUS>
|
||||
<DATE>10/10/2010 10:10:01</DATE>
|
||||
<COMMENTAIRES><![CDATA[]]></COMMENTAIRES>
|
||||
</RESULTAT>
|
||||
<DATA>
|
||||
%s
|
||||
</DATA>
|
||||
</PORTAILSERVICE>
|
||||
'''.strip() % content
|
||||
return enfants_activites.response_converter.decode(ET.fromstring(resp))['DATA']['PORTAIL']['DUI']
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def flat_update_params():
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/flat_update_family_info.json')
|
||||
|
@ -363,6 +388,36 @@ def test_operation_form_paiement_dui(resource, content):
|
|||
})
|
||||
|
||||
|
||||
@pytest.mark.parametrize('content', [
|
||||
'<PORTAIL><DUI/></PORTAIL>',
|
||||
])
|
||||
def test_operation_enfants_activites(resource, content):
|
||||
with mock_getdata(content, 'EnfantsActivites'):
|
||||
with pytest.raises(AxelError):
|
||||
enfants_activites(resource, {
|
||||
'DUI': {
|
||||
'IDDUI': 'XXX',
|
||||
'ANNEEREFERENCE': '2042',
|
||||
'TYPESACTIVITES': 'MAT,MIDI,SOIR,GARD',
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@pytest.mark.parametrize('content', [
|
||||
'<PORTAIL><DUI/></PORTAIL>',
|
||||
])
|
||||
def test_operation_reservation_periode(resource, content):
|
||||
with mock_getdata(content, 'ReservationPeriode'):
|
||||
with pytest.raises(AxelError):
|
||||
reservation_periode(resource, {
|
||||
'PORTAIL': {
|
||||
'DUI': {
|
||||
'IDDUI': 'XXX',
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def test_management_dates_endpoint_axel_error(app, resource):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.ref_date_gestion_dui') as operation:
|
||||
operation.side_effect = AxelError('FooBar')
|
||||
|
@ -1688,3 +1743,205 @@ def test_pay_invoice_endpoint(app, resource):
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_clae_booking_info_endpoint_axel_error(app, resource):
|
||||
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.enfants_activites') as operation:
|
||||
operation.side_effect = AxelError('FooBar')
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err_desc'] == "Axel error: FooBar"
|
||||
assert resp.json['err'] == 'error'
|
||||
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
||||
with open(filepath) as xml:
|
||||
content = xml.read()
|
||||
with mock_getdata(content, 'EnfantsActivites'):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.reservation_periode') as operation:
|
||||
operation.side_effect = AxelError('FooBar')
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err_desc'] == "Axel error: FooBar"
|
||||
assert resp.json['err'] == 'error'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value', ['foo', '20/01/2020', '2020'])
|
||||
def test_clae_booking_info_endpoint_bad_date_format(app, resource, value):
|
||||
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=%s' % value, status=400)
|
||||
assert resp.json['err_desc'] == "bad date format"
|
||||
assert resp.json['err'] == 'bad-request'
|
||||
|
||||
|
||||
def test_clae_booking_info_endpoint_no_result(app, resource, child_activities_data):
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err_desc'] == "Person not found"
|
||||
assert resp.json['err'] == 'not-found'
|
||||
|
||||
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/child_activities.xml')
|
||||
with open(filepath) as xml:
|
||||
content = xml.read()
|
||||
with mock_getdata(content, 'EnfantsActivites'):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.reservation_periode') as operation:
|
||||
operation.side_effect = AxelError('FooBar')
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=4242&booking_date=2020-01-20')
|
||||
assert resp.json['err_desc'] == "Child not found"
|
||||
assert resp.json['err'] == 'not-found'
|
||||
|
||||
content = """<PORTAIL>
|
||||
<DUI>
|
||||
<IDDUI>XXX</IDDUI>
|
||||
<ENFANT>
|
||||
<IDPERSONNE>4242</IDPERSONNE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>A19P1M1</IDACTIVITE>
|
||||
<JOUR>00000</JOUR>
|
||||
</ACTIVITE>
|
||||
</ENFANT>
|
||||
</DUI>
|
||||
</PORTAIL>"""
|
||||
activities = child_activities_data['ENFANT'][0]
|
||||
with mock_getdata(content, 'ReservationPeriode'):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities):
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err_desc'] == "Child not found"
|
||||
assert resp.json['err'] == 'not-found'
|
||||
|
||||
|
||||
def test_clae_booking_info_endpoint(app, resource, child_activities_data):
|
||||
Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
|
||||
filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/booking_info.xml')
|
||||
with open(filepath) as xml:
|
||||
content = xml.read()
|
||||
activities = child_activities_data['ENFANT'][0]
|
||||
with mock_getdata(content, 'ReservationPeriode'):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities):
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == {
|
||||
'ACTIVITE': [
|
||||
{
|
||||
'COUTREVIENT': '99999',
|
||||
'DATEDEBUT': '2019-08-01',
|
||||
'DATEENTREE': '2019-08-01',
|
||||
'DATEFIN': '2020-07-31',
|
||||
'DATESORTIE': '2020-07-31',
|
||||
'IDACTIVITE': 'A19P1M1',
|
||||
'ISPAI': False,
|
||||
'LIBELLEACTIVITE': 'Temps du matin',
|
||||
'TARIF': '0.42',
|
||||
'TYPEACTIVITE': 'MAT',
|
||||
'booking': {
|
||||
'days': {
|
||||
'friday': False,
|
||||
'monday': False,
|
||||
'thursday': False,
|
||||
'tuesday': False,
|
||||
'wednesday': False
|
||||
},
|
||||
'raw_value': '00000'
|
||||
}
|
||||
},
|
||||
{
|
||||
'COUTREVIENT': '99999',
|
||||
'DATEDEBUT': '2019-08-01',
|
||||
'DATEENTREE': '2019-08-01',
|
||||
'DATEFIN': '2020-07-31',
|
||||
'DATESORTIE': '2020-07-31',
|
||||
'IDACTIVITE': 'A19P1M2',
|
||||
'ISPAI': False,
|
||||
'LIBELLEACTIVITE': 'Temps du midi',
|
||||
'TARIF': '0.43',
|
||||
'TYPEACTIVITE': 'MIDI',
|
||||
'booking': {
|
||||
'days': {
|
||||
'friday': True,
|
||||
'monday': True,
|
||||
'thursday': True,
|
||||
'tuesday': True,
|
||||
'wednesday': True
|
||||
},
|
||||
'raw_value': '11111'
|
||||
}
|
||||
},
|
||||
{
|
||||
'COUTREVIENT': '99999',
|
||||
'DATEDEBUT': '2019-08-01',
|
||||
'DATEENTREE': '2019-08-01',
|
||||
'DATEFIN': '2020-07-31',
|
||||
'DATESORTIE': '2020-07-31',
|
||||
'IDACTIVITE': 'A19P1M3',
|
||||
'ISPAI': False,
|
||||
'LIBELLEACTIVITE': 'Temps du soir',
|
||||
'TARIF': '0.44',
|
||||
'TYPEACTIVITE': 'SOIR',
|
||||
'booking': {
|
||||
'days': {
|
||||
'friday': True,
|
||||
'monday': True,
|
||||
'thursday': True,
|
||||
'tuesday': True,
|
||||
'wednesday': None
|
||||
},
|
||||
'raw_value': '11211'
|
||||
}
|
||||
},
|
||||
{
|
||||
'COUTREVIENT': '99999',
|
||||
'DATEDEBUT': '2019-08-01',
|
||||
'DATEENTREE': '2019-08-01',
|
||||
'DATEFIN': '2020-07-31',
|
||||
'DATESORTIE': '2020-07-31',
|
||||
'IDACTIVITE': 'A19P1M4',
|
||||
'ISPAI': False,
|
||||
'LIBELLEACTIVITE': u'Temps mercredi après midi',
|
||||
'TARIF': '0.45',
|
||||
'TYPEACTIVITE': 'GARD',
|
||||
'booking': {
|
||||
'days': {
|
||||
'friday': None,
|
||||
'monday': None,
|
||||
'thursday': None,
|
||||
'tuesday': None,
|
||||
'wednesday': True
|
||||
},
|
||||
'raw_value': '22122'
|
||||
}
|
||||
}
|
||||
],
|
||||
'DATENAISSANCE': '2019-01-01',
|
||||
'IDPERSONNE': '3535',
|
||||
'LIBELLEECOLE': 'MATERNELLE 1',
|
||||
'NOM': 'foo',
|
||||
'PRENOM': 'foo',
|
||||
'REGIME': 'SV'
|
||||
}
|
||||
|
||||
# test wrong and missing IDACTIVITE
|
||||
content = """<PORTAIL>
|
||||
<DUI>
|
||||
<IDDUI>XXX</IDDUI>
|
||||
<ENFANT>
|
||||
<IDPERSONNE>3535</IDPERSONNE>
|
||||
<ACTIVITE>
|
||||
<ANNEEREFERENCE>2019</ANNEEREFERENCE>
|
||||
<IDACTIVITE>UNKNOWN</IDACTIVITE>
|
||||
<JOUR>00000</JOUR>
|
||||
</ACTIVITE>
|
||||
</ENFANT>
|
||||
</DUI>
|
||||
</PORTAIL>"""
|
||||
activities = child_activities_data['ENFANT'][0]
|
||||
with mock_getdata(content, 'ReservationPeriode'):
|
||||
with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_child_activities', return_value=activities):
|
||||
resp = app.get('/toulouse-axel/test/clae_booking_info?NameID=yyy&idpersonne=3535&booking_date=2020-01-20')
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data']['ACTIVITE'][0]['IDACTIVITE'] == 'A19P1M1'
|
||||
assert resp.json['data']['ACTIVITE'][0]['booking'] == {}
|
||||
assert resp.json['data']['ACTIVITE'][1]['IDACTIVITE'] == 'A19P1M2'
|
||||
assert resp.json['data']['ACTIVITE'][1]['booking'] == {}
|
||||
assert resp.json['data']['ACTIVITE'][2]['IDACTIVITE'] == 'A19P1M3'
|
||||
assert resp.json['data']['ACTIVITE'][2]['booking'] == {}
|
||||
assert resp.json['data']['ACTIVITE'][3]['IDACTIVITE'] == 'A19P1M4'
|
||||
assert resp.json['data']['ACTIVITE'][3]['booking'] == {}
|
||||
|
|
|
@ -14,8 +14,15 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import datetime
|
||||
import pytest
|
||||
|
||||
from passerelle.contrib.toulouse_axel.utils import (
|
||||
encode_datetime,
|
||||
get_booking,
|
||||
get_reference_year_from_date,
|
||||
get_week_dates_from_date,
|
||||
json_date_format,
|
||||
)
|
||||
|
||||
|
||||
|
@ -26,3 +33,40 @@ def test_encode_datetime():
|
|||
assert encode_datetime('2019-12-12T12:01:72') == '2019-12-12T12:01:72'
|
||||
# ok
|
||||
assert encode_datetime('2019-12-12T12:01:42') == '12/12/2019 12:01:42'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, expected', [
|
||||
('0', False),
|
||||
('1', True),
|
||||
('2', None),
|
||||
('foo', False),
|
||||
])
|
||||
def test_get_booking(value, expected):
|
||||
assert get_booking(value) is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('value, expected', [
|
||||
('2020-01-01', 2019),
|
||||
('2020-07-31', 2019),
|
||||
('2020-08-01', 2020),
|
||||
('2020-12-31', 2020),
|
||||
])
|
||||
def test_get_reference_year_from_date(value, expected):
|
||||
in_date = datetime.datetime.strptime(value, json_date_format)
|
||||
assert get_reference_year_from_date(in_date) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('in_value, start_value, end_value', [
|
||||
('2020-01-06', '2020-01-06', '2020-01-10'), # monday
|
||||
('2020-01-07', '2020-01-06', '2020-01-10'), # tuesday
|
||||
('2020-01-08', '2020-01-06', '2020-01-10'), # wednesday
|
||||
('2020-01-09', '2020-01-06', '2020-01-10'), # thursday
|
||||
('2020-01-10', '2020-01-06', '2020-01-10'), # friday
|
||||
('2020-01-11', '2020-01-06', '2020-01-10'), # saturday
|
||||
('2020-01-12', '2020-01-06', '2020-01-10'), # sunday
|
||||
])
|
||||
def test_get_week_dates_from_date(in_value, start_value, end_value):
|
||||
in_date = datetime.datetime.strptime(in_value, json_date_format)
|
||||
start_date = datetime.datetime.strptime(start_value, json_date_format)
|
||||
end_date = datetime.datetime.strptime(end_value, json_date_format)
|
||||
assert get_week_dates_from_date(in_date) == (start_date, end_date)
|
||||
|
|
Loading…
Reference in New Issue