toulouse_axel: booking_info endpoint (#39126)

This commit is contained in:
Lauréline Guérin 2020-01-27 11:20:47 +01:00 committed by Thomas NOEL
parent bb4161fd22
commit a1e17662bb
10 changed files with 756 additions and 1 deletions

View File

@ -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)

View File

@ -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'

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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&#232;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>

View File

@ -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'] == {}

View File

@ -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)