Skip to content

Commit

Permalink
circulation: update ILL request JSON schema
Browse files Browse the repository at this point in the history
* Allows to manage manually the loan status.
* Adds notes (public/staff) to an ILL request.
* Configures request resource to allow faceting.
* Fixes search serializer configuration to include created and updated
  date into search results.
* Fixes object serializer with `resolve` argument. 'created' and
  'updated' keys were null, date are now correct.
* Fixes translation problems on the user ILL request form.

Closes #1320

Co-Authored-by: Renaud Michotte <[email protected]>
  • Loading branch information
zannkukai committed Dec 7, 2020
1 parent 02e514e commit a333847
Show file tree
Hide file tree
Showing 20 changed files with 532 additions and 100 deletions.
30 changes: 25 additions & 5 deletions data/ill_requests.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@
"url": "http://data.rero.ch/01-R007878671/html?view=GE_V1"
},
"pages": "18-24",
"note": "Could you please add the front page of the journal issue? Thanks a lot!"
"notes": [
{
"type": "public_note",
"content": "Could you please add the front page of the journal issue? Thanks a lot!"
}
]
},
{
"status": "pending",
Expand Down Expand Up @@ -61,10 +66,20 @@
"url": "https://www.amazon.fr/grand-roman-maths-pr%C3%A9histoire-jours/dp/2081378760"
},
"pages": "19-44",
"note": "Je voudrais obtenir le chapitre 2 de ce livre."
"notes": [
{
"type": "public_note",
"content": "Je voudrais obtenir le chapitre 2 de ce livre."
},
{
"type": "staff_note",
"content": "Ce livre ne comprend pas de chapitre"
}
]
},
{
"status": "pending",
"status": "validated",
"loan_status": "ITEM_AT_DESK",
"copy": false,
"document": {
"title": "Harry Potter and the Philosopher's Stone",
Expand All @@ -76,6 +91,11 @@
"source": "Amazon",
"url": "https://read.amazon.com/kp/embed?asin=B019PIOJYU&preview=newtab&linkCode=kpe&ref_=cm_sw_r_kb_dp_MBjwFb8A8N94P"
},
"note": "In english please."
"notes": [
{
"type": "public_note",
"content": "In english please."
}
]
}
]
]
45 changes: 43 additions & 2 deletions rero_ils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ def _(x):
'rero_ils.modules.serializers:json_v1_response'
),
'application/rero+json': (
'rero_ils.modules.items.serializers:json_item_search'
'rero_ils.modules.ill_requests.serializers:json_ill_request'
)
},
search_serializers_aliases={
Expand All @@ -545,6 +545,9 @@ def _(x):
search_serializers={
'application/json': (
'rero_ils.modules.serializers:json_v1_search'
),
'application/rero+json': (
'rero_ils.modules.ill_requests.serializers:json_ill_request_search'
)
},
record_loaders={
Expand Down Expand Up @@ -1777,7 +1780,45 @@ def _(x):
_('subject'): and_term_filter('subjects.name'),
_('teacher'): and_term_filter('teachers.facet')
}
)
),
ill_requests=dict(
aggs=dict(
status=dict(
terms=dict(
field='status',
size=RERO_ILS_AGGREGATION_SIZE.get(
'ill_requests', RERO_ILS_DEFAULT_AGGREGATION_SIZE)
)
),
loan_status=dict(
terms=dict(
field='loan_status',
size=RERO_ILS_AGGREGATION_SIZE.get(
'ill_requests', RERO_ILS_DEFAULT_AGGREGATION_SIZE)
)
),
requester=dict(
terms=dict(
field='patron.facet',
size=RERO_ILS_AGGREGATION_SIZE.get(
'ill_requests', RERO_ILS_DEFAULT_AGGREGATION_SIZE)
)
),
library=dict(
terms=dict(
field='library.pid',
size=RERO_ILS_AGGREGATION_SIZE.get(
'ill_requests', RERO_ILS_DEFAULT_AGGREGATION_SIZE)
)
)
),
filters={
_('status'): and_term_filter('status'),
_('loan_status'): and_term_filter('loan_status'),
_('requester'): and_term_filter('patron.facet'),
_('library'): and_term_filter('library.pid')
}
),
)

# Elasticsearch fields boosting by index
Expand Down
27 changes: 24 additions & 3 deletions rero_ils/modules/ill_requests/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@

from functools import partial

from .models import ILLRequestIdentifier
from flask_babelex import gettext as _

from .models import ILLRequestIdentifier, ILLRequestMetadata, \
ILLRequestNoteStatus
from ..api import IlsRecord, IlsRecordsIndexer, IlsRecordsSearch
from ..fetchers import id_fetcher
from ..locations.api import Location
Expand Down Expand Up @@ -54,15 +57,22 @@ class ILLRequest(IlsRecord):
minter = ill_request_id_minter
fetcher = ill_request_id_fetcher
provider = ILLRequestProvider
model_cls = ILLRequestMetadata

def extended_validation(self, **kwargs):
"""Validate record against schema.
If record is a copy request (copy==true) then `pages` property is
required
* If record is a copy request (copy==true) then `pages` property is
required
* Ensures that only one note of each type is present.
"""
if self.is_copy and self.get('pages') is None:
return 'Required property : `pages`'

note_types = [note.get('type') for note in self.get('notes', [])]
if len(note_types) != len(set(note_types)):
return _('Can not have multiple notes of same type.')

return True

@classmethod
Expand Down Expand Up @@ -113,11 +123,22 @@ def organisation_pid(self):
"""Get organisation pid for ill_request."""
return self.get_pickup_location().organisation_pid

@property
def public_note(self):
"""Get the public note for ill_requests."""
notes = [note.get('content') for note in self.get('notes', [])
if note.get('type') == ILLRequestNoteStatus.PUBLIC_NOTE]
return next(iter(notes or []), None)

def get_pickup_location(self):
"""Get the pickup location."""
location_pid = self.replace_refs()['pickup_location']['pid']
return Location.get_record_by_pid(location_pid)

def get_library(self):
"""Get the library linked to the ill_request."""
return self.get_pickup_location().get_library()


class ILLRequestsIndexer(IlsRecordsIndexer):
"""Indexing documents in Elasticsearch."""
Expand Down
8 changes: 5 additions & 3 deletions rero_ils/modules/ill_requests/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ def create_ill_requests(input_file):
if 'pid' in request_data:
del request_data['pid']
if organisation_pid not in patron_pids:
patron_pids[organisation_pid] = list(
Patron.get_all_pids_for_organisation(organisation_pid)
)
patron_pids[organisation_pid] = [
pid for pid in Patron.get_all_pids_for_organisation(
organisation_pid)
if Patron.get_record_by_pid(pid).is_patron
]
patron_pid = random.choice(patron_pids[organisation_pid])
request_data['patron'] = {
'$ref': get_ref_for_pid('patrons', patron_pid)
Expand Down
8 changes: 6 additions & 2 deletions rero_ils/modules/ill_requests/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,13 @@ def get_data(self):
'found_in': {
'source': self.source.origin.data,
'url': self.source.url.data
},
'note': self.note.data
}
})
if self.note.data:
data['notes'] = [{
'type': 'public_note',
'content': self.note.data
}]

# if we put 'copy' in the dict before the dict cleaning and if 'copy'
# is set to 'No', then it will be removed by `remove_empties_from_dict`
Expand Down
Loading

0 comments on commit a333847

Please sign in to comment.