From 3d7a3b3446b029a544bb726b0aa535eb1e8faeea Mon Sep 17 00:00:00 2001 From: Aly Badr Date: Mon, 5 Nov 2018 16:13:04 +0100 Subject: [PATCH] Circulation: integration of invenio-circulation APIs * NEW makes invenio circ APIs available Signed-off-by: Aly Badr --- Pipfile | 3 +- Pipfile.lock | 28 +- requirements-devel.txt | 1 + rero_ils/config.py | 512 ++++++++++++++---------- rero_ils/modules/documents_items/api.py | 19 + rero_ils/modules/items/api.py | 10 + 6 files changed, 350 insertions(+), 223 deletions(-) diff --git a/Pipfile b/Pipfile index 701d32b9d1..b4ad534e94 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ PyYAML = ">=3.13" rero-ils = {editable = true, path = "."} uwsgi = ">=2.0" invenio-oaiharvester = {ref = "v1.0.0a4", git = "https://github.com/inveniosoftware/invenio-oaiharvester.git"} +invenio-circulation = {ref = "master", git = "https://github.com/inveniosoftware/invenio-circulation.git"} pip = "<=18.0" pipenv = "*" requests = ">=2.20.0" @@ -34,7 +35,7 @@ pytest-pep8 = ">=1.0.6" pytest-random-order = ">=0.5.4" pytest-runner = ">=3.0.0,<5" transifex-client = ">=0.12.5" -requests = ">=2.19.1" +requests = ">=2.20.0" rero-ils = {editable = true, path = "."} [requires] diff --git a/Pipfile.lock b/Pipfile.lock index 9634b1d532..e6d2148236 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "81155b5229a2dd162e8310ed008fcdbfe3414ba71311f0a226c2ea7c63d8ed87" + "sha256": "26e453991138dd4b8491c1aaecdd53328e4e3988e0f964a8e6fca09814646a37" }, "pipfile-spec": 6, "requires": { @@ -487,6 +487,10 @@ ], "version": "==1.0.0" }, + "invenio-circulation": { + "git": "https://github.com/inveniosoftware/invenio-circulation.git", + "ref": "3e144794bc636d3c2eceb13125975259a5b5c8a1" + }, "invenio-config": { "hashes": [ "sha256:628f771e351598d7f4e150a30aaa8f3a7daf62f969c7256b6bd211544f5bc494", @@ -1029,17 +1033,17 @@ }, "regex": { "hashes": [ - "sha256:384c78351ceb08b9f04e28552edea9af837d05ad4fda9a187a7bbd82759f29b6", - "sha256:41b70db2608726396de185e7571a70391507ab47a64b564f59861ff13f2c50a5", - "sha256:50f4b57696883fdbb0494cf1ff1cf6e04790d5e1848dff0b2cf28a2b97614351", - "sha256:81515123132f9ab0cc8128d035ba7db7783206e4616bdabd3faba335b9add185", - "sha256:91e965833a9f93b3e6abfef815026ccb8a9abe12c0958c723fc6c0d396384602", - "sha256:9cb058e53c2488b6cba85a7e6ce6d659b3f33ebe00f613dc9fda46de788a1298", - "sha256:b41a81228c3994789d4785d9fef96770f9a6b564a30c10af671bd5a4078da6f4", - "sha256:cf20d6539e00021793df23c2a98d57aff84f9402f81ac5896fffb4f8c8a08897", - "sha256:f937fdbcdb1e455c23709f5cf6df91a0ecfe8c23268f601606173232958daa8d" - ], - "version": "==2018.11.6" + "sha256:1ce9b1e31d34554a7c3c3edb524453e6521ae0fbd37e0c26299e05ae38bd9814", + "sha256:5d7e8ad4a4ac4c3ca96e8b32d32530913e3eb15dd368c838d3faa151a1b68d85", + "sha256:7bfb6e13ed8195513160550c3a82c49da8bbc6df5d149089cd37f51f36eddd39", + "sha256:80bbc5851f707a780d51a92df9eff885a43a44b611f3c1d745022827d4015285", + "sha256:8a6fc7e8da98f87a6659f0800ecb6a701afb9506d6c484db810b730eb268a644", + "sha256:ac72e3189c401d8d4397149ea1911f6b47a74875468951f48ca9b6c03acdd382", + "sha256:b5750b4eec5b64adf66098d922f8cf65b5306ad7a84d58a03f79cda1d2948d62", + "sha256:c0dd9b50bc9238ca53466ef1780bcdc5126b181594f1528d2d469d571861fb3f", + "sha256:e13fe1f764206e42643e51aff19479685531c0ce728b4828b048867eb3a8e53d" + ], + "version": "==2018.11.7" }, "requests": { "hashes": [ diff --git a/requirements-devel.txt b/requirements-devel.txt index 4cbe92bf21..e24e4c46de 100644 --- a/requirements-devel.txt +++ b/requirements-devel.txt @@ -27,6 +27,7 @@ # base bundle -e git+https://github.com/inveniosoftware/invenio-admin.git#egg=invenio-admin -e git+git://github.com/inveniosoftware/invenio-assets.git#egg=invenio-assets +-e git+git://github.com/inveniosoftware/invenio-circulation.git#egg=invenio-circulation -e git+git://github.com/inveniosoftware/invenio-formatter.git#egg=invenio-formatter -e git+git://github.com/inveniosoftware/invenio-logging.git#egg=invenio-logging -e git+https://github.com/inveniosoftware/invenio-mail.git#egg=invenio-mail diff --git a/rero_ils/config.py b/rero_ils/config.py index 91cadf80d2..be7e4139cd 100644 --- a/rero_ils/config.py +++ b/rero_ils/config.py @@ -34,6 +34,11 @@ from datetime import timedelta +from invenio_circulation.transitions.transitions import CreatedToItemOnLoan, \ + CreatedToPending, ItemAtDeskToItemOnLoan, \ + ItemInTransitHouseToItemReturned, ItemOnLoanToItemInTransitHouse, \ + ItemOnLoanToItemOnLoan, ItemOnLoanToItemReturned, PendingToItemAtDesk, \ + PendingToItemInTransitPickup from invenio_records_rest.facets import range_filter, terms_filter from invenio_search import RecordsSearch @@ -69,7 +74,7 @@ def _(x): I18N_LANGUAGES = [ ('fr', _('French')), ('de', _('German')), - ('it', _('Italian')) + ('it', _('Italian')), ] # Base templates @@ -107,8 +112,9 @@ def _(x): #: Brand logo. THEME_LOGO = 'images/logo_rero_ils.png' -SEARCH_UI_JSTEMPLATE_RESULTS = \ +SEARCH_UI_JSTEMPLATE_RESULTS = ( 'templates/rero_ils/brief_view_documents_items.html' +) SEARCH_UI_SEARCH_TEMPLATE = 'rero_ils/search.html' SEARCH_UI_JSTEMPLATE_FACETS = 'templates/rero_ils/facets.html' SEARCH_UI_JSTEMPLATE_RANGE = 'templates/rero_ils/range.html' @@ -137,8 +143,7 @@ def _(x): #: Email address used as sender of account registration emails. SECURITY_EMAIL_SENDER = SUPPORT_EMAIL #: Email subject for account registration emails. -SECURITY_EMAIL_SUBJECT_REGISTER = _( - "Welcome to RERO-ILS!") +SECURITY_EMAIL_SUBJECT_REGISTER = _("Welcome to RERO-ILS!") #: Redis session storage URL. ACCOUNTS_SESSION_REDIS_URL = 'redis://localhost:6379/1' # Disable User Profiles @@ -165,21 +170,21 @@ def _(x): 'ebooks-harvester': { 'task': 'invenio_oaiharvester.tasks.list_records_from_dates', 'schedule': timedelta(minutes=60), - 'kwargs': dict(name='ebooks') + 'kwargs': dict(name='ebooks'), }, 'mef-harvester': { 'task': 'rero_ils.modules.apiharvester.tasks.harvest_records', 'schedule': timedelta(minutes=60), - 'kwargs': dict(name='mef') + 'kwargs': dict(name='mef'), }, - } # Database # ======== #: Database URI including user and password -SQLALCHEMY_DATABASE_URI = \ +SQLALCHEMY_DATABASE_URI = ( 'postgresql+psycopg2://rero-ils:rero-ils@localhost/rero-ils' +) #: Disable Versioning due to Bad Performance DB_VERSIONING = False #: Disable warning @@ -232,7 +237,7 @@ def _(x): 'content_security_policy_report_uri': None, 'content_security_policy_report_only': False, 'session_cookie_secure': True, - 'session_cookie_http_only': True + 'session_cookie_http_only': True, } #: Sets cookie with the secure flag by default SESSION_COOKIE_SECURE = False @@ -266,20 +271,23 @@ def _(x): search_index='documents', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response') + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/documents/', item_route='/documents/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), doc_csv=dict( pid_type='doc', @@ -292,19 +300,19 @@ def _(x): 'text/csv': ( 'rero_ils.modules.documents_items.serializers' ':documents_items_csv_v1_response' - ), + ) }, search_serializers={ 'text/csv': ( 'rero_ils.modules.documents_items.serializers' ':documents_items_csv_v1_search' - ), + ) }, list_route='/export/documents/csv/', item_route='/export/documents/csv/', default_media_type='text/csv', max_result_window=20000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), org=dict( pid_type='org', @@ -314,22 +322,26 @@ def _(x): search_index='organisations', search_type=None, record_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ), }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/organisations/', item_route='/organisations/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), item=dict( pid_type='item', @@ -339,20 +351,23 @@ def _(x): search_index='items', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/items/', item_route='/items/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), itty=dict( pid_type='itty', @@ -362,20 +377,23 @@ def _(x): search_index='items_types', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/items_types/', item_route='/items_types/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), ptrn=dict( pid_type='ptrn', @@ -385,20 +403,23 @@ def _(x): search_index='patrons', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/patrons/', item_route='/patrons/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), ptty=dict( pid_type='ptty', @@ -408,20 +429,23 @@ def _(x): search_index='patrons_types', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/patrons_types/', item_route='/patrons_types/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), lib=dict( pid_type='lib', @@ -431,20 +455,23 @@ def _(x): search_index='libraries', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/libraries/', item_route='/libraries/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), loc=dict( pid_type='loc', @@ -454,20 +481,23 @@ def _(x): search_index='locations', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/locations/', item_route='/locations/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), pers=dict( pid_type='pers', @@ -477,20 +507,23 @@ def _(x): search_index='persons', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/persons/', item_route='/persons/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' + search_factory_imp='rero_ils.query:and_search_factory', ), cipo=dict( pid_type='cipo', @@ -500,39 +533,42 @@ def _(x): search_index='circ_policies', search_type=None, record_serializers={ - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_response'), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_response' + ) }, search_serializers={ - 'application/rero+json': ('rero_ils.modules.serializers' - ':json_v1_search'), - 'application/json': ('invenio_records_rest.serializers' - ':json_v1_search'), + 'application/rero+json': ( + 'rero_ils.modules.serializers' ':json_v1_search' + ), + 'application/json': ( + 'invenio_records_rest.serializers' ':json_v1_search' + ), }, list_route='/circ_policies/', item_route='/circ_policies/', default_media_type='application/json', max_result_window=10000, - search_factory_imp='rero_ils.query:and_search_factory' - ) + search_factory_imp='rero_ils.query:and_search_factory', + ), ) SEARCH_UI_SEARCH_INDEX = 'documents' RERO_ILS_APP_CONFIG_FACETS = { 'documents': { - 'order': ['document_type', 'library', 'author', 'language', 'subject', - 'status'], - 'expand': ['document_type'] - }, - 'patrons': { - 'order': ['roles'], - 'expand': ['roles'] - }, - 'persons': { - 'order': ['sources'], - 'expand': ['sources'] + 'order': [ + 'document_type', + 'library', + 'author', + 'language', + 'subject', + 'status', + ], + 'expand': ['document_type'], }, + 'patrons': {'order': ['roles'], 'expand': ['roles']}, + 'persons': {'order': ['sources'], 'expand': ['sources']}, } RECORDS_REST_FACETS = { @@ -540,20 +576,12 @@ def _(x): aggs=dict( years=dict( date_histogram=dict( - field='publicationYear', - interval='year', - format='yyyy', - ) - ), - document_type=dict( - terms=dict( - field='type', + field='publicationYear', interval='year', format='yyyy' ) ), + document_type=dict(terms=dict(field='type')), library=dict( - terms=dict( - field='itemslist.library_name', - ), + terms=dict(field='itemslist.library_name'), # aggs=dict( # location=dict( # terms=dict( @@ -562,26 +590,10 @@ def _(x): # ) # ) ), - author=dict( - terms=dict( - field='facet_authors', - ) - ), - language=dict( - terms=dict( - field='languages.language', - ) - ), - subject=dict( - terms=dict( - field='subject', - ) - ), - status=dict( - terms=dict( - field='itemslist._circulation.status', - ) - ), + author=dict(terms=dict(field='facet_authors')), + language=dict(terms=dict(field='languages.language')), + subject=dict(terms=dict(field='subject')), + status=dict(terms=dict(field='itemslist._circulation.status')), ), # can be also post_filter filters={ @@ -590,61 +602,39 @@ def _(x): _('author'): terms_filter('facet_authors'), _('language'): terms_filter('languages.language'), _('subject'): terms_filter('subject'), - _('status'): terms_filter('itemslist._circulation.status') + _('status'): terms_filter('itemslist._circulation.status'), }, post_filters={ _('years'): range_filter( - 'publicationYear', - format='yyyy', - end_date_math='/y' + 'publicationYear', format='yyyy', end_date_math='/y' ) - } + }, ), 'patrons': dict( - aggs=dict( - roles=dict( - terms=dict( - field='roles', - ) - ) - ), - filters={ - _('roles'): terms_filter('roles') - } + aggs=dict(roles=dict(terms=dict(field='roles'))), + filters={_('roles'): terms_filter('roles')}, ), 'persons': dict( - aggs=dict( - sources=dict( - terms=dict( - field='sources', - ) - ) - ), - filters={ - _('sources'): terms_filter('sources') - } - ) + aggs=dict(sources=dict(terms=dict(field='sources'))), + filters={_('sources'): terms_filter('sources')}, + ), } # sort RECORDS_REST_SORT_OPTIONS = { 'documents': dict( bestmatch=dict( - fields=['_score'], - title='Best match', - default_order='asc' + fields=['_score'], title='Best match', default_order='asc' ), mostrecent=dict( - fields=['-_created'], - title='Most recent', - default_order='desc' + fields=['-_created'], title='Most recent', default_order='desc' ), ) } # default sort RECORDS_REST_DEFAULT_SORT = { - 'documents': dict(query='bestmatch', noquery='mostrecent'), + 'documents': dict(query='bestmatch', noquery='mostrecent') } # Detailed View Configuration @@ -655,7 +645,7 @@ def _(x): route='/documents/', template='rero_ils/detailed_view_documents_items.html', view_imp='rero_ils.modules.documents_items.views.doc_item_view_method', - record_class='rero_ils.modules.documents_items.api:DocumentsWithItems' + record_class='rero_ils.modules.documents_items.api:DocumentsWithItems', ), 'doc_export': dict( pid_type='doc', @@ -669,21 +659,21 @@ def _(x): route='/organisations/', template='rero_ils/detailed_view_organisations_libraries.html', record_class='rero_ils.modules.organisations_libraries.api:OrganisationWithLibraries', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'lib': dict( pid_type='lib', route='/libraries/', template='rero_ils/detailed_view_libraries_locations.html', record_class='rero_ils.modules.libraries_locations.api:LibraryWithLocations', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'loc': dict( pid_type='loc', route='/locations/', template='rero_ils/detailed_view_locations.html', record_class='rero_ils.modules.locations.api:Location', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'item': dict( pid_type='item', @@ -691,29 +681,28 @@ def _(x): template='rero_ils/detailed_view_items.html', view_imp='rero_ils.modules.items.views.item_view_method', record_class='rero_ils.modules.items.api:Item', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'itty': dict( pid_type='itty', route='/items_types/', template='rero_ils/detailed_view_items_types.html', record_class='rero_ils.modules.items_types.api:ItemType', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'ptrn': dict( pid_type='ptrn', route='/patrons/', template='rero_ils/detailed_view_patrons.html', record_class='rero_ils.modules.patrons.api:Patron', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' - + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'ptty': dict( pid_type='ptty', route='/patrons_types/', template='rero_ils/detailed_view_patrons_types.html', record_class='rero_ils.modules.patrons_types.api:PatronType', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', ), 'pers': dict( pid_type='pers', @@ -726,16 +715,15 @@ def _(x): route='/circ_policies/', template='rero_ils/detailed_view_circ_policies.html', record_class='rero_ils.modules.circ_policies.api:CircPolicy', - permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory' - ) + permission_factory_imp='rero_ils.permissions.cataloguer_permission_factory', + ), } RECORDS_UI_EXPORT_FORMATS = { 'doc': { 'json': dict( title='JSON', - serializer='invenio_records_rest.serializers' - ':json_v1', + serializer='invenio_records_rest.serializers' ':json_v1', order=1, ) } @@ -750,37 +738,45 @@ def _(x): results_template='templates/rero_ils/brief_view_documents_items.html', editor_template='rero_ils/document_editor.html', schema='documents/document-v0.0.1.json', - form_options=('rero_ils.modules.documents.form_options', - 'documents/document-v0.0.1.json'), + form_options=( + 'rero_ils.modules.documents.form_options', + 'documents/document-v0.0.1.json', + ), record_class=DocumentsWithItems, - form_options_create_exclude=['pid'] + form_options_create_exclude=['pid'], ), _('item'): dict( editor_template='rero_ils/item_editor.html', schema='items/item-v0.0.1.json', - form_options=('rero_ils.modules.items.form_options', - 'items/item-v0.0.1.json'), + form_options=( + 'rero_ils.modules.items.form_options', + 'items/item-v0.0.1.json', + ), save_record='rero_ils.modules.documents_items.utils:save_item', delete_record='rero_ils.modules.documents_items.utils:delete_item', record_class=Item, - form_options_create_exclude=['pid'] + form_options_create_exclude=['pid'], ), _('itty'): dict( api='/api/items_types/', schema='items_types/item_type-v0.0.1.json', - form_options=('rero_ils.modules.items_types.form_options', - 'items_types/item_type-v0.0.1.json'), + form_options=( + 'rero_ils.modules.items_types.form_options', + 'items_types/item_type-v0.0.1.json', + ), save_record='rero_ils.modules.items_types.utils:save_item_type', editor_template='rero_ils/item_type_editor.html', results_template='templates/rero_ils/brief_view_items_types.html', record_class=ItemType, - form_options_create_exclude=['pid', 'organisation_pid'] + form_options_create_exclude=['pid', 'organisation_pid'], ), _('ptrn'): dict( api='/api/patrons/', schema='patrons/patron-v0.0.1.json', - form_options=('rero_ils.modules.patrons.form_options', - 'patrons/patron-v0.0.1.json'), + form_options=( + 'rero_ils.modules.patrons.form_options', + 'patrons/patron-v0.0.1.json', + ), save_record='rero_ils.modules.patrons.utils:save_patron', editor_template='rero_ils/patron_editor.html', results_template='templates/rero_ils/brief_view_patrons.html', @@ -789,63 +785,75 @@ def _(x): _('ptty'): dict( api='/api/patrons_types/', schema='patrons_types/patron_type-v0.0.1.json', - form_options=('rero_ils.modules.patrons_types.form_options', - 'patrons_types/patron_type-v0.0.1.json'), + form_options=( + 'rero_ils.modules.patrons_types.form_options', + 'patrons_types/patron_type-v0.0.1.json', + ), save_record='rero_ils.modules.patrons_types.utils:save_patron_type', editor_template='rero_ils/patron_type_editor.html', results_template='templates/rero_ils/brief_view_patrons_types.html', record_class=PatronType, - form_options_create_exclude=['pid', 'organisation_pid'] + form_options_create_exclude=['pid', 'organisation_pid'], ), _('org'): dict( schema='organisations/organisation-v0.0.1.json', - form_options=('rero_ils.modules.organisations.form_options', - 'organisations/organisation-v0.0.1.json'), + form_options=( + 'rero_ils.modules.organisations.form_options', + 'organisations/organisation-v0.0.1.json', + ), record_class=OrganisationWithLibraries, - form_options_create_exclude=['pid'] + form_options_create_exclude=['pid'], ), _('lib'): dict( api='/api/libraries/', results_template='templates/rero_ils/brief_view_libraries_locations.html', editor_template='rero_ils/library_editor.html', schema='libraries/library-v0.0.1.json', - form_options=('rero_ils.modules.libraries.form_options', - 'libraries/library-v0.0.1.json'), + form_options=( + 'rero_ils.modules.libraries.form_options', + 'libraries/library-v0.0.1.json', + ), save_record='rero_ils.modules.organisations_libraries.utils:save_library', delete_record='rero_ils.modules.organisations_libraries.utils:delete_library', record_class=LibraryWithLocations, - form_options_create_exclude=['pid'] + form_options_create_exclude=['pid'], ), _('loc'): dict( editor_template='rero_ils/location_editor.html', schema='locations/location-v0.0.1.json', - form_options=('rero_ils.modules.locations.form_options', - 'locations/location-v0.0.1.json'), + form_options=( + 'rero_ils.modules.locations.form_options', + 'locations/location-v0.0.1.json', + ), save_record='rero_ils.modules.libraries_locations.utils:save_location', delete_record='rero_ils.modules.libraries_locations.utils:delete_location', record_class=Location, - form_options_create_exclude=['pid'] + form_options_create_exclude=['pid'], ), _('pers'): dict( api='/api/persons/', results_template='templates/rero_ils/brief_view_mef_persons.html', editor_template='rero_ils/document_editor.html', schema='persons/mef-person-v0.0.1.json', - form_options=('rero_ils.modules.documents.form_options', - 'persons/mef-person-v0.0.1.json'), + form_options=( + 'rero_ils.modules.documents.form_options', + 'persons/mef-person-v0.0.1.json', + ), record_class=MefPerson, - can_create=lambda: False + can_create=lambda: False, ), _('cipo'): dict( api='/api/circ_policies/', schema='circ_policies/circ_policy-v0.0.1.json', - form_options=('rero_ils.modules.circ_policies.form_options', - 'circ_policies/circ_policy-v0.0.1.json'), + form_options=( + 'rero_ils.modules.circ_policies.form_options', + 'circ_policies/circ_policy-v0.0.1.json', + ), save_record='rero_ils.modules.circ_policies.utils:save_circ_policy', editor_template='rero_ils/circ_policy_editor.html', results_template='templates/rero_ils/brief_view_circ_policies.html', record_class=CircPolicy, - form_options_create_exclude=['pid', 'organisation_pid'] + form_options_create_exclude=['pid', 'organisation_pid'], ), } @@ -877,8 +885,13 @@ def _(x): # RERO Specific Configuration # =========================== RERO_ILS_BABEL_TRANSLATE_JSON_KEYS = [ - 'title', 'description', 'placeholder', - 'validationMessage', 'name', 'add', '403' + 'title', + 'description', + 'placeholder', + 'validationMessage', + 'name', + 'add', + '403', ] RERO_ILS_PERMALINK_RERO_URL = 'http://data.rero.ch/01-{identifier}' @@ -890,12 +903,11 @@ def _(x): #: RERO_ILS specific configurations. -RERO_ILS_APP_IMPORT_BNF_EAN = 'http://catalogue.bnf.fr/api/SRU?'\ - 'version=1.2&operation=searchRetrieve'\ - '&recordSchema=unimarcxchange&maximumRecords=1'\ - '&startRecord=1&query=bib.ean%%20all%%20"%s"' +RERO_ILS_APP_IMPORT_BNF_EAN = 'http://catalogue.bnf.fr/api/SRU?' 'version=1.2&operation=searchRetrieve' '&recordSchema=unimarcxchange&maximumRecords=1' '&startRecord=1&query=bib.ean%%20all%%20"%s"' -RERO_ILS_APP_HELP_PAGE = 'https://github.com/rero/rero-ils/wiki/Public-demo-help' +RERO_ILS_APP_HELP_PAGE = ( + 'https://github.com/rero/rero-ils/wiki/Public-demo-help' +) #: Cover service RERO_ILS_THUMBNAIL_SERVICE_URL = 'https://services.test.rero.ch/cover' @@ -907,8 +919,88 @@ def _(x): RERO_ILS_PERSONS_LABEL_ORDER = { 'fallback': 'fr', 'fr': ['rero', 'bnf', 'gnd'], - 'de': ['gnd', 'rero', 'bnf'] + 'de': ['gnd', 'rero', 'bnf'], } ADMIN_PERMISSION_FACTORY = 'rero_ils.permissions.admin_permission_factory' ADMIN_BASE_TEMPLATE = BASE_TEMPLATE + + +#: Invenio circulation configuration. +CIRCULATION_ITEM_EXISTS = Item.get_record_by_pid +CIRCULATION_PATRON_EXISTS = Patron.get_record_by_pid +CIRCULATION_STATES_ITEM_AVAILABLE = [ + 'ITEM_RETURNED', + 'CANCELLED', + 'ITEM_AT_DESK', + 'PENDING', +] +CIRCULATION_ITEM_LOCATION_RETRIEVER = Item.item_location_retriever +CIRCULATION_DOCUMENT_RETRIEVER_FROM_ITEM = ( + DocumentsWithItems.document_retriever +) +CIRCULATION_ITEMS_RETRIEVER_FROM_DOCUMENT = DocumentsWithItems.items_retriever + +CIRCULATION_LOAN_TRANSITIONS = { + 'CREATED': [ + dict(dest='PENDING', trigger='request', transition=CreatedToPending), + dict( + dest='ITEM_ON_LOAN', + trigger='checkout', + transition=CreatedToItemOnLoan, + ), + ], + 'PENDING': [ + dict( + dest='ITEM_AT_DESK', + transition=PendingToItemAtDesk, + trigger='validate', + ), + dict( + dest='ITEM_IN_TRANSIT_FOR_PICKUP', + transition=PendingToItemInTransitPickup, + trigger='validate', + ), + dict(dest='CANCELLED', trigger='cancel'), + ], + 'ITEM_AT_DESK': [ + dict( + dest='ITEM_ON_LOAN', + transition=ItemAtDeskToItemOnLoan, + trigger='checkout', + ), + dict(dest='CANCELLED', trigger='cancel'), + ], + 'ITEM_IN_TRANSIT_FOR_PICKUP': [ + dict(dest='ITEM_AT_DESK', trigger='receive'), + dict(dest='CANCELLED', trigger='cancel'), + ], + 'ITEM_ON_LOAN': [ + dict( + dest='ITEM_RETURNED', + transition=ItemOnLoanToItemReturned, + trigger='checkin', + ), + dict( + dest='ITEM_IN_TRANSIT_TO_HOUSE', + transition=ItemOnLoanToItemInTransitHouse, + trigger='checkin', + ), + dict( + dest='ITEM_ON_LOAN', + transition=ItemOnLoanToItemOnLoan, + trigger='extend', + ), + dict(dest='CANCELLED', trigger='cancel'), + ], + 'ITEM_IN_TRANSIT_TO_HOUSE': [ + dict( + dest='ITEM_RETURNED', + transition=ItemInTransitHouseToItemReturned, + trigger='checkin', + ), + dict(dest='CANCELLED', trigger='cancel'), + ], + 'ITEM_RETURNED': [], + 'CANCELLED': [], +} diff --git a/rero_ils/modules/documents_items/api.py b/rero_ils/modules/documents_items/api.py index d9c6ff6a96..e9a1f53e3d 100644 --- a/rero_ils/modules/documents_items/api.py +++ b/rero_ils/modules/documents_items/api.py @@ -134,3 +134,22 @@ def get_document_by_itemid(cls, id_, with_deleted=False): return super(DocumentsWithItems, cls).get_record_by_elementid( id_, with_deleted ) + + @classmethod + def document_retriever(cls, item_pid, **kwargs): + """Retrieve document pid from item pid.""" + document_pid = '' + if Item.get_record_by_pid(item_pid): + id = Item.get_record_by_pid(item_pid).id + document_pid = cls.get_document_by_itemid(id).pid + return document_pid + + @classmethod + def items_retriever(cls, document_pid): + """Retrieve item pids by document pid.""" + item_pids = [] + if cls.get_record_by_pid(document_pid): + document = cls.get_record_by_pid(document_pid) + for item in document.itemslist: + item_pids.append(item.get('pid')) + return item_pids diff --git a/rero_ils/modules/items/api.py b/rero_ils/modules/items/api.py index ded0a237af..4c637e8744 100644 --- a/rero_ils/modules/items/api.py +++ b/rero_ils/modules/items/api.py @@ -527,3 +527,13 @@ def loaned_to_patron(self, patron_barcode): if holding['patron_barcode'] == patron_barcode: return True return False + + @classmethod + def item_location_retriever(cls, item_pid, **kwargs): + """Get item location.""" + location_pid = '' + if cls.get_record_by_pid(item_pid): + item = cls.get_record_by_pid(item_pid) + if item.get('location_pid'): + location_pid = item.get('location_pid') + return location_pid