invenio-app-ils 1.0.0a54__py2.py3-none-any.whl → 6.1.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- invenio_app_ils/__init__.py +2 -2
- invenio_app_ils/acquisition/api.py +3 -1
- invenio_app_ils/acquisition/config.py +10 -21
- invenio_app_ils/acquisition/jsonresolvers/order_order_lines.py +1 -0
- invenio_app_ils/acquisition/mappings/os-v1/acq_orders/order-v1.0.0.json +364 -0
- invenio_app_ils/acquisition/mappings/os-v2/__init__.py +0 -0
- invenio_app_ils/acquisition/mappings/os-v2/acq_orders/order-v1.0.0.json +364 -0
- invenio_app_ils/acquisition/mappings/v7/acq_orders/order-v1.0.0.json +14 -0
- invenio_app_ils/acquisition/search.py +5 -15
- invenio_app_ils/assets/semantic-ui/less/theme.config +103 -0
- invenio_app_ils/assets/semantic-ui/templates/.gitkeep +0 -0
- invenio_app_ils/circulation/api.py +153 -67
- invenio_app_ils/circulation/config.py +29 -25
- invenio_app_ils/circulation/indexer.py +14 -19
- invenio_app_ils/circulation/loaders/__init__.py +2 -0
- invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py +2 -3
- invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +82 -16
- invenio_app_ils/circulation/loaders/schemas/json/loan_self_checkout.py +19 -0
- invenio_app_ils/circulation/notifications/api.py +23 -19
- invenio_app_ils/circulation/notifications/messages.py +6 -6
- invenio_app_ils/circulation/notifications/tasks.py +1 -2
- invenio_app_ils/circulation/receivers.py +2 -5
- invenio_app_ils/circulation/search.py +23 -22
- invenio_app_ils/circulation/serializers/__init__.py +2 -2
- invenio_app_ils/circulation/serializers/csv.py +1 -3
- invenio_app_ils/circulation/serializers/custom_fields.py +5 -9
- invenio_app_ils/circulation/serializers/json.py +2 -6
- invenio_app_ils/circulation/serializers/response.py +12 -12
- invenio_app_ils/circulation/stats/views.py +5 -15
- invenio_app_ils/circulation/tasks.py +2 -6
- invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/self_checkout.html +19 -0
- invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/update_dates.html +19 -0
- invenio_app_ils/circulation/utils.py +23 -17
- invenio_app_ils/circulation/views.py +103 -39
- invenio_app_ils/cli.py +220 -260
- invenio_app_ils/closures/api.py +72 -7
- invenio_app_ils/closures/serializers/__init__.py +16 -0
- invenio_app_ils/closures/serializers/response.py +35 -0
- invenio_app_ils/closures/serializers/schema.py +28 -0
- invenio_app_ils/closures/tasks.py +4 -11
- invenio_app_ils/closures/views.py +66 -0
- invenio_app_ils/config.py +207 -150
- invenio_app_ils/document_requests/api.py +6 -21
- invenio_app_ils/document_requests/loaders/__init__.py +4 -12
- invenio_app_ils/document_requests/mappings/{v6 → os-v1}/__init__.py +2 -2
- invenio_app_ils/document_requests/mappings/os-v1/document_requests/document_request-v1.0.0.json +196 -0
- invenio_app_ils/document_requests/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/document_requests/mappings/os-v2/document_requests/document_request-v1.0.0.json +196 -0
- invenio_app_ils/document_requests/notifications/api.py +2 -7
- invenio_app_ils/document_requests/notifications/messages.py +3 -7
- invenio_app_ils/document_requests/search.py +2 -6
- invenio_app_ils/document_requests/views.py +4 -10
- invenio_app_ils/documents/api.py +19 -25
- invenio_app_ils/documents/indexer.py +13 -20
- invenio_app_ils/documents/jsonresolvers/document_circulation.py +11 -33
- invenio_app_ils/documents/jsonresolvers/document_eitem.py +1 -0
- invenio_app_ils/documents/jsonresolvers/document_item.py +8 -9
- invenio_app_ils/documents/jsonresolvers/document_stock.py +7 -7
- invenio_app_ils/documents/loaders/jsonschemas/document.py +3 -14
- invenio_app_ils/documents/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/documents/mappings/os-v1/documents/document-v1.0.0.json +932 -0
- invenio_app_ils/documents/mappings/os-v1/documents/document-v2.0.0.json +1066 -0
- invenio_app_ils/documents/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/documents/mappings/os-v2/documents/document-v1.0.0.json +932 -0
- invenio_app_ils/documents/mappings/os-v2/documents/document-v2.0.0.json +1066 -0
- invenio_app_ils/documents/mappings/v7/documents/document-v1.0.0.json +102 -11
- invenio_app_ils/documents/mappings/v7/documents/document-v2.0.0.json +1066 -0
- invenio_app_ils/documents/schemas/documents/document-v2.0.0.json +732 -0
- invenio_app_ils/eitems/api.py +41 -7
- invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +6 -6
- invenio_app_ils/eitems/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v1.0.0.json +139 -0
- invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v2.0.0.json +142 -0
- invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v3.0.0.json +179 -0
- invenio_app_ils/{series/mappings/v6 → eitems/mappings/os-v2}/__init__.py +1 -1
- invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v1.0.0.json +139 -0
- invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v2.0.0.json +142 -0
- invenio_app_ils/eitems/mappings/os-v2/eitems/eitem-v3.0.0.json +179 -0
- invenio_app_ils/eitems/mappings/v7/eitems/eitem-v1.0.0.json +12 -2
- invenio_app_ils/eitems/mappings/v7/eitems/eitem-v2.0.0.json +142 -0
- invenio_app_ils/eitems/mappings/v7/eitems/eitem-v3.0.0.json +179 -0
- invenio_app_ils/eitems/schemas/eitems/eitem-v2.0.0.json +120 -0
- invenio_app_ils/eitems/schemas/eitems/eitem-v3.0.0.json +120 -0
- invenio_app_ils/eitems/search.py +3 -9
- invenio_app_ils/errors.py +119 -6
- invenio_app_ils/ext.py +15 -18
- invenio_app_ils/facets.py +13 -15
- invenio_app_ils/files/receivers.py +1 -1
- invenio_app_ils/files/views.py +1 -2
- invenio_app_ils/ill/api.py +1 -2
- invenio_app_ils/ill/config.py +10 -16
- invenio_app_ils/ill/jsonresolvers/borrowing_request_document.py +2 -3
- invenio_app_ils/ill/jsonresolvers/borrowing_request_patron.py +1 -3
- invenio_app_ils/ill/jsonresolvers/borrowing_request_provider.py +1 -3
- invenio_app_ils/ill/loaders/__init__.py +3 -9
- invenio_app_ils/ill/loaders/jsonschemas/patron_loan_actions.py +1 -8
- invenio_app_ils/ill/loaders/jsonschemas/patron_loan_extension_actions.py +3 -8
- invenio_app_ils/ill/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/ill/mappings/os-v1/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
- invenio_app_ils/{acquisition/mappings/v6 → ill/mappings/os-v2}/__init__.py +1 -1
- invenio_app_ils/ill/mappings/os-v2/ill_borrowing_requests/borrowing_request-v1.0.0.json +254 -0
- invenio_app_ils/ill/mappings/v7/ill_borrowing_requests/borrowing_request-v1.0.0.json +14 -0
- invenio_app_ils/ill/notifications/api.py +1 -4
- invenio_app_ils/ill/search.py +3 -9
- invenio_app_ils/ill/serializers/__init__.py +1 -3
- invenio_app_ils/ill/views.py +2 -4
- invenio_app_ils/internal_locations/api.py +1 -4
- invenio_app_ils/internal_locations/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/internal_locations/mappings/os-v1/internal_locations/internal_location-v1.0.0.json +108 -0
- invenio_app_ils/internal_locations/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/internal_locations/mappings/os-v2/internal_locations/internal_location-v1.0.0.json +108 -0
- invenio_app_ils/internal_locations/search.py +1 -3
- invenio_app_ils/items/api.py +18 -15
- invenio_app_ils/items/indexer.py +1 -3
- invenio_app_ils/items/jsonresolvers/item_document.py +1 -1
- invenio_app_ils/items/jsonresolvers/item_internal_location.py +2 -6
- invenio_app_ils/items/loaders/jsonschemas/items.py +2 -0
- {tests/api/circulation → invenio_app_ils/items/mappings/os-v1}/__init__.py +1 -1
- invenio_app_ils/items/mappings/os-v1/items/item-v1.0.0.json +285 -0
- invenio_app_ils/items/mappings/os-v1/items/item-v2.0.0.json +326 -0
- {tests/api/ill → invenio_app_ils/items/mappings/os-v2}/__init__.py +1 -1
- invenio_app_ils/items/mappings/os-v2/items/item-v1.0.0.json +285 -0
- invenio_app_ils/items/mappings/os-v2/items/item-v2.0.0.json +326 -0
- invenio_app_ils/items/mappings/v7/items/item-v1.0.0.json +11 -0
- invenio_app_ils/items/mappings/v7/items/item-v2.0.0.json +326 -0
- invenio_app_ils/items/schemas/items/item-v1.0.0.json +22 -0
- invenio_app_ils/items/schemas/items/item-v2.0.0.json +172 -0
- invenio_app_ils/items/search.py +18 -11
- invenio_app_ils/items/serializers/item.py +7 -6
- invenio_app_ils/literature/api.py +1 -3
- invenio_app_ils/literature/search.py +3 -5
- invenio_app_ils/literature/serializers/csv.py +1 -3
- invenio_app_ils/literature/serializers/json.py +1 -3
- invenio_app_ils/locations/api.py +2 -4
- invenio_app_ils/locations/indexer.py +3 -9
- invenio_app_ils/locations/loaders/__init__.py +1 -3
- invenio_app_ils/locations/loaders/jsonschemas/location.py +4 -11
- invenio_app_ils/locations/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/locations/mappings/os-v1/locations/location-v1.0.0.json +90 -0
- invenio_app_ils/locations/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/locations/mappings/os-v2/locations/location-v1.0.0.json +90 -0
- invenio_app_ils/notifications/messages.py +4 -3
- invenio_app_ils/notifications/tasks.py +1 -3
- invenio_app_ils/notifications/views.py +2 -2
- invenio_app_ils/patrons/anonymization.py +53 -32
- invenio_app_ils/patrons/api.py +3 -5
- invenio_app_ils/patrons/cli.py +1 -2
- invenio_app_ils/patrons/indexer.py +4 -13
- invenio_app_ils/patrons/mappings/os-v1/__init__.py +8 -0
- invenio_app_ils/patrons/mappings/os-v1/patrons/patron-v1.0.0.json +42 -0
- invenio_app_ils/patrons/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/patrons/mappings/os-v2/patrons/patron-v1.0.0.json +42 -0
- invenio_app_ils/patrons/views.py +4 -14
- invenio_app_ils/permissions.py +93 -35
- invenio_app_ils/providers/api.py +2 -6
- invenio_app_ils/providers/config.py +11 -19
- invenio_app_ils/providers/indexer.py +2 -6
- invenio_app_ils/providers/mappings/{v6 → os-v1}/__init__.py +1 -1
- invenio_app_ils/providers/mappings/os-v1/providers/provider-v1.0.0.json +57 -0
- invenio_app_ils/providers/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/providers/mappings/os-v2/providers/provider-v1.0.0.json +57 -0
- invenio_app_ils/providers/mappings/v7/__init__.py +1 -1
- invenio_app_ils/providers/proxies.py +1 -3
- invenio_app_ils/records/api.py +3 -9
- invenio_app_ils/records/loaders/schemas/changed_by.py +1 -3
- invenio_app_ils/records/loaders/schemas/identifiers.py +23 -0
- invenio_app_ils/records/metadata_extensions.py +1 -4
- invenio_app_ils/records/permissions.py +8 -2
- invenio_app_ils/records/serializers/__init__.py +1 -4
- invenio_app_ils/records/views.py +4 -7
- invenio_app_ils/records_relations/api.py +11 -34
- invenio_app_ils/records_relations/indexer.py +1 -3
- invenio_app_ils/records_relations/retriever.py +14 -9
- invenio_app_ils/records_relations/views.py +16 -50
- invenio_app_ils/relations/api.py +17 -16
- invenio_app_ils/search_permissions.py +24 -24
- invenio_app_ils/series/api.py +10 -12
- invenio_app_ils/series/loaders/jsonschemas/series.py +3 -2
- invenio_app_ils/{items/mappings/v6 → series/mappings/os-v1}/__init__.py +1 -1
- invenio_app_ils/series/mappings/os-v1/series/series-v1.0.0.json +324 -0
- invenio_app_ils/series/mappings/os-v1/series/series-v2.0.0.json +396 -0
- {tests/api/acquisition → invenio_app_ils/series/mappings/os-v2}/__init__.py +1 -1
- invenio_app_ils/series/mappings/os-v2/series/series-v1.0.0.json +324 -0
- invenio_app_ils/series/mappings/os-v2/series/series-v2.0.0.json +396 -0
- invenio_app_ils/series/mappings/v7/series/series-v1.0.0.json +35 -3
- invenio_app_ils/series/mappings/v7/series/series-v2.0.0.json +396 -0
- invenio_app_ils/series/schemas/series/series-v2.0.0.json +354 -0
- invenio_app_ils/stats/aggregations/aggr_file_download/os-v1/aggr-file-download-v1.json +60 -0
- invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/__init__.py +9 -0
- invenio_app_ils/stats/aggregations/aggr_file_download/os-v2/aggr-file-download-v1.json +60 -0
- invenio_app_ils/stats/event_builders.py +73 -0
- invenio_app_ils/stats/file_download/os-v1/file-download-v1.json +72 -0
- invenio_app_ils/stats/file_download/os-v2/__init__.py +9 -0
- invenio_app_ils/stats/file_download/os-v2/file-download-v1.json +72 -0
- invenio_app_ils/stats/processors.py +30 -0
- invenio_app_ils/stats/templates/aggregations/__init__.py +8 -0
- invenio_app_ils/stats/templates/aggregations/ils_record_changes/__init__.py +8 -0
- invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/__init__.py +8 -0
- invenio_app_ils/stats/templates/aggregations/ils_record_changes/os-v2/aggr-ils-record-changes-v1.json +41 -0
- {tests → invenio_app_ils/stats/templates/events}/__init__.py +2 -2
- invenio_app_ils/stats/templates/events/ils_record_changes/__init__.py +8 -0
- invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/__init__.py +8 -0
- invenio_app_ils/stats/templates/events/ils_record_changes/os-v2/ils-record-changes-v1.json +41 -0
- invenio_app_ils/templates/logged_out.html +12 -0
- invenio_app_ils/views.py +18 -4
- invenio_app_ils/vocabularies/api.py +1 -1
- invenio_app_ils/vocabularies/cli.py +6 -18
- invenio_app_ils/vocabularies/data/acq_order_line_payment_modes.json +5 -0
- invenio_app_ils/vocabularies/data/identifier_schemes.json +5 -0
- invenio_app_ils/vocabularies/indexer.py +1 -4
- invenio_app_ils/vocabularies/jsonresolvers/licenses.py +2 -11
- invenio_app_ils/vocabularies/mappings/os-v1/__init__.py +8 -0
- invenio_app_ils/vocabularies/mappings/os-v1/vocabularies/vocabulary-v1.0.0.json +23 -0
- invenio_app_ils/vocabularies/mappings/os-v2/__init__.py +8 -0
- invenio_app_ils/vocabularies/mappings/os-v2/vocabularies/vocabulary-v1.0.0.json +23 -0
- invenio_app_ils/vocabularies/sources/base.py +1 -3
- invenio_app_ils/webpack.py +27 -0
- invenio_app_ils-6.1.0.dist-info/METADATA +627 -0
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/RECORD +227 -249
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/WHEEL +1 -1
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/entry_points.txt +9 -5
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info}/top_level.txt +0 -1
- invenio_app_ils/acquisition/mappings/v6/acq_orders/order-v1.0.0.json +0 -352
- invenio_app_ils/document_requests/mappings/v6/document_requests/document_request-v1.0.0.json +0 -199
- invenio_app_ils/documents/mappings/v6/documents/document-v1.0.0.json +0 -843
- invenio_app_ils/eitems/mappings/v6/eitems/eitem-v1.0.0.json +0 -131
- invenio_app_ils/ill/mappings/v6/ill_borrowing_requests/borrowing_request-v1.0.0.json +0 -242
- invenio_app_ils/internal_locations/mappings/v6/internal_locations/internal_location-v1.0.0.json +0 -110
- invenio_app_ils/items/mappings/v6/items/item-v1.0.0.json +0 -276
- invenio_app_ils/locations/mappings/v6/locations/location-v1.0.0.json +0 -92
- invenio_app_ils/notifications/admin.py +0 -57
- invenio_app_ils/patrons/mappings/v6/__init__.py +0 -8
- invenio_app_ils/patrons/mappings/v6/patrons/patron-v1.0.0.json +0 -44
- invenio_app_ils/providers/mappings/v6/providers/provider-v1.0.0.json +0 -59
- invenio_app_ils/series/mappings/v6/series/series-v1.0.0.json +0 -298
- invenio_app_ils/stats/aggregations/aggr_file_download/v6/aggr-file-download-v1.json +0 -59
- invenio_app_ils/stats/file_download/v6/file-download-v1.json +0 -74
- invenio_app_ils/version.py +0 -14
- invenio_app_ils/vocabularies/mappings/v6/__init__.py +0 -8
- invenio_app_ils/vocabularies/mappings/v6/vocabularies/vocabulary-v1.0.0.json +0 -25
- invenio_app_ils-1.0.0a54.dist-info/METADATA +0 -95
- tests/api/__init__.py +0 -8
- tests/api/acquisition/test_acq_orders_crud.py +0 -102
- tests/api/acquisition/test_acq_orders_permissions.py +0 -104
- tests/api/acquisition/test_acq_providers_permissions.py +0 -83
- tests/api/circulation/test_expired_loans.py +0 -88
- tests/api/circulation/test_loan_checkout.py +0 -216
- tests/api/circulation/test_loan_default_durations.py +0 -57
- tests/api/circulation/test_loan_document_resolver.py +0 -18
- tests/api/circulation/test_loan_extend.py +0 -132
- tests/api/circulation/test_loan_item_permissions.py +0 -139
- tests/api/circulation/test_loan_item_resolver.py +0 -26
- tests/api/circulation/test_loan_list_permissions.py +0 -104
- tests/api/circulation/test_loan_patron_resolver.py +0 -38
- tests/api/circulation/test_loan_request.py +0 -234
- tests/api/circulation/test_loan_update.py +0 -150
- tests/api/circulation/test_notifications.py +0 -229
- tests/api/conftest.py +0 -236
- tests/api/document_requests/__init__.py +0 -8
- tests/api/document_requests/test_document_requests.py +0 -131
- tests/api/document_requests/test_document_requests_permissions.py +0 -177
- tests/api/document_requests/test_notifications_filter.py +0 -36
- tests/api/ill/test_ill_brw_crud.py +0 -84
- tests/api/ill/test_ill_brw_reqs_patron_loan_create_action.py +0 -207
- tests/api/ill/test_ill_brw_reqs_patron_loan_extension_actions.py +0 -298
- tests/api/ill/test_ill_brw_reqs_permissions.py +0 -169
- tests/api/ill/test_ill_providers_permissions.py +0 -82
- tests/api/ils/__init__.py +0 -8
- tests/api/ils/documents/__init__.py +0 -8
- tests/api/ils/documents/test_document_crud.py +0 -57
- tests/api/ils/documents/test_document_permissions.py +0 -106
- tests/api/ils/documents/test_document_resolvers.py +0 -35
- tests/api/ils/eitems/__init__.py +0 -8
- tests/api/ils/eitems/test_eitems_crud.py +0 -41
- tests/api/ils/eitems/test_eitems_permissions.py +0 -84
- tests/api/ils/eitems/test_files.py +0 -172
- tests/api/ils/items/__init__.py +0 -8
- tests/api/ils/items/test_apis.py +0 -43
- tests/api/ils/items/test_items_crud.py +0 -60
- tests/api/ils/items/test_items_permissions.py +0 -107
- tests/api/ils/items/test_items_update.py +0 -47
- tests/api/ils/records_relations/__init__.py +0 -8
- tests/api/ils/records_relations/helpers.py +0 -115
- tests/api/ils/records_relations/test_records_relations_parentchild.py +0 -560
- tests/api/ils/records_relations/test_records_relations_sequence.py +0 -302
- tests/api/ils/records_relations/test_records_relations_siblings.py +0 -678
- tests/api/ils/series/__init__.py +0 -8
- tests/api/ils/series/test_series_permissions.py +0 -95
- tests/api/ils/test_anonymization.py +0 -189
- tests/api/ils/test_apis.py +0 -76
- tests/api/ils/test_closures.py +0 -324
- tests/api/ils/test_errors.py +0 -126
- tests/api/ils/test_facets.py +0 -84
- tests/api/ils/test_internal_locations.py +0 -96
- tests/api/ils/test_loaders.py +0 -55
- tests/api/ils/test_metadata_extensions.py +0 -205
- tests/api/ils/test_notifications.py +0 -183
- tests/api/ils/test_notifications_mails.py +0 -39
- tests/api/ils/test_notifications_permissions.py +0 -55
- tests/api/ils/test_patrons.py +0 -106
- tests/api/ils/test_record_delete.py +0 -46
- tests/api/ils/test_record_permissions.py +0 -135
- tests/api/ils/test_resolvers.py +0 -207
- tests/api/ils/test_stats.py +0 -160
- tests/api/ils/test_tasks.py +0 -211
- tests/api/ils/test_vocabularies.py +0 -35
- tests/conftest.py +0 -123
- tests/data/acq_orders.json +0 -89
- tests/data/acq_providers.json +0 -12
- tests/data/document_requests.json +0 -77
- tests/data/documents.json +0 -237
- tests/data/eitems.json +0 -66
- tests/data/ill_borrowing_requests.json +0 -77
- tests/data/ill_providers.json +0 -12
- tests/data/internal_locations.json +0 -22
- tests/data/items.json +0 -271
- tests/data/loans.json +0 -133
- tests/data/loans_most_loaned.json +0 -128
- tests/data/locations.json +0 -20
- tests/data/series.json +0 -33
- tests/helpers.py +0 -104
- tests/templates/notifications/title_body.html +0 -8
- tests/templates/notifications/title_body_html.html +0 -13
- tests/templates/notifications/title_body_html_ctx.html +0 -13
- tests/templates/notifications/title_only.html +0 -3
- tests/test_version.py +0 -17
- /tests/templates/notifications/blank.html → /invenio_app_ils/acquisition/mappings/os-v1/__init__.py +0 -0
- /invenio_app_ils/stats/aggregations/aggr_file_download/{v6 → os-v1}/__init__.py +0 -0
- /invenio_app_ils/stats/file_download/{v6 → os-v1}/__init__.py +0 -0
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/AUTHORS.rst +0 -0
- {invenio_app_ils-1.0.0a54.dist-info → invenio_app_ils-6.1.0.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
#
|
|
3
|
-
# Copyright (C) 2018-
|
|
3
|
+
# Copyright (C) 2018-2025 CERN.
|
|
4
4
|
#
|
|
5
5
|
# invenio-app-ils is free software; you can redistribute it and/or modify it
|
|
6
6
|
# under the terms of the MIT License; see LICENSE file for more details.
|
|
@@ -12,7 +12,6 @@ from copy import copy, deepcopy
|
|
|
12
12
|
from datetime import date, timedelta
|
|
13
13
|
from functools import partial
|
|
14
14
|
|
|
15
|
-
from elasticsearch import VERSION as ES_VERSION
|
|
16
15
|
from flask import current_app
|
|
17
16
|
from flask_login import current_user
|
|
18
17
|
from invenio_circulation.config import (
|
|
@@ -27,14 +26,22 @@ from invenio_db import db
|
|
|
27
26
|
from invenio_pidstore.models import PIDStatus
|
|
28
27
|
from invenio_pidstore.providers.recordid_v2 import RecordIdProviderV2
|
|
29
28
|
|
|
29
|
+
from invenio_app_ils.circulation.notifications.api import (
|
|
30
|
+
send_dates_updated_notification,
|
|
31
|
+
)
|
|
30
32
|
from invenio_app_ils.circulation.search import (
|
|
31
|
-
|
|
33
|
+
get_all_expiring_or_overdue_loans_by_patron_pid,
|
|
32
34
|
)
|
|
33
35
|
from invenio_app_ils.errors import (
|
|
36
|
+
DocumentOverbookedError,
|
|
34
37
|
IlsException,
|
|
35
38
|
InvalidLoanExtendError,
|
|
36
39
|
InvalidParameterError,
|
|
40
|
+
ItemCannotCirculateError,
|
|
41
|
+
ItemHasActiveLoanError,
|
|
42
|
+
ItemNotFoundError,
|
|
37
43
|
MissingRequiredParameterError,
|
|
44
|
+
MultipleItemsBarcodeFoundError,
|
|
38
45
|
PatronHasLoanOnDocumentError,
|
|
39
46
|
PatronHasLoanOnItemError,
|
|
40
47
|
PatronHasRequestOnDocumentError,
|
|
@@ -44,9 +51,6 @@ from invenio_app_ils.items.api import Item
|
|
|
44
51
|
from invenio_app_ils.minters import pid_minter
|
|
45
52
|
from invenio_app_ils.proxies import current_app_ils
|
|
46
53
|
|
|
47
|
-
lt_es7 = ES_VERSION[0] < 7
|
|
48
|
-
|
|
49
|
-
|
|
50
54
|
# override default `invenio-circulation` minters to use the base32 PIDs
|
|
51
55
|
# CIRCULATION_LOAN_PID_TYPE is already defined in `invenio-circulation`
|
|
52
56
|
ILS_CIRCULATION_LOAN_MINTER = "ilsloanid"
|
|
@@ -55,9 +59,7 @@ ILS_CIRCULATION_LOAN_FETCHER = "ilsloanid"
|
|
|
55
59
|
IlsCirculationLoanIdProvider = type(
|
|
56
60
|
"IlsCirculationLoanIdProvider",
|
|
57
61
|
(RecordIdProviderV2,),
|
|
58
|
-
dict(
|
|
59
|
-
pid_type=CIRCULATION_LOAN_PID_TYPE, default_status=PIDStatus.REGISTERED
|
|
60
|
-
),
|
|
62
|
+
dict(pid_type=CIRCULATION_LOAN_PID_TYPE, default_status=PIDStatus.REGISTERED),
|
|
61
63
|
)
|
|
62
64
|
ils_circulation_loan_pid_minter = partial(
|
|
63
65
|
pid_minter, provider_cls=IlsCirculationLoanIdProvider
|
|
@@ -79,9 +81,9 @@ def _validate_delivery(delivery):
|
|
|
79
81
|
)
|
|
80
82
|
|
|
81
83
|
|
|
82
|
-
def _set_item_to_can_circulate(
|
|
84
|
+
def _set_item_to_can_circulate(item_pid_value):
|
|
83
85
|
"""Change the item status to CAN_CIRCULATE."""
|
|
84
|
-
item = Item.get_record_by_pid(
|
|
86
|
+
item = Item.get_record_by_pid(item_pid_value)
|
|
85
87
|
if item["status"] != "CAN_CIRCULATE":
|
|
86
88
|
item["status"] = "CAN_CIRCULATE"
|
|
87
89
|
item.commit()
|
|
@@ -91,16 +93,12 @@ def _set_item_to_can_circulate(item_pid):
|
|
|
91
93
|
|
|
92
94
|
def patron_has_request_on_document(patron_pid, document_pid):
|
|
93
95
|
"""Return loan request for given patron and document."""
|
|
94
|
-
states =
|
|
95
|
-
current_app.config["CIRCULATION_STATES_LOAN_REQUEST"]
|
|
96
|
-
)
|
|
96
|
+
states = current_app.config["CIRCULATION_STATES_LOAN_REQUEST"]
|
|
97
97
|
search = search_by_patron_item_or_document(
|
|
98
98
|
patron_pid=patron_pid, document_pid=document_pid, filter_states=states
|
|
99
99
|
)
|
|
100
100
|
search_result = search.execute()
|
|
101
|
-
total =
|
|
102
|
-
search_result.hits.total if lt_es7 else search_result.hits.total.value
|
|
103
|
-
)
|
|
101
|
+
total = search_result.hits.total.value
|
|
104
102
|
if total > 0:
|
|
105
103
|
return search_result.hits[0]
|
|
106
104
|
else:
|
|
@@ -117,9 +115,7 @@ def patron_has_active_loan_or_request_on_document(patron_pid, document_pid):
|
|
|
117
115
|
patron_pid=patron_pid, document_pid=document_pid, filter_states=states
|
|
118
116
|
)
|
|
119
117
|
search_result = search.execute()
|
|
120
|
-
total =
|
|
121
|
-
search_result.hits.total if lt_es7 else search_result.hits.total.value
|
|
122
|
-
)
|
|
118
|
+
total = search_result.hits.total.value
|
|
123
119
|
if total > 0:
|
|
124
120
|
return search_result.hits[0]
|
|
125
121
|
else:
|
|
@@ -131,7 +127,7 @@ def request_loan(
|
|
|
131
127
|
patron_pid,
|
|
132
128
|
transaction_location_pid,
|
|
133
129
|
transaction_user_pid=None,
|
|
134
|
-
**kwargs
|
|
130
|
+
**kwargs,
|
|
135
131
|
):
|
|
136
132
|
"""Create a new loan and trigger the first transition to PENDING."""
|
|
137
133
|
loan_cls = current_circulation.loan_record_cls
|
|
@@ -179,11 +175,48 @@ def patron_has_active_loan_on_item(patron_pid, item_pid):
|
|
|
179
175
|
filter_states=current_app.config["CIRCULATION_STATES_LOAN_ACTIVE"],
|
|
180
176
|
)
|
|
181
177
|
search_result = search.execute()
|
|
182
|
-
return
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
178
|
+
return search_result.hits.total.value > 0
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def _checkout_loan(
|
|
182
|
+
item_pid,
|
|
183
|
+
patron_pid,
|
|
184
|
+
transaction_location_pid,
|
|
185
|
+
trigger="checkout",
|
|
186
|
+
transaction_user_pid=None,
|
|
187
|
+
delivery=None,
|
|
188
|
+
**kwargs,
|
|
189
|
+
):
|
|
190
|
+
"""Checkout a loan."""
|
|
191
|
+
transaction_user_pid = transaction_user_pid or str(current_user.id)
|
|
192
|
+
loan_cls = current_circulation.loan_record_cls
|
|
193
|
+
# create a new loan
|
|
194
|
+
record_uuid = uuid.uuid4()
|
|
195
|
+
new_loan = dict(
|
|
196
|
+
patron_pid=patron_pid,
|
|
197
|
+
transaction_location_pid=transaction_location_pid,
|
|
198
|
+
transaction_user_pid=transaction_user_pid,
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
if delivery:
|
|
202
|
+
new_loan["delivery"] = delivery
|
|
203
|
+
# check if there is an existing request
|
|
204
|
+
loan = patron_has_request_on_document(patron_pid, kwargs.get("document_pid"))
|
|
205
|
+
if loan:
|
|
206
|
+
loan = loan_cls.get_record_by_pid(loan.pid)
|
|
207
|
+
pid = IlsCirculationLoanIdProvider.get(loan["pid"]).pid
|
|
208
|
+
loan.update(new_loan)
|
|
209
|
+
else:
|
|
210
|
+
pid = ils_circulation_loan_pid_minter(record_uuid, data=new_loan)
|
|
211
|
+
loan = loan_cls.create(data=new_loan, id_=record_uuid)
|
|
212
|
+
|
|
213
|
+
params = deepcopy(loan)
|
|
214
|
+
params.update(item_pid=item_pid, **kwargs)
|
|
215
|
+
|
|
216
|
+
loan = current_circulation.circulation.trigger(
|
|
217
|
+
loan, **dict(params, trigger=trigger)
|
|
186
218
|
)
|
|
219
|
+
return pid, loan
|
|
187
220
|
|
|
188
221
|
|
|
189
222
|
def checkout_loan(
|
|
@@ -192,7 +225,7 @@ def checkout_loan(
|
|
|
192
225
|
transaction_location_pid,
|
|
193
226
|
transaction_user_pid=None,
|
|
194
227
|
force=False,
|
|
195
|
-
**kwargs
|
|
228
|
+
**kwargs,
|
|
196
229
|
):
|
|
197
230
|
"""Create a new loan and trigger the first transition to ITEM_ON_LOAN.
|
|
198
231
|
|
|
@@ -207,61 +240,114 @@ def checkout_loan(
|
|
|
207
240
|
the checkout. If False, the checkout will fail when the item cannot
|
|
208
241
|
circulate.
|
|
209
242
|
"""
|
|
210
|
-
|
|
211
|
-
if patron_has_active_loan_on_item(
|
|
212
|
-
patron_pid=patron_pid, item_pid=item_pid
|
|
213
|
-
):
|
|
243
|
+
|
|
244
|
+
if patron_has_active_loan_on_item(patron_pid=patron_pid, item_pid=item_pid):
|
|
214
245
|
raise PatronHasLoanOnItemError(patron_pid, item_pid)
|
|
215
246
|
optional_delivery = kwargs.get("delivery")
|
|
216
247
|
if optional_delivery:
|
|
217
248
|
_validate_delivery(optional_delivery)
|
|
218
249
|
|
|
219
250
|
if force:
|
|
220
|
-
_set_item_to_can_circulate(item_pid)
|
|
251
|
+
_set_item_to_can_circulate(item_pid["value"])
|
|
221
252
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
new_loan = dict(
|
|
227
|
-
patron_pid=patron_pid,
|
|
228
|
-
transaction_location_pid=transaction_location_pid,
|
|
253
|
+
return _checkout_loan(
|
|
254
|
+
item_pid,
|
|
255
|
+
patron_pid,
|
|
256
|
+
transaction_location_pid,
|
|
229
257
|
transaction_user_pid=transaction_user_pid,
|
|
258
|
+
**kwargs,
|
|
230
259
|
)
|
|
231
260
|
|
|
232
|
-
# check if there is an existing request
|
|
233
|
-
loan = patron_has_request_on_document(
|
|
234
|
-
patron_pid, kwargs.get("document_pid")
|
|
235
|
-
)
|
|
236
|
-
if loan:
|
|
237
|
-
loan = loan_cls.get_record_by_pid(loan.pid)
|
|
238
|
-
pid = IlsCirculationLoanIdProvider.get(loan["pid"]).pid
|
|
239
|
-
loan.update(new_loan)
|
|
240
|
-
else:
|
|
241
|
-
pid = ils_circulation_loan_pid_minter(record_uuid, data=new_loan)
|
|
242
|
-
loan = loan_cls.create(data=new_loan, id_=record_uuid)
|
|
243
261
|
|
|
244
|
-
|
|
245
|
-
|
|
262
|
+
def _ensure_item_loanable_via_self_checkout(item_pid_value):
|
|
263
|
+
"""Self-checkout: return loanable item or raise when not loanable.
|
|
246
264
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
265
|
+
Implements the self-checkout rules to loan an item.
|
|
266
|
+
"""
|
|
267
|
+
item = current_app_ils.item_record_cls.get_record_by_pid(item_pid_value)
|
|
268
|
+
item_dict = item.replace_refs()
|
|
269
|
+
|
|
270
|
+
if item_dict["status"] == "MISSING":
|
|
271
|
+
_set_item_to_can_circulate(item_pid_value)
|
|
272
|
+
item = current_app_ils.item_record_cls.get_record_by_pid(item_pid_value)
|
|
273
|
+
item_dict = item.replace_refs()
|
|
274
|
+
|
|
275
|
+
if item_dict["status"] != "CAN_CIRCULATE":
|
|
276
|
+
raise ItemCannotCirculateError()
|
|
277
|
+
|
|
278
|
+
circulation_state = item_dict["circulation"].get("state")
|
|
279
|
+
has_active_loan = (
|
|
280
|
+
circulation_state and circulation_state in CIRCULATION_STATES_LOAN_ACTIVE
|
|
250
281
|
)
|
|
282
|
+
if has_active_loan:
|
|
283
|
+
raise ItemHasActiveLoanError(loan_pid=item_dict["circulation"]["loan_pid"])
|
|
284
|
+
|
|
285
|
+
document = current_app_ils.document_record_cls.get_record_by_pid(
|
|
286
|
+
item_dict["document_pid"]
|
|
287
|
+
)
|
|
288
|
+
document_dict = document.replace_refs()
|
|
289
|
+
if document_dict["circulation"].get("overbooked", False):
|
|
290
|
+
raise DocumentOverbookedError(
|
|
291
|
+
f"Cannot self-checkout the overbooked document {item_dict['document_pid']}"
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
return item
|
|
251
295
|
|
|
252
|
-
|
|
296
|
+
|
|
297
|
+
def self_checkout_get_item_by_barcode(barcode):
|
|
298
|
+
"""Search for an item by barcode.
|
|
299
|
+
|
|
300
|
+
:param barcode: the barcode of the item to search for
|
|
301
|
+
:return item: the item that was found, or raise in case of errors
|
|
302
|
+
"""
|
|
303
|
+
item_search = current_app_ils.item_search_cls()
|
|
304
|
+
items = item_search.search_by_barcode(barcode).execute()
|
|
305
|
+
if items.hits.total.value == 0:
|
|
306
|
+
raise ItemNotFoundError(barcode=barcode)
|
|
307
|
+
if items.hits.total.value > 1:
|
|
308
|
+
raise MultipleItemsBarcodeFoundError(barcode)
|
|
309
|
+
|
|
310
|
+
item_pid = items.hits[0].pid
|
|
311
|
+
item = _ensure_item_loanable_via_self_checkout(item_pid)
|
|
312
|
+
return item_pid, item
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def self_checkout(
|
|
316
|
+
item_pid, patron_pid, transaction_location_pid, transaction_user_pid=None, **kwargs
|
|
317
|
+
):
|
|
318
|
+
"""Perform self-checkout.
|
|
319
|
+
|
|
320
|
+
:param item_pid: a dict containing `value` and `type` fields to
|
|
321
|
+
uniquely identify the item.
|
|
322
|
+
:param patron_pid: the PID value of the patron
|
|
323
|
+
:param transaction_location_pid: the PID value of the location where the
|
|
324
|
+
checkout is performed
|
|
325
|
+
:param transaction_user_pid: the PID value of the user that performed the
|
|
326
|
+
checkout
|
|
327
|
+
"""
|
|
328
|
+
_ensure_item_loanable_via_self_checkout(item_pid["value"])
|
|
329
|
+
return _checkout_loan(
|
|
330
|
+
item_pid,
|
|
331
|
+
patron_pid,
|
|
332
|
+
transaction_location_pid,
|
|
333
|
+
transaction_user_pid=transaction_user_pid,
|
|
334
|
+
trigger="self_checkout",
|
|
335
|
+
delivery=dict(method="SELF-CHECKOUT"),
|
|
336
|
+
**kwargs,
|
|
337
|
+
)
|
|
253
338
|
|
|
254
339
|
|
|
255
340
|
def bulk_extend_loans(patron_pid, **kwargs):
|
|
256
341
|
"""Bulk extend qualified loans."""
|
|
257
342
|
loan_class = current_circulation.loan_record_cls
|
|
258
|
-
days = current_app.config["ILS_CIRCULATION_LOAN_WILL_EXPIRE_DAYS"]
|
|
259
343
|
|
|
260
|
-
loans_search =
|
|
261
|
-
|
|
344
|
+
loans_search = get_all_expiring_or_overdue_loans_by_patron_pid(
|
|
345
|
+
patron_pid=patron_pid
|
|
346
|
+
)
|
|
262
347
|
|
|
263
348
|
extended_loans = []
|
|
264
349
|
not_extended_loans = []
|
|
350
|
+
|
|
265
351
|
for loan in loans_search.scan():
|
|
266
352
|
loan_record = loan_class.get_record_by_pid(loan["pid"])
|
|
267
353
|
params = deepcopy(loan_record)
|
|
@@ -271,8 +357,8 @@ def bulk_extend_loans(patron_pid, **kwargs):
|
|
|
271
357
|
**dict(
|
|
272
358
|
params,
|
|
273
359
|
trigger="extend",
|
|
274
|
-
transition_kwargs=dict(send_notification=False)
|
|
275
|
-
)
|
|
360
|
+
transition_kwargs=dict(send_notification=False),
|
|
361
|
+
),
|
|
276
362
|
)
|
|
277
363
|
extended_loans.append(extended_loan)
|
|
278
364
|
except (CirculationException, InvalidLoanExtendError):
|
|
@@ -292,14 +378,12 @@ def update_dates_loan(
|
|
|
292
378
|
):
|
|
293
379
|
"""Updates the dates of a loan."""
|
|
294
380
|
state = record["state"]
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
or state in CIRCULATION_STATES_LOAN_COMPLETED
|
|
298
|
-
)
|
|
381
|
+
is_active = state in CIRCULATION_STATES_LOAN_ACTIVE
|
|
382
|
+
is_completed = state in CIRCULATION_STATES_LOAN_COMPLETED
|
|
299
383
|
|
|
300
384
|
data = copy(record)
|
|
301
385
|
|
|
302
|
-
if
|
|
386
|
+
if is_active or is_completed:
|
|
303
387
|
today = date.today().strftime("%Y-%m-%d")
|
|
304
388
|
if request_start_date or request_expire_date:
|
|
305
389
|
raise IlsException(
|
|
@@ -320,8 +404,7 @@ def update_dates_loan(
|
|
|
320
404
|
else: # Pending or cancelled
|
|
321
405
|
if start_date or end_date:
|
|
322
406
|
raise IlsException(
|
|
323
|
-
description="Cannot modify dates of "
|
|
324
|
-
"a pending or cancelled loan."
|
|
407
|
+
description="Cannot modify dates of " "a pending or cancelled loan."
|
|
325
408
|
)
|
|
326
409
|
if request_start_date:
|
|
327
410
|
data["request_start_date"] = request_start_date
|
|
@@ -335,6 +418,9 @@ def update_dates_loan(
|
|
|
335
418
|
db.session.commit()
|
|
336
419
|
current_circulation.loan_indexer().index(record)
|
|
337
420
|
|
|
421
|
+
if is_active:
|
|
422
|
+
send_dates_updated_notification(record)
|
|
423
|
+
|
|
338
424
|
return record
|
|
339
425
|
|
|
340
426
|
|
|
@@ -41,7 +41,7 @@ from invenio_app_ils.items.api import (
|
|
|
41
41
|
)
|
|
42
42
|
from invenio_app_ils.patrons.api import patron_exists
|
|
43
43
|
from invenio_app_ils.permissions import (
|
|
44
|
-
|
|
44
|
+
PatronOwnerReadPermission,
|
|
45
45
|
authenticated_user_permission,
|
|
46
46
|
backoffice_permission,
|
|
47
47
|
loan_extend_circulation_permission,
|
|
@@ -51,11 +51,7 @@ from invenio_app_ils.permissions import (
|
|
|
51
51
|
|
|
52
52
|
from .api import ILS_CIRCULATION_LOAN_FETCHER, ILS_CIRCULATION_LOAN_MINTER
|
|
53
53
|
from .indexer import LoanIndexer
|
|
54
|
-
from .jsonresolvers.loan import
|
|
55
|
-
document_resolver,
|
|
56
|
-
item_resolver,
|
|
57
|
-
loan_patron_resolver,
|
|
58
|
-
)
|
|
54
|
+
from .jsonresolvers.loan import document_resolver, item_resolver, loan_patron_resolver
|
|
59
55
|
from .notifications.api import circulation_filter_notifications
|
|
60
56
|
from .transitions.transitions import ILSItemOnLoanToItemOnLoan, ILSToItemOnLoan
|
|
61
57
|
from .utils import (
|
|
@@ -78,13 +74,17 @@ from .utils import (
|
|
|
78
74
|
ILS_CIRCULATION_NOTIFICATION_OVERDUE_REMINDER_INTERVAL = 3
|
|
79
75
|
#: The maximum duration of a loan request
|
|
80
76
|
ILS_CIRCULATION_LOAN_REQUEST_DURATION_DAYS = 60
|
|
77
|
+
#: The minimum number of days after which a loan can start from the date of request
|
|
78
|
+
ILS_CIRCULATION_LOAN_REQUEST_OFFSET = 0
|
|
81
79
|
#: Period of time in days, before loans expire, for notifications etc.
|
|
82
80
|
ILS_CIRCULATION_LOAN_WILL_EXPIRE_DAYS = 7
|
|
83
81
|
#: Optional delivery methods when requesting a new loan. Set to empty object to
|
|
84
82
|
# disable it
|
|
85
83
|
ILS_CIRCULATION_DELIVERY_METHODS = {
|
|
84
|
+
"NOT-SPECIFIED": "Not specified",
|
|
86
85
|
"PICKUP": "Pick it up at the library desk",
|
|
87
86
|
"DELIVERY": "Have it delivered to my office",
|
|
87
|
+
"SELF-CHECKOUT": "Self-checkout",
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
# Notification message creator for loan notifications
|
|
@@ -109,9 +109,7 @@ CIRCULATION_DOCUMENT_EXISTS = document_exists
|
|
|
109
109
|
|
|
110
110
|
CIRCULATION_ITEM_LOCATION_RETRIEVER = circulation_item_location_retriever
|
|
111
111
|
|
|
112
|
-
CIRCULATION_TRANSACTION_LOCATION_VALIDATOR =
|
|
113
|
-
circulation_transaction_location_validator
|
|
114
|
-
)
|
|
112
|
+
CIRCULATION_TRANSACTION_LOCATION_VALIDATOR = circulation_transaction_location_validator
|
|
115
113
|
|
|
116
114
|
CIRCULATION_TRANSACTION_USER_VALIDATOR = circulation_transaction_user_validator
|
|
117
115
|
|
|
@@ -134,9 +132,7 @@ CIRCULATION_POLICIES = dict(
|
|
|
134
132
|
|
|
135
133
|
CIRCULATION_ITEM_REF_BUILDER = circulation_build_item_ref
|
|
136
134
|
|
|
137
|
-
CIRCULATION_ITEM_RESOLVING_PATH =
|
|
138
|
-
"/api/resolver/circulation/loans/<loan_pid>/item"
|
|
139
|
-
)
|
|
135
|
+
CIRCULATION_ITEM_RESOLVING_PATH = "/api/resolver/circulation/loans/<loan_pid>/item"
|
|
140
136
|
|
|
141
137
|
CIRCULATION_ITEM_RESOLVER_ENDPOINT = item_resolver
|
|
142
138
|
|
|
@@ -150,9 +146,7 @@ CIRCULATION_DOCUMENT_RESOLVER_ENDPOINT = document_resolver
|
|
|
150
146
|
|
|
151
147
|
CIRCULATION_PATRON_REF_BUILDER = circulation_build_patron_ref
|
|
152
148
|
|
|
153
|
-
CIRCULATION_PATRON_RESOLVING_PATH =
|
|
154
|
-
"/api/resolver/circulation/loans/<loan_pid>/patron"
|
|
155
|
-
)
|
|
149
|
+
CIRCULATION_PATRON_RESOLVING_PATH = "/api/resolver/circulation/loans/<loan_pid>/patron"
|
|
156
150
|
|
|
157
151
|
CIRCULATION_PATRON_RESOLVER_ENDPOINT = loan_patron_resolver
|
|
158
152
|
|
|
@@ -171,6 +165,12 @@ CIRCULATION_LOAN_TRANSITIONS = {
|
|
|
171
165
|
transition=ILSToItemOnLoan,
|
|
172
166
|
permission_factory=backoffice_permission,
|
|
173
167
|
),
|
|
168
|
+
dict(
|
|
169
|
+
dest="ITEM_ON_LOAN",
|
|
170
|
+
trigger="self_checkout",
|
|
171
|
+
transition=ILSToItemOnLoan,
|
|
172
|
+
permission_factory=authenticated_user_permission,
|
|
173
|
+
),
|
|
174
174
|
],
|
|
175
175
|
"PENDING": [
|
|
176
176
|
dict(
|
|
@@ -179,6 +179,12 @@ CIRCULATION_LOAN_TRANSITIONS = {
|
|
|
179
179
|
transition=ILSToItemOnLoan,
|
|
180
180
|
permission_factory=backoffice_permission,
|
|
181
181
|
),
|
|
182
|
+
dict(
|
|
183
|
+
dest="ITEM_ON_LOAN",
|
|
184
|
+
trigger="self_checkout",
|
|
185
|
+
transition=ILSToItemOnLoan,
|
|
186
|
+
permission_factory=authenticated_user_permission,
|
|
187
|
+
),
|
|
182
188
|
dict(
|
|
183
189
|
dest="CANCELLED",
|
|
184
190
|
trigger="cancel",
|
|
@@ -225,9 +231,7 @@ ILS_CIRCULATION_RECORDS_REST_ENDPOINTS = dict(
|
|
|
225
231
|
record_class=Loan,
|
|
226
232
|
indexer_class=LoanIndexer,
|
|
227
233
|
record_loaders={
|
|
228
|
-
"application/json":
|
|
229
|
-
"invenio_circulation.records.loaders:loan_loader"
|
|
230
|
-
)
|
|
234
|
+
"application/json": "invenio_circulation.records.loaders:loan_loader"
|
|
231
235
|
},
|
|
232
236
|
record_serializers={
|
|
233
237
|
"application/json": (
|
|
@@ -238,19 +242,19 @@ ILS_CIRCULATION_RECORDS_REST_ENDPOINTS = dict(
|
|
|
238
242
|
"application/json": (
|
|
239
243
|
"invenio_app_ils.circulation.serializers:json_v1_search"
|
|
240
244
|
),
|
|
241
|
-
"text/csv":
|
|
242
|
-
|
|
243
|
-
|
|
245
|
+
"text/csv": "invenio_app_ils.circulation.serializers:csv_v1_search",
|
|
246
|
+
},
|
|
247
|
+
search_serializers_aliases={
|
|
248
|
+
"csv": "text/csv",
|
|
249
|
+
"json": "application/json",
|
|
244
250
|
},
|
|
245
251
|
list_route="/circulation/loans/",
|
|
246
|
-
item_route="/circulation/loans/<{0}:pid_value>".format(
|
|
247
|
-
_LOANID_CONVERTER
|
|
248
|
-
),
|
|
252
|
+
item_route="/circulation/loans/<{0}:pid_value>".format(_LOANID_CONVERTER),
|
|
249
253
|
default_media_type="application/json",
|
|
250
254
|
links_factory_imp="invenio_circulation.links:loan_links_factory",
|
|
251
255
|
max_result_window=RECORDS_REST_MAX_RESULT_WINDOW,
|
|
252
256
|
error_handlers=dict(),
|
|
253
|
-
read_permission_factory_imp=
|
|
257
|
+
read_permission_factory_imp=PatronOwnerReadPermission,
|
|
254
258
|
# auth via search_factory
|
|
255
259
|
list_permission_factory_imp=authenticated_user_permission,
|
|
256
260
|
create_permission_factory_imp=superuser_permission,
|
|
@@ -14,6 +14,7 @@ from flask import current_app
|
|
|
14
14
|
from invenio_circulation.pidstore.pids import CIRCULATION_LOAN_PID_TYPE
|
|
15
15
|
from invenio_circulation.proxies import current_circulation
|
|
16
16
|
from invenio_indexer.api import RecordIndexer
|
|
17
|
+
from invenio_pidstore.errors import PIDDeletedError
|
|
17
18
|
|
|
18
19
|
from invenio_app_ils.circulation.utils import resolve_item_from_loan
|
|
19
20
|
from invenio_app_ils.documents.api import DOCUMENT_PID_TYPE
|
|
@@ -48,20 +49,15 @@ def index_referenced_records(loan):
|
|
|
48
49
|
loan_class = current_circulation.loan_record_cls
|
|
49
50
|
loan_record = loan_class.get_record_by_pid(loan["pid"])
|
|
50
51
|
|
|
51
|
-
referenced.append(
|
|
52
|
-
dict(pid_type=CIRCULATION_LOAN_PID_TYPE, record=loan_record)
|
|
53
|
-
)
|
|
52
|
+
referenced.append(dict(pid_type=CIRCULATION_LOAN_PID_TYPE, record=loan_record))
|
|
54
53
|
|
|
55
54
|
# add all the other loans, as after indexing this one, they
|
|
56
55
|
# will be affected in search
|
|
57
|
-
pending_loans =
|
|
58
|
-
document.search_loan_references().scan()
|
|
56
|
+
pending_loans = document.search_loan_references().scan()
|
|
59
57
|
|
|
60
58
|
for loan_hit in pending_loans:
|
|
61
59
|
pending_loan = loan_class.get_record_by_pid(loan_hit.pid)
|
|
62
|
-
referenced.append(
|
|
63
|
-
dict(pid_type=CIRCULATION_LOAN_PID_TYPE, record=pending_loan)
|
|
64
|
-
)
|
|
60
|
+
referenced.append(dict(pid_type=CIRCULATION_LOAN_PID_TYPE, record=pending_loan))
|
|
65
61
|
|
|
66
62
|
# index the loan and referenced records
|
|
67
63
|
indexer.index(indexed, referenced)
|
|
@@ -86,19 +82,18 @@ def index_extra_fields_for_loan(loan_dict):
|
|
|
86
82
|
details.
|
|
87
83
|
"""
|
|
88
84
|
document_class = current_app_ils.document_record_cls
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
85
|
+
try:
|
|
86
|
+
document_record = document_class.get_record_by_pid(loan_dict["document_pid"])
|
|
87
|
+
except PIDDeletedError:
|
|
88
|
+
# Document might have been deleted while reindexing asynchronously.
|
|
89
|
+
return
|
|
90
|
+
|
|
92
91
|
document = document_record.replace_refs()
|
|
93
92
|
|
|
94
|
-
items_available_for_loan_count = document
|
|
95
|
-
"available_items_for_loan_count"
|
|
96
|
-
)
|
|
97
|
-
loan_dict[
|
|
93
|
+
items_available_for_loan_count = document["circulation"][
|
|
98
94
|
"available_items_for_loan_count"
|
|
99
|
-
]
|
|
95
|
+
]
|
|
96
|
+
loan_dict["available_items_for_loan_count"] = items_available_for_loan_count
|
|
100
97
|
|
|
101
|
-
can_circulate_items_count = document
|
|
102
|
-
"can_circulate_items_count"
|
|
103
|
-
)
|
|
98
|
+
can_circulate_items_count = document["circulation"]["can_circulate_items_count"]
|
|
104
99
|
loan_dict["can_circulate_items_count"] = can_circulate_items_count
|
|
@@ -12,9 +12,11 @@ from invenio_app_ils.records.loaders import ils_marshmallow_loader
|
|
|
12
12
|
from .schemas.json.bulk_extend import BulkExtendLoansSchemaV1
|
|
13
13
|
from .schemas.json.loan_checkout import LoanCheckoutSchemaV1
|
|
14
14
|
from .schemas.json.loan_request import LoanRequestSchemaV1
|
|
15
|
+
from .schemas.json.loan_self_checkout import LoanSelfCheckoutSchemaV1
|
|
15
16
|
from .schemas.json.loan_update_dates import LoanUpdateDatesSchemaV1
|
|
16
17
|
|
|
17
18
|
loan_request_loader = ils_marshmallow_loader(LoanRequestSchemaV1)
|
|
18
19
|
loan_checkout_loader = ils_marshmallow_loader(LoanCheckoutSchemaV1)
|
|
20
|
+
loan_self_checkout_loader = ils_marshmallow_loader(LoanSelfCheckoutSchemaV1)
|
|
19
21
|
loan_update_dates_loader = ils_marshmallow_loader(LoanUpdateDatesSchemaV1)
|
|
20
22
|
loans_bulk_update_loader = ils_marshmallow_loader(BulkExtendLoansSchemaV1)
|
|
@@ -26,7 +26,7 @@ class LoanCheckoutSchemaV1(LoanBaseSchemaV1):
|
|
|
26
26
|
item_pid = fields.Nested(LoanItemPIDSchemaV1, required=True)
|
|
27
27
|
start_date = DateString()
|
|
28
28
|
end_date = DateString()
|
|
29
|
-
force = fields.Bool(
|
|
29
|
+
force = fields.Bool(load_default=False)
|
|
30
30
|
|
|
31
31
|
@validates("force")
|
|
32
32
|
def validate_force(self, value, **kwargs):
|
|
@@ -57,8 +57,7 @@ class LoanCheckoutSchemaV1(LoanBaseSchemaV1):
|
|
|
57
57
|
"The loan start date cannot be after the end date."
|
|
58
58
|
],
|
|
59
59
|
"end_date": [
|
|
60
|
-
"The loan end date cannot"
|
|
61
|
-
" be before the start date."
|
|
60
|
+
"The loan end date cannot" " be before the start date."
|
|
62
61
|
],
|
|
63
62
|
}
|
|
64
63
|
)
|