-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reports: create inventory list based on item resource
This part implements backend to perform inventory list reports in CSV format. * Adds CSVSerializer to render search results in CSV. * Adds ItemJSONSerializer to post process item search. * Adapts configuration of item rest endpoint to add serializer. * Adds library to elasticsearch mapping for item. * Adapts listener to add library_pid into item before indexing. * Writes tests. Co-Authored-by: Lauren-D <laurent.dubois@itld-solutions.be>
- Loading branch information
Showing
13 changed files
with
415 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# RERO ILS | ||
# Copyright (C) 2019 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 | ||
# the Free Software Foundation, version 3 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# 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/>. | ||
|
||
"""Items serializers.""" | ||
|
||
from invenio_records_rest.serializers.response import record_responsify, \ | ||
search_responsify | ||
|
||
from rero_ils.modules.serializers import JSONSerializer, RecordSchemaJSONV1 | ||
|
||
from .csv import ItemCSVSerializer | ||
from .json import ItemsJSONSerializer | ||
|
||
csv_item = ItemCSVSerializer( | ||
JSONSerializer, | ||
csv_included_fields=[ | ||
'pid', | ||
'document_pid', | ||
'document_title', | ||
'document_type', | ||
'location_name', | ||
'barcode', | ||
'call_number', | ||
'second_call_number', | ||
'loans_count', | ||
'last_transaction_date', | ||
'status', | ||
'created' | ||
] | ||
) | ||
csv_item_response = record_responsify(csv_item, "text/csv") | ||
csv_item_search = search_responsify(csv_item, "text/csv") | ||
"""CSV serializer.""" | ||
|
||
json_item = ItemsJSONSerializer(RecordSchemaJSONV1) | ||
"""JSON serializer.""" | ||
|
||
json_item_search = search_responsify(json_item, 'application/rero+json') | ||
json_item_response = record_responsify(json_item, 'application/rero+json') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# -*- coding: utf-8 -*- | ||
# | ||
# RERO ILS | ||
# Copyright (C) 2019 RERO | ||
# Copyright (C) 2020 UCLouvain | ||
# | ||
# 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 | ||
# the Free Software Foundation, version 3 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU Affero General Public License for more details. | ||
# | ||
# 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/>. | ||
|
||
"""Item serializers.""" | ||
|
||
import csv | ||
|
||
from invenio_i18n.ext import current_i18n | ||
from invenio_records_rest.serializers.csv import CSVSerializer, Line | ||
|
||
from rero_ils.filter import format_date_filter | ||
from rero_ils.modules.documents.api import search_document_by_pid | ||
from rero_ils.modules.documents.utils import title_format_text_head | ||
from rero_ils.modules.items.api import search_active_loans_for_item | ||
from rero_ils.modules.locations.api import LocationsSearch | ||
|
||
|
||
class ItemCSVSerializer(CSVSerializer): | ||
"""Serialize and filter item circulation status.""" | ||
|
||
def transform_search_hit( | ||
self, pid, record_hit, links_factory=None, **kwargs | ||
): | ||
"""Transform search result hit into an intermediate representation. | ||
:param pid: Persistent identifier instance. | ||
:param pid: Persistent identifier instance. | ||
:param record_hit: Record metadata retrieved via search. | ||
:param links_factory: Factory function for record links. | ||
""" | ||
hit = self.preprocess_search_hit( | ||
pid, record_hit, links_factory=links_factory, **kwargs | ||
) | ||
return hit | ||
|
||
def preprocess_search_hit(self, pid, record_hit, links_factory=None, | ||
**kwargs): | ||
"""Prepare a record hit from Elasticsearch for serialization. | ||
:param pid: Persistent identifier instance. | ||
:param record_hit: Record metadata retrieved via search. | ||
:param links_factory: Factory function for record links. | ||
""" | ||
record = record_hit['_source'] | ||
item_pid = pid.pid_value | ||
|
||
# process location | ||
locations_map = kwargs.get('locations_map') | ||
record['location_name'] = locations_map[ | ||
record.get('location').get('pid')] | ||
|
||
# retrieve and process document | ||
document = search_document_by_pid(record['document']['pid']) | ||
record['document_title'] = title_format_text_head(document.title, | ||
with_subtitle=True) | ||
record['document_type'] = document.type | ||
|
||
# get loans information | ||
loans_count, loans = search_active_loans_for_item(item_pid) | ||
record['loans_count'] = loans_count | ||
if loans_count: | ||
# get first loan | ||
loan = next(loans) | ||
record['last_transaction_date'] = format_date_filter( | ||
loan.transaction_date, | ||
format='short_date', | ||
locale=current_i18n.locale.language, | ||
) | ||
|
||
record['created'] = format_date_filter( | ||
record['_created'], | ||
format='short_date', | ||
locale=current_i18n.locale.language, | ||
) | ||
|
||
# prevent csv key error | ||
# TODO: find other way to prevent csv key error | ||
del(record['type']) | ||
|
||
return record | ||
|
||
def serialize_search(self, pid_fetcher, search_result, links=None, | ||
item_links_factory=None): | ||
"""Serialize a search result. | ||
:param pid_fetcher: Persistent identifier fetcher. | ||
:param search_result: Elasticsearch search result. | ||
:param links: Dictionary of links to add to response. | ||
:param item_links_factory: Factory function for record links. | ||
""" | ||
records = [] | ||
locations_map = {} | ||
for location in LocationsSearch().filter().scan(): | ||
locations_map[location.pid] = location.name | ||
for hit in search_result['hits']['hits']: | ||
processed_hit = self.transform_search_hit( | ||
pid_fetcher(hit['_id'], hit['_source']), | ||
hit, | ||
links_factory=item_links_factory, | ||
locations_map=locations_map | ||
) | ||
records.append(self.process_dict(processed_hit)) | ||
|
||
return self._format_csv(records) | ||
|
||
def _format_csv(self, records): | ||
"""Return the list of records as a CSV string. | ||
:param records: Records metadata to format. | ||
""" | ||
# build a unique list of all keys in included fields as CSV headers | ||
headers = dict.fromkeys(self.csv_included_fields) | ||
# write the CSV output in memory | ||
line = Line() | ||
writer = csv.DictWriter(line, | ||
quoting=csv.QUOTE_ALL, | ||
fieldnames=headers) | ||
writer.writeheader() | ||
yield line.read() | ||
|
||
for record in records: | ||
writer.writerow(record) | ||
yield line.read() |
Oops, something went wrong.