invenio-app-ils 4.2.0__py2.py3-none-any.whl → 4.4.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/errors.py CHANGED
@@ -98,11 +98,17 @@ class RecordHasReferencesError(IlsException):
98
98
  self.record_id = record_id
99
99
 
100
100
 
101
+ class ItemCannotCirculateError(IlsException):
102
+ """The item cannot circulate."""
103
+
104
+ description = "This item cannot circulate."
105
+
106
+
101
107
  class ItemHasActiveLoanError(IlsException):
102
108
  """The item which we are trying to update has an active loan."""
103
109
 
104
110
  description = (
105
- "Could not update item because it has an active loan with " "pid: {loan_pid}."
111
+ "Could not update item because it has an active loan with pid: {loan_pid}."
106
112
  )
107
113
 
108
114
  def __init__(self, loan_pid, **kwargs):
@@ -126,6 +132,7 @@ class PatronNotFoundError(IlsException):
126
132
  class PatronHasLoanOnItemError(IlsException):
127
133
  """A patron already has an active loan or a loan request on an item."""
128
134
 
135
+ code = 400
129
136
  description = "Patron '{0}' has already an active loan on item '{1}:{2}'"
130
137
 
131
138
  def __init__(self, patron_pid, item_pid, **kwargs):
@@ -135,6 +142,8 @@ class PatronHasLoanOnItemError(IlsException):
135
142
  :param prop: Missing property from loan request.
136
143
  """
137
144
  super().__init__(**kwargs)
145
+ self.patron_pid = patron_pid
146
+ self.item_pid = item_pid
138
147
  self.description = self.description.format(
139
148
  patron_pid, item_pid["type"], item_pid["value"]
140
149
  )
@@ -143,6 +152,7 @@ class PatronHasLoanOnItemError(IlsException):
143
152
  class PatronHasRequestOnDocumentError(IlsException):
144
153
  """A patron already has a loan request on a document."""
145
154
 
155
+ code = 400
146
156
  description = (
147
157
  "Patron '{patron_pid}' has already a loan "
148
158
  "request on document '{document_pid}'"
@@ -163,6 +173,7 @@ class PatronHasRequestOnDocumentError(IlsException):
163
173
  class PatronHasLoanOnDocumentError(IlsException):
164
174
  """A patron already has an active loan on a document."""
165
175
 
176
+ code = 400
166
177
  description = (
167
178
  "Patron '{patron_pid}' has already an active loan "
168
179
  "on document '{document_pid}'"
@@ -194,9 +205,54 @@ class LoanCheckoutByPatronForbidden(IlsException):
194
205
  )
195
206
 
196
207
 
208
+ class LoanSelfCheckoutItemUnavailable(IlsException):
209
+ """A patron cannot self-checkout an item."""
210
+
211
+ code = 400
212
+ description = "This literature is not available for self-checkout. Please contact the library for more information."
213
+
214
+ def get_body(self, environ=None, scope=None):
215
+ """Get the request body."""
216
+ body = dict(
217
+ status=self.code,
218
+ message=self.get_description(environ),
219
+ )
220
+
221
+ if self.supportCode:
222
+ body["supportCode"] = self.supportCode
223
+
224
+ return json.dumps(body)
225
+
226
+
227
+ class LoanSelfCheckoutItemInvalidStatus(LoanSelfCheckoutItemUnavailable):
228
+ """A patron cannot self-checkout an item that cannot circulate."""
229
+
230
+ supportCode = "SELF-CHECKOUT-001"
231
+
232
+
233
+ class LoanSelfCheckoutDocumentOverbooked(LoanSelfCheckoutItemUnavailable):
234
+ """A patron cannot self-checkout an item for an overbooked document."""
235
+
236
+ supportCode = "SELF-CHECKOUT-002"
237
+
238
+
239
+ class LoanSelfCheckoutItemActiveLoan(LoanSelfCheckoutItemUnavailable):
240
+ """A patron cannot self-checkout an item that cannot circulate."""
241
+
242
+ supportCode = "SELF-CHECKOUT-003"
243
+
244
+
245
+ class LoanSelfCheckoutItemNotFound(LoanSelfCheckoutItemUnavailable):
246
+ """A patron cannot self-checkout an item because item with provided barcode doesn't exist."""
247
+
248
+ supportCode = "SELF-CHECKOUT-004"
249
+ description = "Literature not found. Please try again with another barcode or contact the library."
250
+
251
+
197
252
  class NotImplementedConfigurationError(IlsException):
198
253
  """Exception raised when function is not implemented."""
199
254
 
255
+ code = 500
200
256
  description = (
201
257
  "Function is not implemented. Implement this function in your module "
202
258
  "and pass it to the config variable"
@@ -211,15 +267,20 @@ class NotImplementedConfigurationError(IlsException):
211
267
  class MissingRequiredParameterError(IlsException):
212
268
  """Exception raised when required parameter is missing."""
213
269
 
270
+ code = 400
271
+
214
272
 
215
273
  class InvalidParameterError(IlsException):
216
274
  """Exception raised when an invalid parameter is has been given."""
217
275
 
276
+ code = 400
277
+
218
278
 
219
279
  class DocumentNotFoundError(IlsException):
220
280
  """Raised when a document could not be found."""
221
281
 
222
- description = "Document PID '{}' was not found"
282
+ code = 404
283
+ description = "Document PID '{}' was not found."
223
284
 
224
285
  def __init__(self, document_pid, **kwargs):
225
286
  """Initialize exception."""
@@ -227,10 +288,38 @@ class DocumentNotFoundError(IlsException):
227
288
  self.description = self.description.format(document_pid)
228
289
 
229
290
 
291
+ class ItemNotFoundError(IlsException):
292
+ """Raised when an item could not be found."""
293
+
294
+ code = 404
295
+ description = "Item not found."
296
+
297
+ def __init__(self, pid=None, barcode=None, **kwargs):
298
+ """Initialize exception."""
299
+ super().__init__(**kwargs)
300
+ if pid:
301
+ self.description += " PID: {}".format(pid)
302
+ if barcode:
303
+ self.description += " Barcode: {}".format(barcode)
304
+
305
+
306
+ class MultipleItemsBarcodeFoundError(IlsException):
307
+ """Raised when multiple items with the same barcode has been found."""
308
+
309
+ code = 500
310
+ description = "Multiple items with barcode {} found."
311
+
312
+ def __init__(self, barcode, **kwargs):
313
+ """Initialize exception."""
314
+ super().__init__(**kwargs)
315
+ self.description = self.description.format(barcode)
316
+
317
+
230
318
  class LocationNotFoundError(IlsException):
231
319
  """Raised when a location could not be found."""
232
320
 
233
- description = "Location PID '{}' was not found"
321
+ code = 404
322
+ description = "Location PID '{}' was not found."
234
323
 
235
324
  def __init__(self, location_pid, **kwargs):
236
325
  """Initialize exception."""
@@ -241,7 +330,8 @@ class LocationNotFoundError(IlsException):
241
330
  class InternalLocationNotFoundError(IlsException):
242
331
  """Raised when an internal location could not be found."""
243
332
 
244
- description = "Internal Location PID '{}' was not found"
333
+ code = 404
334
+ description = "Internal Location PID '{}' was not found."
245
335
 
246
336
  def __init__(self, internal_location_pid, **kwargs):
247
337
  """Initialize exception."""
@@ -252,6 +342,7 @@ class InternalLocationNotFoundError(IlsException):
252
342
  class UnknownItemPidTypeError(IlsException):
253
343
  """Raised when the given item PID type is unknown."""
254
344
 
345
+ code = 400
255
346
  description = "Unknown Item PID type '{}'"
256
347
 
257
348
  def __init__(self, pid_type, **kwargs):
@@ -293,6 +384,14 @@ class DocumentRequestError(IlsException):
293
384
  super().__init__(description=description)
294
385
 
295
386
 
387
+ class DocumentOverbookedError(IlsException):
388
+ """Raised when a document is overbooked."""
389
+
390
+ def __init__(self, description):
391
+ """Initialize exception."""
392
+ super().__init__(description=description)
393
+
394
+
296
395
  class VocabularyError(IlsException):
297
396
  """Generic vocabulary exception."""
298
397
 
@@ -41,6 +41,19 @@ class ItemSearch(RecordsSearch):
41
41
 
42
42
  return search
43
43
 
44
+ def search_by_barcode(self, barcode, filter_states=None, exclude_states=None):
45
+ """Retrieve items matching the given barcode."""
46
+ search = self
47
+
48
+ search = search.filter("term", barcode=barcode)
49
+
50
+ if filter_states:
51
+ search = search.filter("terms", status=filter_states)
52
+ elif exclude_states:
53
+ search = search.exclude("terms", status=exclude_states)
54
+
55
+ return search
56
+
44
57
  def search_by_internal_location_pid(
45
58
  self,
46
59
  internal_location_pid=None,
@@ -12,18 +12,22 @@ from copy import deepcopy
12
12
 
13
13
  from flask import current_app
14
14
  from invenio_accounts.models import LoginInformation, SessionActivity, User, userrole
15
+ from invenio_circulation.pidstore.pids import CIRCULATION_LOAN_PID_TYPE
15
16
  from invenio_circulation.proxies import current_circulation
16
17
  from invenio_db import db
17
18
  from invenio_oauthclient.models import RemoteAccount, RemoteToken, UserIdentity
18
19
  from invenio_search.engine import search as inv_search
19
20
  from invenio_userprofiles.models import UserProfile
20
21
 
22
+ from invenio_app_ils.acquisition.api import ORDER_PID_TYPE
21
23
  from invenio_app_ils.acquisition.proxies import current_ils_acq
22
24
  from invenio_app_ils.circulation.search import (
23
25
  get_active_loans_by_patron_pid,
24
26
  get_loans_by_patron_pid,
25
27
  )
28
+ from invenio_app_ils.document_requests.api import DOCUMENT_REQUEST_PID_TYPE
26
29
  from invenio_app_ils.errors import AnonymizationActiveLoansError, PatronNotFoundError
30
+ from invenio_app_ils.ill.api import BORROWING_REQUEST_PID_TYPE
27
31
  from invenio_app_ils.ill.proxies import current_ils_ill
28
32
  from invenio_app_ils.notifications.models import NotificationsLogs
29
33
  from invenio_app_ils.patrons.api import get_patron_or_unknown_dump
@@ -106,9 +110,32 @@ def anonymize_patron_data(patron_pid, force=False):
106
110
  cls = current_app.config["ILS_PATRON_ANONYMOUS_CLASS"]
107
111
  anonymous_patron_fields = cls().dumps_loader()
108
112
 
113
+ Loan = current_circulation.loan_record_cls
114
+ BorrowingRequest = current_ils_ill.borrowing_request_record_cls
115
+ DocumentRequest = current_app_ils.document_request_record_cls
116
+ Order = current_ils_acq.order_record_cls
117
+
118
+ anonymized_records = {
119
+ CIRCULATION_LOAN_PID_TYPE: {
120
+ "indexer": current_circulation.loan_indexer(),
121
+ "records": [],
122
+ },
123
+ BORROWING_REQUEST_PID_TYPE: {
124
+ "indexer": current_ils_ill.borrowing_request_indexer_cls(),
125
+ "records": [],
126
+ },
127
+ DOCUMENT_REQUEST_PID_TYPE: {
128
+ "indexer": current_app_ils.document_request_indexer,
129
+ "records": [],
130
+ },
131
+ ORDER_PID_TYPE: {
132
+ "indexer": current_ils_acq.order_indexer,
133
+ "records": [],
134
+ },
135
+ }
136
+
109
137
  patron_loans = get_loans_by_patron_pid(patron_pid).scan()
110
138
 
111
- Loan = current_circulation.loan_record_cls
112
139
  indices = 0
113
140
  for hit in patron_loans:
114
141
  loan = Loan.get_record_by_pid(hit.pid)
@@ -131,7 +158,7 @@ def anonymize_patron_data(patron_pid, force=False):
131
158
  loan["patron_pid"] = anonymous_patron_fields["pid"]
132
159
  loan["patron"] = anonymous_patron_fields
133
160
  loan.commit()
134
- current_circulation.loan_indexer().index(loan)
161
+ anonymized_records[CIRCULATION_LOAN_PID_TYPE]["records"].append(loan)
135
162
  indices += 1
136
163
 
137
164
  BorrowingRequestsSearch = current_ils_ill.borrowing_request_search_cls
@@ -139,14 +166,12 @@ def anonymize_patron_data(patron_pid, force=False):
139
166
  BorrowingRequestsSearch().search_by_patron_pid(patron_pid).scan()
140
167
  )
141
168
 
142
- BorrowingRequest = current_ils_ill.borrowing_request_record_cls
143
- indexer = current_ils_ill.borrowing_request_indexer_cls()
144
169
  for hit in patron_borrowing_requests:
145
170
  borrowing_request = BorrowingRequest.get_record_by_pid(hit.pid)
146
171
  borrowing_request["patron"] = anonymous_patron_fields
147
172
  borrowing_request["patron_pid"] = anonymous_patron_fields["pid"]
148
173
  borrowing_request.commit()
149
- indexer.index(borrowing_request)
174
+ anonymized_records[BORROWING_REQUEST_PID_TYPE]["records"].append(borrowing_request)
150
175
  indices += 1
151
176
 
152
177
  DocumentRequestSearch = current_app_ils.document_request_search_cls
@@ -154,7 +179,6 @@ def anonymize_patron_data(patron_pid, force=False):
154
179
  DocumentRequestSearch().search_by_patron_pid(patron_pid).scan()
155
180
  )
156
181
 
157
- DocumentRequest = current_app_ils.document_request_record_cls
158
182
  for hit in patron_document_requests:
159
183
  document_request = DocumentRequest.get_record_by_pid(hit.pid)
160
184
  if document_request["state"] == "PENDING":
@@ -163,19 +187,18 @@ def anonymize_patron_data(patron_pid, force=False):
163
187
  document_request["patron"] = anonymous_patron_fields
164
188
  document_request["patron_pid"] = anonymous_patron_fields["pid"]
165
189
  document_request.commit()
166
- current_app_ils.document_request_indexer.index(document_request)
190
+ anonymized_records[ORDER_PID_TYPE]["records"].append(document_request)
167
191
  indices += 1
168
192
 
169
193
  patron_acquisitions = OrderSearch().search_by_patron_pid(patron_pid).scan()
170
194
 
171
- Order = current_ils_acq.order_record_cls
172
195
  for hit in patron_acquisitions:
173
196
  acquisition = Order.get_record_by_pid(hit.pid)
174
197
  for line in acquisition["order_lines"]:
175
198
  if line.get("patron_pid") == patron_pid:
176
199
  line["patron_pid"] = anonymous_patron_fields["pid"]
177
200
  acquisition.commit()
178
- current_ils_acq.order_indexer.index(acquisition)
201
+ anonymized_records[Order._pid_type]["records"].append(acquisition)
179
202
  indices += 1
180
203
 
181
204
  # delete rows from db
@@ -185,6 +208,13 @@ def anonymize_patron_data(patron_pid, force=False):
185
208
  notifications = anonymize_patron_in_notification_logs(patron_pid)
186
209
 
187
210
  db.session.commit()
211
+
212
+ # index all after committing to DB, to ensure that no errors occurred.
213
+ for value in anonymized_records.values():
214
+ indexer, records = value["indexer"], value["records"]
215
+ for record in records:
216
+ indexer.index(record)
217
+
188
218
  if patron:
189
219
  try:
190
220
  patron_indexer = current_app_ils.patron_indexer
@@ -132,7 +132,10 @@ def patron_owner_permission(record):
132
132
 
133
133
 
134
134
  def loan_checkout_permission(*args, **kwargs):
135
- """Return permission to allow admins and librarians to checkout and patrons to self-checkout if enabled."""
135
+ """Loan checkout permissions checks.
136
+
137
+ Allow admins and librarians to checkout, patrons to self-checkout when enabled.
138
+ """
136
139
  if not has_request_context():
137
140
  # CLI or Celery task
138
141
  return backoffice_permission()
@@ -199,8 +202,10 @@ def views_permissions_factory(action):
199
202
  elif action in _is_patron_owner_permission:
200
203
  return PatronOwnerPermission
201
204
  elif action == "circulation-loan-checkout":
202
- if current_app.config["ILS_SELF_CHECKOUT_ENABLED"]:
203
- return authenticated_user_permission()
204
- else:
205
- return backoffice_permission()
205
+ return backoffice_permission()
206
+ elif (
207
+ action == "circulation-loan-self-checkout"
208
+ and current_app.config["ILS_SELF_CHECKOUT_ENABLED"]
209
+ ):
210
+ return authenticated_user_permission()
206
211
  return deny_all()
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: invenio-app-ils
3
- Version: 4.2.0
3
+ Version: 4.4.0
4
4
  Summary: Invenio Integrated Library System.
5
5
  Home-page: https://github.com/inveniosoftware/invenio-app-ils
6
6
  Author: CERN
@@ -16,15 +16,15 @@ Requires-Dist: invenio-app<1.4.0,>=1.3.4
16
16
  Requires-Dist: invenio-db[mysql,postgresql]<2.0.0,>=1.0.14
17
17
  Requires-Dist: invenio-base<1.3.0,>=1.2.11
18
18
  Requires-Dist: invenio-cache<2.0.0,>=1.1.1
19
- Requires-Dist: invenio-celery<1.3.0,>=1.2.4
19
+ Requires-Dist: invenio-celery<2.0.0,>=1.2.4
20
20
  Requires-Dist: invenio-config<1.1.0,>=1.0.3
21
21
  Requires-Dist: invenio-i18n<3.0.0,>=2.0.0
22
22
  Requires-Dist: invenio-admin<1.5.0,>=1.4.0
23
23
  Requires-Dist: invenio-assets<4.0.0,>=3.0.0
24
24
  Requires-Dist: invenio-formatter<3.0.0,>=2.0.0
25
- Requires-Dist: invenio-logging[sentry_sdk]<3.0.0,>=2.0.0
25
+ Requires-Dist: invenio-logging[sentry]<3.0.0,>=2.1.5
26
26
  Requires-Dist: invenio-mail<3.0.0,>=2.0.0
27
- Requires-Dist: invenio-rest<1.4.0,>=1.3.0
27
+ Requires-Dist: invenio-rest<1.6.0,>=1.5.0
28
28
  Requires-Dist: invenio-theme<3.0.0,>=2.0.0
29
29
  Requires-Dist: invenio-access<3.0.0,>=2.0.0
30
30
  Requires-Dist: invenio-accounts<4.0.0,>=3.0.0
@@ -53,11 +53,6 @@ Requires-Dist: itsdangerous<2.1,>=1.1
53
53
  Requires-Dist: SQLAlchemy<2.0.0,>=1.3.0
54
54
  Requires-Dist: Flask<2.3.0,>=2.2.0
55
55
  Requires-Dist: Werkzeug<2.3.0,>=2.2.0
56
- Provides-Extra: docs
57
- Provides-Extra: lorem
58
- Requires-Dist: lorem>=0.1.1; extra == "lorem"
59
- Provides-Extra: opensearch2
60
- Requires-Dist: invenio-search[opensearch2]<3.0.0,>=2.0.0; extra == "opensearch2"
61
56
  Provides-Extra: tests
62
57
  Requires-Dist: pytest-black>=0.3.0; extra == "tests"
63
58
  Requires-Dist: mock>=2.0.0; extra == "tests"
@@ -66,6 +61,11 @@ Requires-Dist: docker-services-cli>=0.6.0; extra == "tests"
66
61
  Requires-Dist: pydocstyle==6.1.1; extra == "tests"
67
62
  Requires-Dist: pytest-mock>=1.6.0; extra == "tests"
68
63
  Requires-Dist: sphinx>=5; extra == "tests"
64
+ Provides-Extra: lorem
65
+ Requires-Dist: lorem>=0.1.1; extra == "lorem"
66
+ Provides-Extra: opensearch2
67
+ Requires-Dist: invenio-search[opensearch2]<3.0.0,>=2.0.0; extra == "opensearch2"
68
+ Provides-Extra: docs
69
69
 
70
70
  ..
71
71
  Copyright (C) 2018-2020 CERN.
@@ -101,6 +101,20 @@ https://invenioils.docs.cern.ch
101
101
  Changes
102
102
  =======
103
103
 
104
+
105
+ Version 4.4.0 (released 2025-02-21)
106
+
107
+ - installation: pin invenio-logging
108
+
109
+ Version 4.3.0 (released 2024-11-19)
110
+
111
+ - self-checkout: use dedicated endpoints for the entire workflow for better
112
+ permissions check and error handling.
113
+ Add a new loan transition and delivery method for self-checkout.
114
+ - anonymization: ensure that re-indexing is happening after the commit to the db,
115
+ to avoid premature re-indexing (and therefore index conflict version)
116
+ when db rollback happens.
117
+
104
118
  Version 4.2.0 (released 2024-11-04)
105
119
 
106
120
  - self-checkout: barcode is now always uppercased to make searches case-insensitive
@@ -567,5 +581,3 @@ Version 1.0.0a4 (released 2020-06-19)
567
581
  Version 1.0.0a0 (released 2020-06-05)
568
582
 
569
583
  - Initial public release.
570
-
571
-
@@ -1,13 +1,13 @@
1
- invenio_app_ils/__init__.py,sha256=BG7JkbyAvqXyUKbb3oLeYr_yMXjp_IyeBWbEWEVKyWY,285
1
+ invenio_app_ils/__init__.py,sha256=meAZ9qX5aymnutmLfBi3C_OoS3FUGNa1s4NHG2QrM4I,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=fW1svDhawp1BfkG_ynvSzJxeN3ea_gPz8-NCr1ICiHc,6859
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=ZVRFTgn8ZV_ku4nA_GAlyIYc10F-6mpekKiGqF5y_Eo,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
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
@@ -226,7 +228,7 @@ invenio_app_ils/internal_locations/schemas/internal_locations/internal_location-
226
228
  invenio_app_ils/items/__init__.py,sha256=Jdz0wSG1rNZyyit0VynCMQVDUHo0Vv1S3A2V-PICDfU,226
227
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
@@ -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
@@ -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
@@ -517,7 +519,7 @@ tests/data/eitems.json,sha256=2qwmHZkTf718Jizmk7YAO1v_8gs4yOm4dytzmvD-asQ,2122
517
519
  tests/data/ill_borrowing_requests.json,sha256=XG3xQnBizpeXrgUsNHphqLA7wQKEYEdLbkYwTZdqOIM,1603
518
520
  tests/data/ill_providers.json,sha256=M1NPVcjyP3_3r4Ynrltf5ZJ8QReBVHzV2fYSVUmj5Nc,169
519
521
  tests/data/internal_locations.json,sha256=CMXYQ98d9Hhu7YnaQoxrUGAoyIe43kTikE3CIhXPq9E,396
520
- tests/data/items.json,sha256=VnPhr7L6dMzi0drzj_XEXKO3OyfktRBnX3_cd6XT4y8,7832
522
+ tests/data/items.json,sha256=CUH1RooPv3aI3xKTJ7yN_GKZ19Ap8Cv0dsT8ZcV6igY,8528
521
523
  tests/data/loans.json,sha256=xVTnEc9IuJdu0Fspd0HDNHM8ZO26lir3EEkwaAvTGIM,3668
522
524
  tests/data/loans_most_loaned.json,sha256=ut1bOCFHCShPv_HotAjVV59gfwNfjpxEahyPCOZmQgY,3039
523
525
  tests/data/locations.json,sha256=2-xvSY4x8MJsDzlK-aleXaJw6mPMaQe7rJqwX1YqxfM,1637
@@ -527,10 +529,10 @@ tests/templates/notifications/title_body.html,sha256=W-pa6eSm7glK9JEcTVo4G7yC3Q1
527
529
  tests/templates/notifications/title_body_html.html,sha256=wPDP-DpQ0c2AX3oIfLvJLRp7J_rMoesIc9nLx3apkDc,146
528
530
  tests/templates/notifications/title_body_html_ctx.html,sha256=qqfTZ9zKVXFqyXIcqt5BLHEJptRlUDPBPtLxPfTmNzQ,193
529
531
  tests/templates/notifications/title_only.html,sha256=aoZ0veSleRYdKPXWgN6fdXLaz3r-KAPzdfHSuHPR2Uo,45
530
- invenio_app_ils-4.2.0.dist-info/AUTHORS.rst,sha256=BaXCGzdHCmiMOl4qtVlh1qrfy2ROMVOQp6ylzy1m0ww,212
531
- invenio_app_ils-4.2.0.dist-info/LICENSE,sha256=9OdaPOAO1ZOJcRQ8BrGj7QAdaJc8SRSUgBtdom49MrI,1062
532
- invenio_app_ils-4.2.0.dist-info/METADATA,sha256=Y_QgDlw4LmdUhMgdoFh7WwQ34zlpruRFEn1mN9JnSQo,15976
533
- invenio_app_ils-4.2.0.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
534
- invenio_app_ils-4.2.0.dist-info/entry_points.txt,sha256=JbIlm87pY7dVL-gLh8Hmfav18psVHXLBmHBzA-fQqlY,7607
535
- invenio_app_ils-4.2.0.dist-info/top_level.txt,sha256=MQTU2NrM0if5YAyIsKmQ0k35skJ3IUyQT7eCD2IWiNQ,22
536
- invenio_app_ils-4.2.0.dist-info/RECORD,,
532
+ invenio_app_ils-4.4.0.dist-info/AUTHORS.rst,sha256=BaXCGzdHCmiMOl4qtVlh1qrfy2ROMVOQp6ylzy1m0ww,212
533
+ invenio_app_ils-4.4.0.dist-info/LICENSE,sha256=9OdaPOAO1ZOJcRQ8BrGj7QAdaJc8SRSUgBtdom49MrI,1062
534
+ invenio_app_ils-4.4.0.dist-info/METADATA,sha256=kFPwEemRyg_ePUbr0UCeGaq6b8BL37z_qj6wA_OXdGo,16508
535
+ invenio_app_ils-4.4.0.dist-info/WHEEL,sha256=9Hm2OB-j1QcCUq9Jguht7ayGIIZBRTdOXD1qg9cCgPM,109
536
+ invenio_app_ils-4.4.0.dist-info/entry_points.txt,sha256=dLh4XxQPtPYRl_VNqzNpRK4l_sv_RQEyAm57tBBL7Ic,7606
537
+ invenio_app_ils-4.4.0.dist-info/top_level.txt,sha256=MQTU2NrM0if5YAyIsKmQ0k35skJ3IUyQT7eCD2IWiNQ,22
538
+ invenio_app_ils-4.4.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.8.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
-