0001-solis_afi_mss-add-age-selections-on-children-endpoin.patch
passerelle/contrib/solis_afi_mss/models.py | ||
---|---|---|
9 | 9 |
# This program is distributed in the hope that it will be useful, |
10 | 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | 12 |
# GNU Affero General Public License for more details. |
13 | 13 |
# |
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from datetime import datetime |
|
18 |
from dateutil.relativedelta import relativedelta |
|
17 | 19 |
from urllib.parse import urljoin |
18 | 20 | |
19 | 21 |
from django.db import models |
22 |
from django.utils import timezone |
|
23 |
from django.utils.dateparse import parse_date |
|
20 | 24 |
from django.utils.translation import ugettext_lazy as _ |
21 | 25 | |
22 | 26 |
from passerelle.base.models import BaseResource, HTTPResource |
23 | 27 |
from passerelle.utils.api import endpoint |
24 | 28 |
from passerelle.utils.jsonresponse import APIError |
25 | 29 | |
26 | 30 |
TAX_SCHEMA = { |
27 | 31 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
... | ... | |
182 | 186 |
description=_('Retrieve adults from family composition'), |
183 | 187 |
parameters={ |
184 | 188 |
'email': {'description': _("Agent's email address")}, |
185 | 189 |
}) |
186 | 190 |
def adults(self, request, email): |
187 | 191 |
adults = self.search_from_email(email)[1] |
188 | 192 |
return {'data': adults} |
189 | 193 | |
194 |
@staticmethod |
|
195 |
def get_age(birthday_date_string, now_date_string=None): |
|
196 |
if now_date_string: |
|
197 |
try: |
|
198 |
now_date = parse_date(now_date_string) |
|
199 |
except ValueError as exc: |
|
200 |
raise APIError( |
|
201 |
'input is well formatted but not a valid date: %s' % exc, http_status=400) |
|
202 |
if not now_date: |
|
203 |
raise APIError( |
|
204 |
"input isn't well formatted, YYYY-MM-DD expected: %s" % birthday_date_string, |
|
205 |
http_status=400) |
|
206 | ||
207 |
# ignore error we can get form Solis data |
|
208 |
try: |
|
209 |
birthday_date = parse_date(birthday_date_string) |
|
210 |
except ValueError as exc: |
|
211 |
birthday_date = None |
|
212 |
if not birthday_date: |
|
213 |
return None |
|
214 | ||
215 |
if not now_date_string: |
|
216 |
now_date = timezone.now().date() |
|
217 |
return relativedelta(now_date, birthday_date) |
|
218 | ||
190 | 219 |
@endpoint( |
191 | 220 |
display_category=_('Agent'), display_order=4, |
192 | 221 |
perm='can_access', methods=['get'], |
193 | 222 |
description=_('Retrieve children from family composition'), |
194 | 223 |
parameters={ |
195 | 224 |
'email': {'description': _("Agent's email address")}, |
225 |
'min_age': {'description': _("Integer to select childreen older or equal to this age")}, |
|
226 |
'max_age': {'description': _("Integer to select childreen younger to this age")}, |
|
227 |
'now': {'description': _("Reference date use to compute age")}, |
|
196 | 228 |
}) |
197 |
def children(self, request, email): |
|
229 |
def children(self, request, email, min_age=None, max_age=None, now=None):
|
|
198 | 230 |
children = self.search_from_email(email)[2] |
199 |
return {'data': children} |
|
231 |
data = [] |
|
232 |
for child in children: |
|
233 |
child_age = self.get_age(child.get('dateNaissance'), now) |
|
234 |
if child_age: |
|
235 |
# do not unselect childreen having no or wrongly formated dateNaissance |
|
236 |
if min_age and child_age.years < int(min_age): |
|
237 |
continue |
|
238 |
if max_age and child_age.years >= int(max_age): |
|
239 |
continue |
|
240 |
child['age'] = child_age.years |
|
241 |
data.append(child) |
|
242 |
return {'data': data} |
|
200 | 243 | |
201 | 244 |
@endpoint( |
202 | 245 |
display_category=_('Budget'), display_order=1, |
203 | 246 |
perm='can_access', methods=['get'], |
204 | 247 |
description=_('Retrieve the list of charges for an agent'), |
205 | 248 |
parameters={ |
206 | 249 |
'email': {'description': _("Agent's email address")}, |
207 | 250 |
'year': {'description': _('Year of taxation (YYYY)')}, |
tests/test_solis_afi_mss.py | ||
---|---|---|
265 | 265 |
def test_children(mocked_get, app, connector, response1, children): |
266 | 266 |
mocked_get.side_effect = [response1] |
267 | 267 |
endpoint = get_endpoint('children') + '?email=foo@dummy.org' |
268 | 268 |
resp = app.get(endpoint) |
269 | 269 |
assert not resp.json['err'] |
270 | 270 |
assert [(x['id'], x['text']) for x in resp.json['data']] == children |
271 | 271 | |
272 | 272 | |
273 |
@pytest.mark.parametrize('index, name, birthday, age', [ |
|
274 |
(123456, 'Nico', '1978-05-11', 42), |
|
275 |
(389229, 'Lola ROUSSEAU', '1995-07-25', 25), |
|
276 |
(389230, 'Nicolas ROUSSEAU', '1990-05-04', 30), |
|
277 |
(389231, 'Mélina ROUSSEAU', '1992-06-10', 28), |
|
278 |
(388413, 'KEVIN PIED', '1997-04-26', 23), |
|
279 |
(388407, 'Camille HUREL', '1991-08-24', 29), |
|
280 |
(388408, 'Valentin HUREL', '1996-08-05', 24), |
|
281 |
]) |
|
282 |
def test_get_age(connector, index, name, birthday, age): |
|
283 |
assert connector.get_age(birthday, '2021-02-10').years == age |
|
284 | ||
285 | ||
286 |
@mock.patch('passerelle.utils.Request.get') |
|
287 |
@pytest.mark.parametrize('response1, children', [ |
|
288 |
(RECHERCHE_PAR_EMAIL_1, []), |
|
289 |
(RECHERCHE_PAR_EMAIL_2, [ |
|
290 |
(388413, 'KEVIN PIED'), |
|
291 |
]), |
|
292 |
(RECHERCHE_PAR_EMAIL_3, []), |
|
293 |
(RECHERCHE_PAR_EMAIL_4, [ |
|
294 |
(388408, 'Valentin HUREL'), |
|
295 |
]), |
|
296 |
]) |
|
297 |
def test_children_younger(mocked_get, freezer, app, connector, response1, children): |
|
298 |
freezer.move_to('2021-02-10') |
|
299 |
mocked_get.side_effect = [response1] |
|
300 |
endpoint = get_endpoint('children') + '?email=foo@dummy.org&max_age=25' |
|
301 |
resp = app.get(endpoint) |
|
302 |
assert not resp.json['err'] |
|
303 |
assert [(x['id'], x['text']) for x in resp.json['data']] == children |
|
304 | ||
305 | ||
306 |
@mock.patch('passerelle.utils.Request.get') |
|
307 |
@pytest.mark.parametrize('response1, children', [ |
|
308 |
(RECHERCHE_PAR_EMAIL_1, [ |
|
309 |
(389229, 'Lola ROUSSEAU'), |
|
310 |
(389230, 'Nicolas ROUSSEAU'), |
|
311 |
(389231, 'Mélina ROUSSEAU'), |
|
312 |
]), |
|
313 |
(RECHERCHE_PAR_EMAIL_2, []), |
|
314 |
(RECHERCHE_PAR_EMAIL_3, []), |
|
315 |
(RECHERCHE_PAR_EMAIL_4, [ |
|
316 |
(388407, 'Camille HUREL'), |
|
317 |
]), |
|
318 |
]) |
|
319 |
def test_children_older(mocked_get, app, connector, response1, children): |
|
320 |
mocked_get.side_effect = [response1] |
|
321 |
endpoint = get_endpoint('children') + '?email=foo@dummy.org&min_age=25&now=2021-02-10' |
|
322 |
resp = app.get(endpoint) |
|
323 |
assert not resp.json['err'] |
|
324 |
assert [(x['id'], x['text']) for x in resp.json['data']] == children |
|
325 | ||
326 | ||
327 |
@mock.patch('passerelle.utils.Request.get') |
|
328 |
@pytest.mark.parametrize('now, err_desc', [ |
|
329 |
('2012-02-30', 'not a valid date'), |
|
330 |
('10/02/2012', 'YYYY-MM-DD expected'), |
|
331 |
('tomorrow', 'YYYY-MM-DD expected'), |
|
332 |
]) |
|
333 |
def test_children_younger_api_error(mocked_get, app, connector, now, err_desc): |
|
334 |
mocked_get.side_effect = [RECHERCHE_PAR_EMAIL_2] |
|
335 |
endpoint = get_endpoint('children') + '?email=foo@dummy.org&max_age=25&now=%s' % now |
|
336 |
resp = app.get(endpoint, status=400) |
|
337 |
assert resp.json['err'] |
|
338 |
assert err_desc in resp.json['err_desc'] |
|
339 | ||
340 | ||
341 |
@mock.patch('passerelle.utils.Request.get') |
|
342 |
@pytest.mark.parametrize('birthday, nb_selected', [ |
|
343 |
('2012-02-30', 1), |
|
344 |
('10/02/2012', 1), |
|
345 |
('tomorrow', 1), |
|
346 |
('2012-02-10', 0), |
|
347 |
]) |
|
348 |
def test_children_older_data_error(mocked_get, freezer, app, connector, birthday, nb_selected): |
|
349 |
freezer.move_to('2021-02-10') |
|
350 |
with open(os.path.join(TEST_BASE_DIR, "%s.json" % 'rechercherParEmail_388412')) as fd: |
|
351 |
content = json.load(fd) |
|
352 |
content['enfantsAgent'][0]['dateNaissance'] = birthday |
|
353 |
mocked_get.side_effect = [response(200, json.dumps(content))] |
|
354 |
endpoint = get_endpoint('children') + '?email=foo@dummy.org&min_age=99' |
|
355 |
resp = app.get(endpoint) |
|
356 |
assert not resp.json['err'] |
|
357 |
assert len(resp.json['data']) == nb_selected |
|
358 | ||
359 | ||
273 | 360 |
@mock.patch('passerelle.utils.Request.get') |
274 | 361 |
@pytest.mark.parametrize('response1, response2, taxes', [ |
275 | 362 |
(RECHERCHE_PAR_EMAIL_4, GET_IMPOSITION_PAR_AGENT_4, |
276 | 363 |
[(2018, '2018: 15000'), (2019, '2019: 1000')]) |
277 | 364 |
]) |
278 | 365 |
def test_taxes(mocked_get, app, connector, response1, response2, taxes): |
279 | 366 |
mocked_get.side_effect = [response1, response2] |
280 | 367 |
endpoint = get_endpoint('taxes') + '?email=foo@dummy.org' |
281 |
- |