invenio-app-ils 4.1.0__py2.py3-none-any.whl → 4.3.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.
Files changed (36) hide show
  1. invenio_app_ils/__init__.py +1 -1
  2. invenio_app_ils/circulation/api.py +123 -26
  3. invenio_app_ils/circulation/config.py +14 -2
  4. invenio_app_ils/circulation/loaders/__init__.py +2 -0
  5. invenio_app_ils/circulation/loaders/schemas/json/loan_request.py +2 -1
  6. invenio_app_ils/circulation/loaders/schemas/json/loan_self_checkout.py +19 -0
  7. invenio_app_ils/circulation/notifications/messages.py +1 -0
  8. invenio_app_ils/circulation/serializers/__init__.py +1 -0
  9. invenio_app_ils/circulation/serializers/response.py +1 -0
  10. invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/self_checkout.html +19 -0
  11. invenio_app_ils/circulation/views.py +100 -12
  12. invenio_app_ils/documents/jsonresolvers/document_stock.py +1 -1
  13. invenio_app_ils/documents/loaders/jsonschemas/document.py +1 -1
  14. invenio_app_ils/eitems/loaders/jsonschemas/eitems.py +1 -1
  15. invenio_app_ils/errors.py +103 -4
  16. invenio_app_ils/items/api.py +13 -1
  17. invenio_app_ils/items/loaders/jsonschemas/items.py +1 -1
  18. invenio_app_ils/items/search.py +13 -0
  19. invenio_app_ils/items/serializers/item.py +4 -4
  20. invenio_app_ils/patrons/anonymization.py +39 -9
  21. invenio_app_ils/permissions.py +49 -36
  22. invenio_app_ils/records/views.py +1 -1
  23. invenio_app_ils/records_relations/api.py +1 -0
  24. invenio_app_ils/relations/api.py +6 -1
  25. invenio_app_ils/series/loaders/jsonschemas/series.py +1 -1
  26. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/METADATA +16 -5
  27. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/RECORD +35 -34
  28. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/WHEEL +1 -1
  29. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/entry_points.txt +0 -1
  30. tests/api/circulation/test_loan_checkout.py +171 -66
  31. tests/api/ils/items/test_items_crud.py +46 -4
  32. tests/data/items.json +49 -27
  33. tests/api/ils/items/test_items_update.py +0 -40
  34. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/AUTHORS.rst +0 -0
  35. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/LICENSE +0 -0
  36. {invenio_app_ils-4.1.0.dist-info → invenio_app_ils-4.3.0.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
- invenio_app_ils/__init__.py,sha256=PIW53N5-l4TsnmnQRYUWVI9NhFBFLNMxAuVLWTbiZe4,285
1
+ invenio_app_ils/__init__.py,sha256=6gWxo9rLMZiagc6YQ3hrsD3hvU6dCPhFUpv2GiX99LI,285
2
2
  invenio_app_ils/cli.py,sha256=wD-SSrkbEhsndI7N9E39p-T1MXj8LR8pvsWFH-JHHVA,57478
3
3
  invenio_app_ils/config.py,sha256=b-3nNceV4s93eS-AS3WEj9eMopROa2hEZ7BI5jDnlAg,40857
4
- invenio_app_ils/errors.py,sha256=eXG53KxCnoC0KH9xAjHbu-U2zIsJG28GNPn9PwLTEfk,10486
4
+ invenio_app_ils/errors.py,sha256=HB_iWj-aYxzTzzO6hWb66mUPZdqpWYHgmr2H2t3j3wU,13293
5
5
  invenio_app_ils/ext.py,sha256=SULPfx1FxBLaOaKcyNKAAIyvZAuvTH3AcH_a8aXTSYo,11522
6
6
  invenio_app_ils/facets.py,sha256=x-ID7vL34zqbxJi7VC3EJSee13l_Jk0CfPZN3RHZrM8,4207
7
7
  invenio_app_ils/fetchers.py,sha256=GY5A6BXaqMB9HKvJuTcio3JYoF15t6eqMo3yzQKTqac,520
8
8
  invenio_app_ils/indexer.py,sha256=ngXRx2liufDzgsSIoCeusk6q0Y1uskQ3QiVLeAi3KRg,2212
9
9
  invenio_app_ils/minters.py,sha256=8JW-45fL9Oy_13eZjlk8kL_12jJGZK59qbKlCeseQgA,537
10
- invenio_app_ils/permissions.py,sha256=Uj8QUvCNkh7imfZEgZU6VXezrwKQVZBYzipnfZbS58o,6759
10
+ invenio_app_ils/permissions.py,sha256=WVe8TW4oHTIpep6cYS8Byawn6QsrduxiGLkuf5TrSWM,6928
11
11
  invenio_app_ils/proxies.py,sha256=IGBwXQSOxpXHjD8PWFG1nqUm70xGAgzWT8Y0AKdCGiI,453
12
12
  invenio_app_ils/search_permissions.py,sha256=KxkzgzSz3yabcDMffrsQag4TqZac0w1TBzntb7zjmOQ,5058
13
13
  invenio_app_ils/signals.py,sha256=KaN8yQUVq-2O2IKQQvPLtMjqp1S3AU1LYPlRyw9U8Pg,395
@@ -35,33 +35,34 @@ invenio_app_ils/acquisition/mappings/v7/acq_orders/order-v1.0.0.json,sha256=KMaS
35
35
  invenio_app_ils/acquisition/schemas/__init__.py,sha256=HulLvvDz0W5owDGxVLIaastuZ4o6T5-MYGw0RPuY90g,233
36
36
  invenio_app_ils/acquisition/schemas/acq_orders/order-v1.0.0.json,sha256=_Kd3oX_7gJJQSqSc2TxQulXletYu0wEeTdQKkXr7kLs,5688
37
37
  invenio_app_ils/circulation/__init__.py,sha256=Gd0KAsGdhPdz0ACEQ9k8xSeOIxZr3xRK_FiE8U3RQWs,248
38
- invenio_app_ils/circulation/api.py,sha256=so7YAlzXoO46nMwnXiKoaGgsQHr4OXwOJeUKYe88p0w,11220
39
- invenio_app_ils/circulation/config.py,sha256=VbRT8DDM-8Drtk333CF-7N67AA6YF9oBOEtcB8oxacE,10988
38
+ invenio_app_ils/circulation/api.py,sha256=wUiRoPF7-tdUg-XsIhNfTSJ4-nF3sOxRTdxVF0JuDdo,14257
39
+ invenio_app_ils/circulation/config.py,sha256=aVl7kLA2fobQuQy2XR9J_fQMV-ZaVxE2niMSTirDQM0,11387
40
40
  invenio_app_ils/circulation/indexer.py,sha256=T24J5QqcB38LRJgirkAXL2tmFOucYToDRegxgFW96ag,3887
41
41
  invenio_app_ils/circulation/receivers.py,sha256=Ux6KTNbII3DHBvCUS0gxqbi6tNbm76_kbcaHtK0BsB4,2488
42
42
  invenio_app_ils/circulation/search.py,sha256=l9DAr9uoaF_JbfiiXVpAFKW3NLv9bgs7D-uDwtU-fv0,6105
43
43
  invenio_app_ils/circulation/tasks.py,sha256=w4lpbQo78aDg_vgdzQoRVe1y1NjCKrz1xNlLl5RDgs0,1515
44
44
  invenio_app_ils/circulation/utils.py,sha256=pMFIzXQTDwqCvGS723aj9YzyixgK-3rDljrYNOIw_X4,4445
45
- invenio_app_ils/circulation/views.py,sha256=KZT2ietMHJS28WlonGav5LKXpfJeH4cCN3hq7cNXYh8,7046
45
+ invenio_app_ils/circulation/views.py,sha256=4yjKK6glyz-7AFkbt-m3VdGEcP2xI1VJ74eae2o6r6s,10138
46
46
  invenio_app_ils/circulation/jsonresolvers/__init__.py,sha256=pLBaAkmp3hJv_jaG986E5e0oDuKZ9pgl7Ax_OLcYiig,246
47
47
  invenio_app_ils/circulation/jsonresolvers/loan.py,sha256=gq99aOhpFunb5Qhb1oeQrFklAF7x9pZris5UcxmskHY,2635
48
- invenio_app_ils/circulation/loaders/__init__.py,sha256=3ZPsNNbs_T5dPOWVE2KHu_X-VJ2YPPe_6-sm7ZJJSbE,853
48
+ invenio_app_ils/circulation/loaders/__init__.py,sha256=qEOh1dDWZ9JmC0-8bbAxf1Q0otLvJe6ACP_L24_loEU,1000
49
49
  invenio_app_ils/circulation/loaders/schemas/__init__.py,sha256=l2qiAyJt9QqFyDqfa7qeMr8lgE3oVezXczgm_HbqeP0,257
50
50
  invenio_app_ils/circulation/loaders/schemas/json/__init__.py,sha256=wsV4twVnMDNWhWYM8Iu_v3y68JVEKPFOKRi5gJ5qT1I,262
51
51
  invenio_app_ils/circulation/loaders/schemas/json/base.py,sha256=lkOTJT6pPbukEjwVXEDaFxA7ruslxO3WyQlNuQpiv-U,1444
52
52
  invenio_app_ils/circulation/loaders/schemas/json/bulk_extend.py,sha256=nDqWF2cwiO2GHwPVO6ivPIya6g2AHQ-pZnQoo9e9fQs,638
53
53
  invenio_app_ils/circulation/loaders/schemas/json/loan_checkout.py,sha256=ijIJ-SLgKOutuGrNtWerB9OmIfk7nVPCoFlaocBhUFg,2147
54
- invenio_app_ils/circulation/loaders/schemas/json/loan_request.py,sha256=jlbtdck6FoG7bK5UjLqc-LFka3kUBBURRVcM-ZRyZW4,5920
54
+ invenio_app_ils/circulation/loaders/schemas/json/loan_request.py,sha256=iJVAnyNE1_LfVTuiO_yNtLVMOKHm0OErRbqU4uhczbU,5921
55
+ invenio_app_ils/circulation/loaders/schemas/json/loan_self_checkout.py,sha256=ceYLWal4ZF1h8J6r5cPVQL0VlkiQn5GusxVgtuNWPDA,578
55
56
  invenio_app_ils/circulation/loaders/schemas/json/loan_update_dates.py,sha256=9NtrBJKytly3Acv4wxuqExN0gB9DGnXB8K_27izQkrs,774
56
57
  invenio_app_ils/circulation/notifications/__init__.py,sha256=fG45An4FOBrAIZcWfFtv-3RnyFC4lfHUXWdwy164y_Q,246
57
58
  invenio_app_ils/circulation/notifications/api.py,sha256=UxGle0HgDU5PA7TeS4wVThybrBurOTWGvH_QKSP5Pyg,3429
58
- invenio_app_ils/circulation/notifications/messages.py,sha256=lzCoOoBGnNt5Q6j4uek-edfF2h5VdqHUi-Xc7oO89cM,3713
59
+ invenio_app_ils/circulation/notifications/messages.py,sha256=D4Fi1eNPsVfsQm2nAlEDpTX8xbZVwzraRwiwi4_R8iE,3757
59
60
  invenio_app_ils/circulation/notifications/tasks.py,sha256=8W4T3YzzWn3VEMcFZZkqOZGil7MAP0EGovJ4tBfFHOA,1806
60
- invenio_app_ils/circulation/serializers/__init__.py,sha256=uVT67rfpNzj2k56rjdpXcpHfUdHPUyoV9mN1Svc8uSg,1034
61
+ invenio_app_ils/circulation/serializers/__init__.py,sha256=RWzG4YNwKZzG81ucpesjwEfZ-K4HBwo4ycowQorqdHw,1035
61
62
  invenio_app_ils/circulation/serializers/csv.py,sha256=se_6Bv0gA8IZm9Je1Edy-_aHfBqB6kfkd3I6NTvSoWc,1328
62
63
  invenio_app_ils/circulation/serializers/custom_fields.py,sha256=EQnWMCLNgModn4BrFkDJLQDLwnTK317nMX_VVnb-dH0,2769
63
64
  invenio_app_ils/circulation/serializers/json.py,sha256=x625dleVLyfZU1bAWuTfk1UvEGUlWuAYUAvec4qAFHo,1553
64
- invenio_app_ils/circulation/serializers/response.py,sha256=UqgMIwl6Ylm1-XqTurmoS0_e67Irq8j2MgFaAf1lj1Q,1288
65
+ invenio_app_ils/circulation/serializers/response.py,sha256=xPmwnO-bHoaaL6KgCz6ayo2FBGBlJKmb4cH9JeOb9ls,1289
65
66
  invenio_app_ils/circulation/stats/__init__.py,sha256=X_oDxvlDZRHxfjM1J-sBisDmn_45F0MptRbvyTTI3WA,247
66
67
  invenio_app_ils/circulation/stats/api.py,sha256=YLdW_TobeoJWrCX1OHgpaW46JBb-FpyiFkeabZLiAgI,1807
67
68
  invenio_app_ils/circulation/stats/views.py,sha256=_I9qgSnvmKs5sjJ4zpH1pLoGYCLA8C3mVMfFLTlzVEM,4933
@@ -73,6 +74,7 @@ invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/
73
74
  invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/overdue_reminder.html,sha256=XAXTBJFo8DQCdDPQE81K-LqdlrAJ7Gam3cIlknYcJ3w,899
74
75
  invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/request.html,sha256=ymEJFd9CWsK1dwxNu9qz6bR9Jdmozm5yMpI1VTysZM8,574
75
76
  invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/request_no_items.html,sha256=iF0KKsw8UuObUvKzlPGPwCt7e_5oPFzqKxlkwY_JCiY,788
77
+ invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/self_checkout.html,sha256=FNTGwP47kyy5RQC292PouuAlLiGsRmaO9rG2yqhx1Rc,654
76
78
  invenio_app_ils/circulation/templates/invenio_app_ils_circulation/notifications/will_expire_in_reminder.html,sha256=bxSEB8clDDvnfaXcs9r-XtyhlAIv3a-QTI4MvU_bqsY,713
77
79
  invenio_app_ils/circulation/transitions/__init__.py,sha256=XaEYQVWOWhZ_0JPxTg0Lx53BmyWJXOfM3_nm2KipYhY,237
78
80
  invenio_app_ils/circulation/transitions/transitions.py,sha256=9W5h4RHm72wMQuY3hKgFHLKwnxN68gkN98RwBlCjsro,1361
@@ -122,10 +124,10 @@ invenio_app_ils/documents/jsonresolvers/document_circulation.py,sha256=qwfP9h8R4
122
124
  invenio_app_ils/documents/jsonresolvers/document_eitem.py,sha256=bMLjQlBnsynuKqAdvUmbAe18duI76nqlt-LsGjBu90w,1827
123
125
  invenio_app_ils/documents/jsonresolvers/document_item.py,sha256=gQaXJ2ebEG9uH_sm4iz34M228_tUJEmferpU5u0clZQ,3204
124
126
  invenio_app_ils/documents/jsonresolvers/document_relations.py,sha256=D2VBBK_5hqKwefmoN7lq13oqKcjeRoHohVKQ83HhHkM,1138
125
- invenio_app_ils/documents/jsonresolvers/document_stock.py,sha256=aoSd1ypYt1TgUlc6H6PnTyY9kwm4A5YhqjqVYbwFDcU,1668
127
+ invenio_app_ils/documents/jsonresolvers/document_stock.py,sha256=QQ1WNsHBqzLoxRngK2uyFcqPVCXwLqj4Ayn23dyF7YM,1668
126
128
  invenio_app_ils/documents/loaders/__init__.py,sha256=h_uilf6ka1qi9vwhfDc5SzL1rdWHH2qWCMQrI_LEnoU,414
127
129
  invenio_app_ils/documents/loaders/jsonschemas/__init__.py,sha256=3RyVNmovfMJnmze6_QKSULev8a3yRHUCuO-0y3UFy64,238
128
- invenio_app_ils/documents/loaders/jsonschemas/document.py,sha256=RXemA7NAQvd1qpdGwZcmYoJ3-9G35yxslsL8IRRxb5Q,7577
130
+ invenio_app_ils/documents/loaders/jsonschemas/document.py,sha256=TmnI6QKR1tl-7MAHZGefiuTxCnt81Ikysm4roCsxDvM,7577
129
131
  invenio_app_ils/documents/mappings/__init__.py,sha256=8myTYxQP-EadjBbmAQd3vjZY1-uUGpSQCDv7Sr2cX6A,229
130
132
  invenio_app_ils/documents/mappings/os-v1/__init__.py,sha256=0TRJl_WtkxFUNK3MxyntNg2s-lZILhzB2ZdKMs7qcDI,241
131
133
  invenio_app_ils/documents/mappings/os-v1/documents/document-v1.0.0.json,sha256=o864rRsme4OKA7SwQhpc2ORO5VflH2hpF-58GssfdqA,21646
@@ -148,7 +150,7 @@ invenio_app_ils/eitems/jsonresolvers/eitem_document.py,sha256=dgs0yGqHlfOL00jIJn
148
150
  invenio_app_ils/eitems/jsonresolvers/eitem_files.py,sha256=xCAIL4HGXAGhovxbNLAWz9ra_CsWZ4UpsNzK3VaddKw,1358
149
151
  invenio_app_ils/eitems/loaders/__init__.py,sha256=F3-_mbd-3Pjr8J20gVEDxGs3VE9nMEKChp03LjLi-Uo,401
150
152
  invenio_app_ils/eitems/loaders/jsonschemas/__init__.py,sha256=6bLAkym3u9rgqYTHDHOX3gr5Hh60QNC_YHQMkzIHDgY,236
151
- invenio_app_ils/eitems/loaders/jsonschemas/eitems.py,sha256=nGnT-HOy4veHbg4ffrAWEw5WSKWvured_OfJQEqc2B8,2063
153
+ invenio_app_ils/eitems/loaders/jsonschemas/eitems.py,sha256=KKUe1QvjZ7z6Swtbi2D1vxBiv_55suIXbQYM4E0tJLs,2063
152
154
  invenio_app_ils/eitems/mappings/__init__.py,sha256=PXpNWKcHerg4WIVNBjag0iCPZRQ8pyb3PyxT9zcrnvc,236
153
155
  invenio_app_ils/eitems/mappings/os-v1/__init__.py,sha256=99ifBNKeEw3npzw0AOKCUTP25mcR2Sn1M7Oy8i_Ra_A,239
154
156
  invenio_app_ils/eitems/mappings/os-v1/eitems/eitem-v1.0.0.json,sha256=MBWhA2wJl8t9q12Rc90pwRkTp0Rk8uSPfZWWWDUabDA,2756
@@ -224,16 +226,16 @@ invenio_app_ils/internal_locations/mappings/v7/internal_locations/internal_locat
224
226
  invenio_app_ils/internal_locations/schemas/__init__.py,sha256=gMsPU0b91BaEF60VR_sY6eWLR-BLkkNSldzIdlsyPBA,244
225
227
  invenio_app_ils/internal_locations/schemas/internal_locations/internal_location-v1.0.0.json,sha256=MgGTxIq64uEGryvEyN5EXSORm9lZoE4MHj4ZLaBqr18,1115
226
228
  invenio_app_ils/items/__init__.py,sha256=Jdz0wSG1rNZyyit0VynCMQVDUHo0Vv1S3A2V-PICDfU,226
227
- invenio_app_ils/items/api.py,sha256=xbjklZI1D605VucninFt4AA3bPsKk_md043_Toa__N4,7413
229
+ invenio_app_ils/items/api.py,sha256=olr3T84QU9qVkmXnKgjIg7DIRQGwKRUfPfyaAjW_kwg,7838
228
230
  invenio_app_ils/items/indexer.py,sha256=vWxOnw6o_zH9gDHex4gWrDClP8H2UMyCcrJnxhxjsaU,2022
229
- invenio_app_ils/items/search.py,sha256=eyEsQNhMvj-DeYMQRgEsyDn4H0AxqxyMIzPMg6prbIY,2985
231
+ invenio_app_ils/items/search.py,sha256=HCxrW9UHFVrO7-1DPm503HpavF823hwO0gfKf2VAdTw,3418
230
232
  invenio_app_ils/items/jsonresolvers/__init__.py,sha256=bS7v-bpbyHNrqtY9n5SkDJDcfi9jqOUZYVjjrd9qyy0,244
231
233
  invenio_app_ils/items/jsonresolvers/item_document.py,sha256=fld6jwEWuygW8v5lrldARRh8lWtMOWPe1Lfsxg3qvfQ,1879
232
234
  invenio_app_ils/items/jsonresolvers/item_internal_location.py,sha256=FKPaEfI8urkBnwN8f8IxUvJiMJqcJ17s_ZZ11CxuQpU,1754
233
235
  invenio_app_ils/items/jsonresolvers/item_loan.py,sha256=RZQP5zvM2lcuAhxQbFlhJJJyxQeNV-ZUE2tMojBApeY,1630
234
236
  invenio_app_ils/items/loaders/__init__.py,sha256=MLPgoiiMW5_7HLacJ4ny3vmmih3qOLA2-5ECPWWwZvg,424
235
237
  invenio_app_ils/items/loaders/jsonschemas/__init__.py,sha256=QjB4GpaGRO8_vUf5F2Igu-VBtCJOrxBBAcyhMYp2uLc,235
236
- invenio_app_ils/items/loaders/jsonschemas/items.py,sha256=Cwi9YmBrYLPMWLpvGelbAhLkfDiWjPbM2JR1QNA_8e0,2073
238
+ invenio_app_ils/items/loaders/jsonschemas/items.py,sha256=vkktlcwZOXhKtZM0ttPUOHFpIJ3eZUIuqg7WeYiZ56k,2073
237
239
  invenio_app_ils/items/mappings/__init__.py,sha256=FHHOdSZAxfKT7lwBTyho9e9H5_MQ5iSJegK9REtcJjY,235
238
240
  invenio_app_ils/items/mappings/os-v1/__init__.py,sha256=d3ZUL6aicw4_MYvaJ3AI5a8vnoEwaSwM5YUDDOgooVg,238
239
241
  invenio_app_ils/items/mappings/os-v1/items/item-v1.0.0.json,sha256=cqSMIOFW7VsuS1FHjsQ0Hy-NuvnYEKhGyaBWM4epP6E,6352
@@ -248,7 +250,7 @@ invenio_app_ils/items/schemas/__init__.py,sha256=oH3ip8OnA1mK1eM3gp8VxEM5LLoSVSW
248
250
  invenio_app_ils/items/schemas/items/item-v1.0.0.json,sha256=kEn3c45Dk_OSJnuRtwJpThUp9WKC_FvBsTr6DcUIqTQ,3960
249
251
  invenio_app_ils/items/schemas/items/item-v2.0.0.json,sha256=kEn3c45Dk_OSJnuRtwJpThUp9WKC_FvBsTr6DcUIqTQ,3960
250
252
  invenio_app_ils/items/serializers/__init__.py,sha256=OxfwU0rGarUnBvznMmiGaJx6uMwX-062pN9RQwR2lhw,914
251
- invenio_app_ils/items/serializers/item.py,sha256=d9TzdYLhpRfp4VyoBdNuYTqQWkshytAk3Q8YUI1E6ms,2967
253
+ invenio_app_ils/items/serializers/item.py,sha256=8qHJp4SFxJj_qM-Pf-Om98KYc5ytweNLJiD94ksGslQ,2967
252
254
  invenio_app_ils/literature/__init__.py,sha256=GELxzVtOq8G2O7Uvs_mLsj0wPnS5l-6ns9mLFDGMEmQ,231
253
255
  invenio_app_ils/literature/api.py,sha256=gbLMK36fN0KXUmygRLadeejPnJ_3CSU_8WFrgxwQ_j4,862
254
256
  invenio_app_ils/literature/covers_builder.py,sha256=_MzoKZik_7UZRKl8szuhcLSD-o8reRSyV8VSbcIbh8g,1285
@@ -284,7 +286,7 @@ invenio_app_ils/notifications/views.py,sha256=3Cq0zseRMQiMfzACyLLJx258DsdJ4khol4
284
286
  invenio_app_ils/notifications/backends/__init__.py,sha256=51F9qVm1JIAOfLfzqn2O80YZlKJ4kVD5cuyoUP2Z748,421
285
287
  invenio_app_ils/notifications/backends/mail.py,sha256=NNKgUsdWG2moqkGfEnwj2tPBOPzkOCuSW2F_WzWnc8A,1341
286
288
  invenio_app_ils/patrons/__init__.py,sha256=zGad-MTgKFzc_92lH9NNKVIZyxSK9zwZX4BBmHK4tbw,228
287
- invenio_app_ils/patrons/anonymization.py,sha256=yxXM8HKmw5vh8ymjM23D7jeMiyvgAfaTnOyB7lpXVnw,9111
289
+ invenio_app_ils/patrons/anonymization.py,sha256=EEUvkubLkjkh83RroIz5lOpQMAr3LRJqDWub-KZBZJk,10242
288
290
  invenio_app_ils/patrons/api.py,sha256=ofVURg73zmacmiNbPJ4edCkDgxngdA90IePxoLM7lRc,5396
289
291
  invenio_app_ils/patrons/cli.py,sha256=k-aZlygrJwwQGu1yAcI5livU6leERXf3jdV2oqyFegI,2018
290
292
  invenio_app_ils/patrons/indexer.py,sha256=3SArGVZicfazVALg5gFS7UdQxewsxre9mrX9tu5nKTI,5956
@@ -323,7 +325,7 @@ invenio_app_ils/records/listeners.py,sha256=6_yZRDh17ujY5zz3gSCArJeId9r8vyo-yadW
323
325
  invenio_app_ils/records/metadata_extensions.py,sha256=Y7knwqFTZ6UQU6-Viuhv22cplGd9VsebXasoDB-o39o,3599
324
326
  invenio_app_ils/records/permissions.py,sha256=_0zd1GCbulcSEGLZ3ZJBaD8Q-TU1r9XLlGLByj-TqCw,3773
325
327
  invenio_app_ils/records/receivers.py,sha256=z9iEd9EMqVw5wS3_pPZTZzeKRyzOguTHqb8FgsKCoD0,493
326
- invenio_app_ils/records/views.py,sha256=Ds4_Fx_YvEVknNoqfpQFyOYf305k6EtkzXLGnojybyg,3410
328
+ invenio_app_ils/records/views.py,sha256=RGdt3ZQOrfvNxuEfv31Dk-udsRG2u_8J73Sb7fiD8m8,3410
327
329
  invenio_app_ils/records/jsonresolvers/__init__.py,sha256=mhHgwyehRSGfoWcfTT9O7F5pCFoS7-yKwJkbFaYRF8Y,249
328
330
  invenio_app_ils/records/jsonresolvers/api.py,sha256=RAM7bqEjqgTn3wx6PlDRY_UEjZknrXiMSB-dMOJwvW0,1183
329
331
  invenio_app_ils/records/loaders/__init__.py,sha256=saCzmtbFLKrgmueTclBSikDwO56XVpHA07PZ_dKu4Bo,817
@@ -336,12 +338,12 @@ invenio_app_ils/records/schemas/__init__.py,sha256=K6l2nVL1zpZM9ZFfZQBgHsjeiSTsk
336
338
  invenio_app_ils/records/schemas/json.py,sha256=r7wShFjJ3FnT_pvunyqfWbgJf9z9iaUV3MhyTEtbEyw,712
337
339
  invenio_app_ils/records/serializers/__init__.py,sha256=pomP0H0b3Zku8lWWcFu86ondB-RJWzO1gDO8mDVEKgo,2230
338
340
  invenio_app_ils/records_relations/__init__.py,sha256=fLycCnrsQv6yVQPARUjHW5QAXcAH7d1dp_dDChQyzFY,238
339
- invenio_app_ils/records_relations/api.py,sha256=2TvOyfwBC5sDVCWX_MUnqlmll53_qXEgSlKb8EQNwKo,16763
341
+ invenio_app_ils/records_relations/api.py,sha256=m2MlN1qS53QtrdqZI8KzRS1bO-0u11QV4z2OcmOFLzI,16764
340
342
  invenio_app_ils/records_relations/indexer.py,sha256=xlNQ6jRKTSrTXX5l0mnbx7kNkfwHeJlw70KsDSqGBeU,2279
341
343
  invenio_app_ils/records_relations/retriever.py,sha256=_PcbdG1IM_hss7xqClvK8Ti-0pB8rBgfOM5GgJvHrNM,8944
342
344
  invenio_app_ils/records_relations/views.py,sha256=-YLUhhSk2oI75RvueAgCxi5L_CafhlsgnNvbePBjobs,14889
343
345
  invenio_app_ils/relations/__init__.py,sha256=K27Ys3WJwwhJp5NnD9RZDbLMIKu_OcOXZWfSTBpcTOY,229
344
- invenio_app_ils/relations/api.py,sha256=2fBGdUJZ9nRnhyr7uy0YlkZJve1jD-qDQMTcJcOEUE8,14074
346
+ invenio_app_ils/relations/api.py,sha256=IDG_6xWv8Mun40csBWuPNXkzRNdaO9wLe1otWquriig,14105
345
347
  invenio_app_ils/relations/nodes.py,sha256=PE_D6gj335EH_G1BWPGEKZOCzrIOII5UpN4a5-MpxcA,376
346
348
  invenio_app_ils/series/__init__.py,sha256=kd4lghqtrIci0-JaTmSIv0kT5DhaydNi5mBh93_x4iw,227
347
349
  invenio_app_ils/series/api.py,sha256=pbFUiOXsR86sN1Shb0eOBIb3EY6zstby4yRXofcQtdQ,3235
@@ -351,7 +353,7 @@ invenio_app_ils/series/jsonresolvers/__init__.py,sha256=KwS1i7XJkydP_YfOMjjvCXbn
351
353
  invenio_app_ils/series/jsonresolvers/series_relations.py,sha256=-QhlHVl93TddK6tsqxyYb3xvp3ISRA9dHa-qz_ZTFW4,1097
352
354
  invenio_app_ils/series/loaders/__init__.py,sha256=2tEAlF_GRq-2-eLXd8e8w4e19iBBZs98E3_nwPQiqlY,404
353
355
  invenio_app_ils/series/loaders/jsonschemas/__init__.py,sha256=h5J1d56DTizrKCfQHHO7d8OH0tno3hb_-dtaKkB63_Y,236
354
- invenio_app_ils/series/loaders/jsonschemas/series.py,sha256=MVOkGUTK02-6lm26sd218W6JfBRS4n939BgImNGeKuI,4110
356
+ invenio_app_ils/series/loaders/jsonschemas/series.py,sha256=K8Z0Bl8wtSxcDCFC1lPGhGPMHdoCPmwvygEDhbaZJeA,4110
355
357
  invenio_app_ils/series/mappings/__init__.py,sha256=A7EmmTOx0yXlMkeimLxvL5xTlwBy3ogbNVRXU8E7bF8,236
356
358
  invenio_app_ils/series/mappings/os-v1/__init__.py,sha256=1Fny1TaeM8uc9Rwvw2bf94RvxEY067R5nP5Lz17UEGs,239
357
359
  invenio_app_ils/series/mappings/os-v1/series/series-v1.0.0.json,sha256=YJLsKB5xjk2IIX8V39tp-1W03r3Vq96c7Ubr_fk1AWA,6919
@@ -450,7 +452,7 @@ tests/api/acquisition/test_acq_providers_permissions.py,sha256=aVshFVUuKwUfjRZgD
450
452
  tests/api/circulation/__init__.py,sha256=AWnR9VZzm4IiO97eKJNn1LLtQJ1sRgjgrxChJ1Wxsuw,235
451
453
  tests/api/circulation/test_expired_loans.py,sha256=nVGu1H7G8KlPGatx_YG2NCEYpeniZnGkwL4gsg_uyp8,2798
452
454
  tests/api/circulation/test_loan_bulk_extend.py,sha256=jDYYyPXn5p6yn55pUVp4ivVSh9GcCvU5C-P8OlubMto,5606
453
- tests/api/circulation/test_loan_checkout.py,sha256=T7-jT3eQWiGbXRQihLCPGJgbxD2mILX0PcdBQZ00Kqk,11672
455
+ tests/api/circulation/test_loan_checkout.py,sha256=ndIi5eto0QwlkojF8O4ny98mCsIKNNEUcY1PFz_ETUc,16308
454
456
  tests/api/circulation/test_loan_default_durations.py,sha256=SWQmAJwe5GSoji1Hibx6DjGorJQZ2tYfiHPkuPZKTJo,1681
455
457
  tests/api/circulation/test_loan_document_resolver.py,sha256=ZNu-otdQ8398ksTV2XdgpK3WcbeR8-X-qaRnlPM2_6w,556
456
458
  tests/api/circulation/test_loan_extend.py,sha256=vkpyss5XkzeHVuGUXU8eOlF9J4esSjrVr5oNx-nXqEU,4158
@@ -500,9 +502,8 @@ tests/api/ils/eitems/test_eitems_permissions.py,sha256=__AlVOpr6Q36xOIiISGTFqAJT
500
502
  tests/api/ils/eitems/test_files.py,sha256=KnzvSYo1HqnFCexXkcKZmmvr_9e4fcABc2D-dE5blK8,4625
501
503
  tests/api/ils/items/__init__.py,sha256=oc7OKnwhkZsi7f8mMAoWhwBFQTHVYeDSAWFVLBXQuEs,229
502
504
  tests/api/ils/items/test_apis.py,sha256=hLD8RCEkGYld7af_JwDFAIL69x8Rin_kElLpqjDn-KE,1366
503
- tests/api/ils/items/test_items_crud.py,sha256=IS1o8Lm3dNKOmt2mrp2bzkTn8KVyTK_WCWEf5ikoCIU,1794
505
+ tests/api/ils/items/test_items_crud.py,sha256=HB3vV5PZWTA1ugumVh7ej9RobRhX1Xf6qIfVRLred7k,3221
504
506
  tests/api/ils/items/test_items_permissions.py,sha256=HE-yYAc6_fza_JXpvTzjcjA9341iAKevJKBoh99jbbw,3757
505
- tests/api/ils/items/test_items_update.py,sha256=_ZZTeh1Y1SZ6zN34O-rVTpEMDyUwqh2LBzbHXsgo69M,1417
506
507
  tests/api/ils/records_relations/__init__.py,sha256=VxNqRmCl2IBDm6PFgG_q_CfFMwFKojB9QtiB-LBONfo,241
507
508
  tests/api/ils/records_relations/helpers.py,sha256=lm2dQdACxYuU2ro-ymA0OtqiKYYldwax8kRmYiqxuWM,3875
508
509
  tests/api/ils/records_relations/test_records_relations_parentchild.py,sha256=vY5gr8L0nrdlvbGKM_wYSD6Vtp4L0QiZoP3YIlwxisA,17969
@@ -518,7 +519,7 @@ tests/data/eitems.json,sha256=2qwmHZkTf718Jizmk7YAO1v_8gs4yOm4dytzmvD-asQ,2122
518
519
  tests/data/ill_borrowing_requests.json,sha256=XG3xQnBizpeXrgUsNHphqLA7wQKEYEdLbkYwTZdqOIM,1603
519
520
  tests/data/ill_providers.json,sha256=M1NPVcjyP3_3r4Ynrltf5ZJ8QReBVHzV2fYSVUmj5Nc,169
520
521
  tests/data/internal_locations.json,sha256=CMXYQ98d9Hhu7YnaQoxrUGAoyIe43kTikE3CIhXPq9E,396
521
- tests/data/items.json,sha256=VnPhr7L6dMzi0drzj_XEXKO3OyfktRBnX3_cd6XT4y8,7832
522
+ tests/data/items.json,sha256=CUH1RooPv3aI3xKTJ7yN_GKZ19Ap8Cv0dsT8ZcV6igY,8528
522
523
  tests/data/loans.json,sha256=xVTnEc9IuJdu0Fspd0HDNHM8ZO26lir3EEkwaAvTGIM,3668
523
524
  tests/data/loans_most_loaned.json,sha256=ut1bOCFHCShPv_HotAjVV59gfwNfjpxEahyPCOZmQgY,3039
524
525
  tests/data/locations.json,sha256=2-xvSY4x8MJsDzlK-aleXaJw6mPMaQe7rJqwX1YqxfM,1637
@@ -528,10 +529,10 @@ tests/templates/notifications/title_body.html,sha256=W-pa6eSm7glK9JEcTVo4G7yC3Q1
528
529
  tests/templates/notifications/title_body_html.html,sha256=wPDP-DpQ0c2AX3oIfLvJLRp7J_rMoesIc9nLx3apkDc,146
529
530
  tests/templates/notifications/title_body_html_ctx.html,sha256=qqfTZ9zKVXFqyXIcqt5BLHEJptRlUDPBPtLxPfTmNzQ,193
530
531
  tests/templates/notifications/title_only.html,sha256=aoZ0veSleRYdKPXWgN6fdXLaz3r-KAPzdfHSuHPR2Uo,45
531
- invenio_app_ils-4.1.0.dist-info/AUTHORS.rst,sha256=BaXCGzdHCmiMOl4qtVlh1qrfy2ROMVOQp6ylzy1m0ww,212
532
- invenio_app_ils-4.1.0.dist-info/LICENSE,sha256=9OdaPOAO1ZOJcRQ8BrGj7QAdaJc8SRSUgBtdom49MrI,1062
533
- invenio_app_ils-4.1.0.dist-info/METADATA,sha256=3KTqFuTubExWO-qq4cNMVUWTCo_sHR3duJ-FcHheYr4,15855
534
- invenio_app_ils-4.1.0.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
535
- invenio_app_ils-4.1.0.dist-info/entry_points.txt,sha256=JbIlm87pY7dVL-gLh8Hmfav18psVHXLBmHBzA-fQqlY,7607
536
- invenio_app_ils-4.1.0.dist-info/top_level.txt,sha256=MQTU2NrM0if5YAyIsKmQ0k35skJ3IUyQT7eCD2IWiNQ,22
537
- invenio_app_ils-4.1.0.dist-info/RECORD,,
532
+ invenio_app_ils-4.3.0.dist-info/AUTHORS.rst,sha256=BaXCGzdHCmiMOl4qtVlh1qrfy2ROMVOQp6ylzy1m0ww,212
533
+ invenio_app_ils-4.3.0.dist-info/LICENSE,sha256=9OdaPOAO1ZOJcRQ8BrGj7QAdaJc8SRSUgBtdom49MrI,1062
534
+ invenio_app_ils-4.3.0.dist-info/METADATA,sha256=zJOoSimPLZBg6uHfY09dwtO9PDwNY5djlPNi8BQOmAE,16437
535
+ invenio_app_ils-4.3.0.dist-info/WHEEL,sha256=0VNUDWQJzfRahYI3neAhz2UVbRCtztpN5dPHAGvmGXc,109
536
+ invenio_app_ils-4.3.0.dist-info/entry_points.txt,sha256=dLh4XxQPtPYRl_VNqzNpRK4l_sv_RQEyAm57tBBL7Ic,7606
537
+ invenio_app_ils-4.3.0.dist-info/top_level.txt,sha256=MQTU2NrM0if5YAyIsKmQ0k35skJ3IUyQT7eCD2IWiNQ,22
538
+ invenio_app_ils-4.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.44.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any
@@ -148,4 +148,3 @@ patrons = invenio_app_ils.patrons.mappings
148
148
  providers = invenio_app_ils.providers.mappings
149
149
  series = invenio_app_ils.series.mappings
150
150
  vocabularies = invenio_app_ils.vocabularies.mappings
151
-
@@ -15,13 +15,16 @@ import arrow
15
15
  from flask import url_for
16
16
  from flask_principal import UserNeed
17
17
  from invenio_access.permissions import Permission
18
+ from invenio_search import current_search
18
19
 
19
- from invenio_app_ils.items.api import Item
20
- from invenio_app_ils.permissions import (
21
- authenticated_user_permission,
22
- loan_checkout_permission,
23
- views_permissions_factory,
20
+ from invenio_app_ils.errors import (
21
+ LoanSelfCheckoutDocumentOverbooked,
22
+ LoanSelfCheckoutItemActiveLoan,
23
+ LoanSelfCheckoutItemInvalidStatus,
24
24
  )
25
+ from invenio_app_ils.items.api import Item
26
+ from invenio_app_ils.items.serializers import item
27
+ from invenio_app_ils.proxies import current_app_ils
25
28
  from tests.helpers import user_login, user_logout
26
29
 
27
30
  NEW_LOAN = {
@@ -30,7 +33,15 @@ NEW_LOAN = {
30
33
  "patron_pid": "3",
31
34
  "transaction_location_pid": "locid-1",
32
35
  "pickup_location_pid": "locid-1",
33
- "delivery": {"method": "PICK_UP"},
36
+ "delivery": {"method": "PICKUP"},
37
+ }
38
+
39
+ NEW_LOAN_REQUEST = {
40
+ "document_pid": "CHANGE ME IN EACH TEST",
41
+ "patron_pid": "3",
42
+ "transaction_location_pid": "locid-1",
43
+ "pickup_location_pid": "locid-1",
44
+ "delivery": {"method": "PICKUP"},
34
45
  }
35
46
 
36
47
 
@@ -215,77 +226,171 @@ def test_checkout_loader_start_end_dates(app, client, json_headers, users, testd
215
226
  assert res.status_code == 400
216
227
 
217
228
 
218
- def _views_permissions_factory(action):
219
- """Override ILS views permissions factory."""
220
- if action == "circulation-loan-checkout":
221
- return authenticated_user_permission()
222
- return views_permissions_factory(action)
229
+ def test_self_checkout_search(app, client, json_headers, users, testdata):
230
+ """Test self-checkout search."""
231
+ app.config["ILS_SELF_CHECKOUT_ENABLED"] = True
232
+
233
+ # test that anonymous user cannot search for barcodes
234
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
235
+ res = client.get(f"{url}?barcode=123456", headers=json_headers)
236
+ assert res.status_code == 401
223
237
 
238
+ user_login(client, "patron2", users)
224
239
 
225
- def test_self_checkout(app, client, json_headers, users, testdata):
226
- """Tests for self checkout feature."""
227
- app.config["ILS_SELF_CHECKOUT_ENABLED"] = True
228
- app.config["ILS_VIEWS_PERMISSIONS_FACTORY"] = _views_permissions_factory
229
- app.config["RECORDS_REST_ENDPOINTS"]["pitmid"][
230
- "list_permission_factory_imp"
231
- ] = authenticated_user_permission
232
- app.config["ILS_CIRCULATION_RECORDS_REST_ENDPOINTS"]["loanid"][
233
- "update_permission_factory_imp"
234
- ] = loan_checkout_permission
235
-
236
- # Self checkout by librarian should pass
237
- librarian = users["librarian"]
240
+ # test the missing parameter error
241
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
242
+ res = client.get(url, headers=json_headers)
243
+ assert res.status_code == 400
244
+
245
+ # test that authenticated user can search for barcodes, but it will return
246
+ # 400 when not found
247
+ unexisting_barcode = "123456"
248
+ res = client.get(f"{url}?barcode={unexisting_barcode}", headers=json_headers)
249
+ assert res.status_code == 400
250
+
251
+ # test that an error is returned when the item cannot circulate
252
+ missing_item_barcode = "123456789-1"
253
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
254
+ res = client.get(f"{url}?barcode={missing_item_barcode}", headers=json_headers)
255
+ assert res.status_code == 400
256
+ # assert that the payload will contain the key error with a msg
257
+ response = res.get_json()
258
+ assert LoanSelfCheckoutItemInvalidStatus.description in response["message"]
259
+ assert LoanSelfCheckoutItemInvalidStatus.supportCode in response["supportCode"]
260
+
261
+ # create a loan on the same patron, and another one on another patron
238
262
  user_login(client, "librarian", users)
239
- params = deepcopy(NEW_LOAN)
240
- params["item_pid"] = dict(type="pitmid", value="itemid-60")
241
- params["transaction_user_pid"] = str(librarian.id)
242
- params["patron_pid"] = str(librarian.id)
243
263
  url = url_for("invenio_app_ils_circulation.loan_checkout")
244
- res = client.post(url, headers=json_headers, data=json.dumps(params))
245
264
 
246
- assert res.status_code == 202
247
- loan = res.get_json()["metadata"]
248
- assert loan["state"] == "ITEM_ON_LOAN"
249
- assert loan["item_pid"] == params["item_pid"]
250
- assert loan["patron_pid"] == str(librarian.id)
251
- user_logout(client)
265
+ for item_pid, patron_pid in [
266
+ ("itemid-60", "2"), # barcode 123456789-60
267
+ ("itemid-61", "1"), # barcode 123456789-61
268
+ ]:
269
+ params = deepcopy(NEW_LOAN)
270
+ params["transaction_user_pid"] = str(users["librarian"].id)
271
+ params["item_pid"] = dict(type="pitmid", value=item_pid)
272
+ params["patron_pid"] = patron_pid
273
+ res = client.post(url, headers=json_headers, data=json.dumps(params))
274
+ assert res.status_code == 202
275
+
276
+ # ensure new loans and related items are fully indexed
277
+ current_search.flush_and_refresh(index="*")
278
+
279
+ user_login(client, "patron2", users)
280
+
281
+ # test that an error is returned when the item is already on loan by the same user
282
+ on_loan_same_patron_barcode = "123456789-60"
283
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
284
+ res = client.get(
285
+ f"{url}?barcode={on_loan_same_patron_barcode}", headers=json_headers
286
+ )
287
+ assert res.status_code == 400
288
+ # assert that the payload will contain the key error with a msg
289
+ response = res.get_json()
290
+ assert LoanSelfCheckoutItemActiveLoan.description in response["message"]
291
+ assert LoanSelfCheckoutItemActiveLoan.supportCode in response["supportCode"]
292
+
293
+ # test that an error is returned when the item is already on loan by another user
294
+ on_loan_other_patron_barcode = "123456789-61"
295
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
296
+ res = client.get(
297
+ f"{url}?barcode={on_loan_other_patron_barcode}", headers=json_headers
298
+ )
299
+ assert res.status_code == 400
300
+ # assert that the payload will contain the key error with a msg
301
+ response = res.get_json()
302
+ assert LoanSelfCheckoutItemActiveLoan.description in response["message"]
303
+ assert LoanSelfCheckoutItemActiveLoan.supportCode in response["supportCode"]
252
304
 
253
- # Self checkout by patron should pass if patron_pid matches
254
- patron3 = users["patron3"]
255
- user_login(client, "patron3", users)
256
- params = deepcopy(NEW_LOAN)
257
- params["item_pid"] = dict(type="pitmid", value="itemid-61")
258
- params["transaction_user_pid"] = str(patron3.id)
259
- params["patron_pid"] = str(patron3.id)
260
- url = url_for("invenio_app_ils_circulation.loan_checkout")
261
- res = client.post(url, headers=json_headers, data=json.dumps(params))
305
+ # test happy path
306
+ available_barcode = "123456789-10"
307
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
308
+ res = client.get(f"{url}?barcode={available_barcode}", headers=json_headers)
309
+ assert res.status_code == 200
310
+ response = res.get_json()
311
+ assert response["metadata"]["pid"] == "itemid-10"
262
312
 
263
- assert res.status_code == 202
264
- loan = res.get_json()["metadata"]
265
- assert loan["state"] == "ITEM_ON_LOAN"
266
- assert loan["item_pid"] == params["item_pid"]
267
- assert loan["patron_pid"] == str(patron3.id)
268
313
 
269
- # Self checkout should fail if feature flag is not set to true
314
+ def test_self_checkout(app, client, json_headers, users, testdata):
315
+ """Test self-checkout."""
316
+
317
+ def _create_request(patron, document_pid):
318
+ url = url_for("invenio_app_ils_circulation.loan_request")
319
+ user = user_login(client, patron, users)
320
+ params = deepcopy(NEW_LOAN_REQUEST)
321
+ params["document_pid"] = document_pid
322
+ params["patron_pid"] = str(user.id)
323
+ params["transaction_user_pid"] = str(user.id)
324
+ res = client.post(url, headers=json_headers, data=json.dumps(params))
325
+ assert res.status_code == 202
326
+ current_search.flush_and_refresh(index="*")
327
+
328
+ def _self_checkout(patron, item_pid, document_pid):
329
+ params = deepcopy(NEW_LOAN)
330
+ params["document_pid"] = document_pid
331
+ params["item_pid"] = dict(type="pitmid", value=item_pid)
332
+ params["patron_pid"] = str(patron.id)
333
+ params["transaction_user_pid"] = str(patron.id)
334
+ return client.post(url, headers=json_headers, data=json.dumps(params))
335
+
336
+ url = url_for("invenio_app_ils_circulation.loan_self_checkout")
337
+
270
338
  app.config["ILS_SELF_CHECKOUT_ENABLED"] = False
271
- params = deepcopy(NEW_LOAN)
272
- params["item_pid"] = dict(type="pitmid", value="itemid-62")
273
- params["transaction_user_pid"] = str(patron3.id)
274
- params["patron_pid"] = str(patron3.id)
275
- url = url_for("invenio_app_ils_circulation.loan_checkout")
276
- res = client.post(url, headers=json_headers, data=json.dumps(params))
277
339
 
340
+ # test a logged in user cannot self-checkout when the feature is disabled
341
+ patron2 = user_login(client, "patron2", users)
342
+ res = client.post(url, headers=json_headers)
278
343
  assert res.status_code == 403
344
+
279
345
  user_logout(client)
346
+ app.config["ILS_SELF_CHECKOUT_ENABLED"] = True
280
347
 
281
- # Self checkout should fail if if patron_pid doesn't match
282
- patron1 = users["patron1"]
283
- user_login(client, "patron1", users)
284
- params = deepcopy(NEW_LOAN)
285
- params["item_pid"] = dict(type="pitmid", value="itemid-63")
286
- params["transaction_user_pid"] = str(patron1.id)
287
- params["patron_pid"] = str(patron3.id)
288
- url = url_for("invenio_app_ils_circulation.loan_checkout")
289
- res = client.post(url, headers=json_headers, data=json.dumps(params))
348
+ # test that anonymous user cannot self-checkout
349
+ res = client.post(url, headers=json_headers)
350
+ assert res.status_code == 401
290
351
 
291
- assert res.status_code == 403
352
+ # test overbooked books
353
+ # create multiple requests from different patrons
354
+ _create_request("patron1", "docid-15")
355
+ _create_request("patron3", "docid-15")
356
+
357
+ document_rec = current_app_ils.document_record_cls.get_record_by_pid("docid-15")
358
+ document = document_rec.replace_refs()
359
+ assert document["circulation"]["overbooked"]
360
+
361
+ # test that user cannot self-checkout an overbooked book, without having a request
362
+ patron2 = user_login(client, "patron2", users)
363
+ res = _self_checkout(patron2, "itemid-71", "docid-15")
364
+ assert res.status_code == 400
365
+ response = res.get_json()
366
+ assert LoanSelfCheckoutDocumentOverbooked.description in response["message"]
367
+ assert LoanSelfCheckoutDocumentOverbooked.supportCode in response["supportCode"]
368
+
369
+ # test that user cannot self-checkout an overbooked book, having a request
370
+ # create request from the same patron
371
+ _create_request("patron2", "docid-15")
372
+ patron2 = user_login(client, "patron2", users)
373
+ res = _self_checkout(patron2, "itemid-71", "docid-15")
374
+ assert res.status_code == 400
375
+ response = res.get_json()
376
+ assert LoanSelfCheckoutDocumentOverbooked.description in response["message"]
377
+ assert LoanSelfCheckoutDocumentOverbooked.supportCode in response["supportCode"]
378
+
379
+ # test that user can self-checkout having a prior request
380
+ _create_request("patron2", "docid-16")
381
+
382
+ patron2 = user_login(client, "patron2", users)
383
+ res = _self_checkout(patron2, "itemid-72", "docid-16")
384
+ assert res.status_code == 202
385
+ response = res.get_json()
386
+ assert response["metadata"]["delivery"]["method"] == "SELF-CHECKOUT"
387
+
388
+ # test that user can self-checkout without having a prior request, even if there
389
+ # are other requests on the book (but not overbooked)
390
+ _create_request("patron1", "docid-17")
391
+
392
+ patron2 = user_login(client, "patron2", users)
393
+ res = _self_checkout(patron2, "itemid-73", "docid-17")
394
+ assert res.status_code == 202
395
+ response = res.get_json()
396
+ assert response["metadata"]["delivery"]["method"] == "SELF-CHECKOUT"
@@ -11,11 +11,16 @@ from copy import deepcopy
11
11
 
12
12
  import pytest
13
13
 
14
- from invenio_app_ils.errors import DocumentNotFoundError, InternalLocationNotFoundError
15
- from invenio_app_ils.items.api import Item
14
+ from invenio_app_ils.circulation.search import get_active_loan_by_item_pid
15
+ from invenio_app_ils.errors import (
16
+ DocumentNotFoundError,
17
+ InternalLocationNotFoundError,
18
+ ItemHasPastLoansError,
19
+ )
20
+ from invenio_app_ils.items.api import ITEM_PID_TYPE, Item
16
21
 
17
22
 
18
- def test_item_refs(app, testdata):
23
+ def test_item_create(app, testdata):
19
24
  """Test creation of an item."""
20
25
  item = Item.create(
21
26
  dict(
@@ -23,7 +28,7 @@ def test_item_refs(app, testdata):
23
28
  document_pid="docid-1",
24
29
  internal_location_pid="ilocid-4",
25
30
  created_by=dict(type="script", value="demo"),
26
- barcode="348048",
31
+ barcode="cm-348048",
27
32
  status="CAN_CIRCULATE",
28
33
  circulation_restriction="NO_RESTRICTION",
29
34
  medium="PAPER",
@@ -31,6 +36,7 @@ def test_item_refs(app, testdata):
31
36
  )
32
37
  assert "$schema" in item
33
38
  assert "document" in item and "$ref" in item["document"]
39
+ assert item["barcode"] == "CM-348048"
34
40
  assert "internal_location" in item and "$ref" in item["internal_location"]
35
41
 
36
42
  item = Item.get_record_by_pid("itemid-1")
@@ -39,6 +45,16 @@ def test_item_refs(app, testdata):
39
45
  assert "internal_location" in item and item["internal_location"]["name"]
40
46
 
41
47
 
48
+ def test_item_update(app, db, testdata):
49
+ """Test update of an item."""
50
+ item = Item.get_record_by_pid("itemid-1")
51
+ item.update(dict(barcode="cm-348048"))
52
+ item.commit()
53
+ db.session.commit()
54
+
55
+ assert Item.get_record_by_pid("itemid-1")["barcode"] == "CM-348048"
56
+
57
+
42
58
  def test_item_validation(db, testdata):
43
59
  """Test validation when updating an item."""
44
60
  item_pid = testdata["items"][0]["pid"]
@@ -55,3 +71,29 @@ def test_item_validation(db, testdata):
55
71
  item["internal_location_pid"] = "not_found_pid"
56
72
  with pytest.raises(InternalLocationNotFoundError):
57
73
  item.commit()
74
+
75
+
76
+ def test_item_references(db, testdata):
77
+ """Test references when updating an item."""
78
+
79
+ def get_active_loan_pid_and_item_pid():
80
+ for t in testdata["items"]:
81
+ if t["status"] == "CAN_CIRCULATE":
82
+ item_pid = dict(type=ITEM_PID_TYPE, value=t["pid"])
83
+ active_loan = get_active_loan_by_item_pid(item_pid).execute().hits
84
+ total = active_loan.total.value
85
+ if total > 0:
86
+ return t["pid"], active_loan[0]["pid"]
87
+
88
+ # change document pid while is on loan
89
+ item_pid, loan_pid = get_active_loan_pid_and_item_pid()
90
+ item = Item.get_record_by_pid(item_pid)
91
+ item["document_pid"] = "docid-1"
92
+ with pytest.raises(ItemHasPastLoansError):
93
+ item.commit()
94
+
95
+ # change document to one that does not exist
96
+ item = Item.get_record_by_pid("itemid-1")
97
+ item["document_pid"] = "not_found_doc"
98
+ with pytest.raises(DocumentNotFoundError):
99
+ item.commit()