From 44ac03a84ec4e0157448dc9ab5d15a82deabfc00 Mon Sep 17 00:00:00 2001 From: Renaud Michotte Date: Thu, 19 Nov 2020 14:00:17 +0100 Subject: [PATCH] circulation: allow overriding exception Sometimes, restrictions can disallow to execute a circulation operation. Adding the "override_blocking" parameter to the API url allows to bypass all restrictions. This commit also corrects some string for translations (color content RDA codes) Closes rero/rero-ils#1488t Co-Authored-by: Renaud Michotte --- .../document_color_content-v0.0.1.json | 4 ++-- rero_ils/modules/items/api_views.py | 2 ++ rero_ils/modules/items/decorators.py | 22 +++++++++++++------ tests/api/circulation/test_borrow_limits.py | 19 +++++++++++++++- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/rero_ils/modules/documents/jsonschemas/documents/document_color_content-v0.0.1.json b/rero_ils/modules/documents/jsonschemas/documents/document_color_content-v0.0.1.json index 12341e063a..4cf902f30e 100644 --- a/rero_ils/modules/documents/jsonschemas/documents/document_color_content-v0.0.1.json +++ b/rero_ils/modules/documents/jsonschemas/documents/document_color_content-v0.0.1.json @@ -15,11 +15,11 @@ "type": "selectWithSort", "options": [ { - "label": "Monochrome", + "label": "rdacc:1002", "value": "rdacc:1002" }, { - "label": "Polychrome", + "label": "rdacc:1003", "value": "rdacc:1003" } ], diff --git a/rero_ils/modules/items/api_views.py b/rero_ils/modules/items/api_views.py index de1b894fd9..78092f12e9 100644 --- a/rero_ils/modules/items/api_views.py +++ b/rero_ils/modules/items/api_views.py @@ -191,6 +191,8 @@ def checkout(item, data): transaction_location_pid, transaction_user_pid """ + data['override_blocking'] = flask_request.args.get( + 'override_blocking', False) return item.checkout(**data) diff --git a/rero_ils/modules/items/decorators.py b/rero_ils/modules/items/decorators.py index 03bc87cf68..43428cb283 100644 --- a/rero_ils/modules/items/decorators.py +++ b/rero_ils/modules/items/decorators.py @@ -70,6 +70,11 @@ def wrapper(item, *args, **kwargs): def check_operation_allowed(action): """Check if a specific action is allowed on an item. + Check if an 'override_blocking' parameter is present. If this param is + present and set to True (or corresponding True values [1, 'true', ...]) + then no CIRCULATION_ACTIONS_VALIDATION should be tested. + Remove this parameter from the data arguments. + Check the CIRCULATION_ACTIONS_VALIDATION configuration file and execute function corresponding to the action specified. All function are execute until one return False (action denied) or all actions are successful. @@ -80,13 +85,16 @@ def check_operation_allowed(action): def inner_function(func): @wraps(func) def decorated_view(*args, **kwargs): - actions = current_app.config.get( - 'CIRCULATION_ACTIONS_VALIDATION', {}) - for func_name in actions.get(action, []): - func_callback = obj_or_import_string(func_name) - can, reasons = func_callback(args[0], **kwargs) - if not can: - raise CirculationException(description=reasons[0]) + override_blocking = kwargs.pop('override_blocking', False) + override_blocking = bool(override_blocking) + if not override_blocking: + actions = current_app.config.get( + 'CIRCULATION_ACTIONS_VALIDATION', {}) + for func_name in actions.get(action, []): + func_callback = obj_or_import_string(func_name) + can, reasons = func_callback(args[0], **kwargs) + if not can: + raise CirculationException(description=reasons[0]) return func(*args, **kwargs) return decorated_view return inner_function diff --git a/tests/api/circulation/test_borrow_limits.py b/tests/api/circulation/test_borrow_limits.py index 77ea0a3cbc..0ac39c61a6 100644 --- a/tests/api/circulation/test_borrow_limits.py +++ b/tests/api/circulation/test_borrow_limits.py @@ -149,10 +149,27 @@ def test_checkout_library_limit( assert 'error' == data['messages'][0]['type'] assert 'Checkout denied' in data['messages'][0]['content'] + # try a checkout with 'override_blocking' parameter. + # --> the restriction is no longer checked, the checkout will be success. + res, data = postdata(client, 'api_item.checkout', dict( + item_pid=item3.pid, + patron_pid=patron.pid, + transaction_location_pid=loc_public_martigny.pid, + transaction_user_pid=librarian_martigny_no_email.pid, + ), url_data={'override_blocking': 'true'}) + assert res.status_code == 200 + loan3_pid = data.get('action_applied')[LoanAction.CHECKOUT].get('pid') + # reset fixtures - # --> checkin both loaned item + # --> checkin three loaned item # --> reset patron_type to original value # --> reset items to original values + res, data = postdata(client, 'api_item.checkin', dict( + item_pid=item3.pid, + pid=loan3_pid, + transaction_location_pid=loc_public_martigny.pid, + transaction_user_pid=librarian_martigny_no_email.pid, + )) res, data = postdata(client, 'api_item.checkin', dict( item_pid=item2.pid, pid=loan2_pid,