From 22ec2493b94045216e14b293951a3edc73d617f8 Mon Sep 17 00:00:00 2001 From: Bertrand Zuchuat Date: Tue, 26 Mar 2024 13:25:12 +0100 Subject: [PATCH] feat(item): add extra data on item dumper Add the name of the temporary location as well as the name of the collections. * Closes #1321. Co-Authored-by: Bertrand Zuchuat --- rero_ils/modules/collections/api.py | 16 +++++++++++- rero_ils/modules/items/dumpers.py | 12 ++++++++- tests/ui/items/test_items_dumpers.py | 38 +++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/rero_ils/modules/collections/api.py b/rero_ils/modules/collections/api.py index 76675c85cc..9a883d6a8c 100644 --- a/rero_ils/modules/collections/api.py +++ b/rero_ils/modules/collections/api.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2019-2022 RERO +# Copyright (C) 2019-2024 RERO # # 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 by @@ -17,6 +17,7 @@ """API for manipulating collections.""" +from datetime import datetime, timezone from functools import partial from rero_ils.modules.items.api import Item @@ -49,6 +50,19 @@ class Meta: index = 'collections' doc_types = None + def active_by_item_pid(self, item_pid): + """Search for active collections by item pid. + + :param item_pid: string - the item to filter with. + """ + collections = self \ + .filter('term', items__pid=item_pid) \ + .filter('range', end_date={'gte': datetime.now(timezone.utc)}) \ + .sort({'end_date': {'order': 'asc'}}) \ + .params(preserve_order=True) \ + .scan() + return [collection.title for collection in collections] + class Collection(IlsRecord): """Collection class.""" diff --git a/rero_ils/modules/items/dumpers.py b/rero_ils/modules/items/dumpers.py index 78eabc7f9a..dc21c013bd 100644 --- a/rero_ils/modules/items/dumpers.py +++ b/rero_ils/modules/items/dumpers.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2019-2023 RERO +# Copyright (C) 2019-2024 RERO # Copyright (C) 2019-2023 UCLouvain # # This program is free software: you can redistribute it and/or modify @@ -21,6 +21,7 @@ from invenio_records.dumpers import Dumper as InvenioRecordsDumper +from rero_ils.modules.collections.api import CollectionsSearch from rero_ils.modules.commons.exceptions import MissingDataException from rero_ils.modules.documents.api import Document from rero_ils.modules.documents.dumpers import \ @@ -144,4 +145,13 @@ def dump(self, record, data): data['pending_loans'] = [ first_request.dumps(LoanCirculationDumper()) ] + # add temporary location name + if temporary_location_pid := item.get('temporary_location', {}).get( + 'pid' + ): + data['temporary_location']['name'] = Location.get_record_by_pid( + temporary_location_pid).get('name') + # add collections + if collections := CollectionsSearch().active_by_item_pid(item['pid']): + data['collections'] = collections return data diff --git a/tests/ui/items/test_items_dumpers.py b/tests/ui/items/test_items_dumpers.py index 637a06606f..a4061390a0 100644 --- a/tests/ui/items/test_items_dumpers.py +++ b/tests/ui/items/test_items_dumpers.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # # RERO ILS -# Copyright (C) 2022 RERO +# Copyright (C) 2022-2024 RERO # Copyright (C) 2022 UCLouvain # # This program is free software: you can redistribute it and/or modify @@ -18,10 +18,13 @@ """Items Record dumper tests.""" from copy import deepcopy +from datetime import date import pytest +from dateutil.relativedelta import relativedelta from utils import item_record_to_a_specific_loan_state +from rero_ils.modules.collections.api import Collection from rero_ils.modules.commons.exceptions import MissingDataException from rero_ils.modules.holdings.api import Holding from rero_ils.modules.items.dumpers import CirculationActionDumper, \ @@ -33,7 +36,8 @@ def test_item_action_circulation_dumper( item_lib_martigny, patron_martigny, loc_public_martigny, - librarian_martigny, circulation_policies): + librarian_martigny, circulation_policies, loc_public_martigny_bourg, + coll_martigny_1): """Test item circulation action dumper.""" params = { 'patron_pid': patron_martigny.pid, @@ -43,7 +47,8 @@ def test_item_action_circulation_dumper( } item, _ = item_record_to_a_specific_loan_state( item=item_lib_martigny, loan_state=LoanState.PENDING, - params=params, copy_item=True) + params=params, copy_item=False) + data = item.dumps(CirculationActionDumper()) # $ref resolution assert data['library']['pid'] @@ -69,6 +74,33 @@ def test_item_action_circulation_dumper( # number of pending requests assert data['current_pending_requests'] == 1 + # not temporary location + assert 'temporary_location' not in data + + # not collections + assert 'collections' not in data + + # update end date on the collection + collection = Collection.get_record_by_pid(coll_martigny_1["pid"]) + next_end_date = date.today() + relativedelta(months=2) + collection["end_date"] = next_end_date.strftime("%Y-%m-%d") + collection.update(collection, dbcommit=True, reindex=True) + + # add temporary location data + item["temporary_location"] = { + "pid": "loc15", + "type": "loc" + } + + data = item.dumps(CirculationActionDumper()) + + # temporary location name + assert data['temporary_location']['name'] == loc_public_martigny_bourg\ + .get('name') + + # Collection title + assert data['collections'][0] == coll_martigny_1.get('title') + def test_item_circulation_dumper(item_lib_martigny): """Test item circulation dumper."""