folio-migration-tools 1.9.10__py3-none-any.whl → 1.10.0b1__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 (52) hide show
  1. folio_migration_tools/__init__.py +3 -4
  2. folio_migration_tools/__main__.py +44 -31
  3. folio_migration_tools/circulation_helper.py +114 -105
  4. folio_migration_tools/custom_dict.py +2 -2
  5. folio_migration_tools/custom_exceptions.py +4 -5
  6. folio_migration_tools/folder_structure.py +1 -1
  7. folio_migration_tools/helper.py +1 -1
  8. folio_migration_tools/library_configuration.py +65 -37
  9. folio_migration_tools/mapper_base.py +38 -25
  10. folio_migration_tools/mapping_file_transformation/courses_mapper.py +1 -1
  11. folio_migration_tools/mapping_file_transformation/holdings_mapper.py +7 -3
  12. folio_migration_tools/mapping_file_transformation/item_mapper.py +13 -26
  13. folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +1 -2
  14. folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +13 -11
  15. folio_migration_tools/mapping_file_transformation/order_mapper.py +6 -5
  16. folio_migration_tools/mapping_file_transformation/organization_mapper.py +3 -3
  17. folio_migration_tools/mapping_file_transformation/user_mapper.py +43 -28
  18. folio_migration_tools/marc_rules_transformation/conditions.py +84 -70
  19. folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +13 -5
  20. folio_migration_tools/marc_rules_transformation/hrid_handler.py +3 -2
  21. folio_migration_tools/marc_rules_transformation/marc_file_processor.py +14 -22
  22. folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +1 -0
  23. folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +46 -36
  24. folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +25 -15
  25. folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +62 -32
  26. folio_migration_tools/migration_report.py +1 -1
  27. folio_migration_tools/migration_tasks/authority_transformer.py +1 -2
  28. folio_migration_tools/migration_tasks/batch_poster.py +78 -68
  29. folio_migration_tools/migration_tasks/bibs_transformer.py +12 -7
  30. folio_migration_tools/migration_tasks/courses_migrator.py +2 -3
  31. folio_migration_tools/migration_tasks/holdings_csv_transformer.py +14 -15
  32. folio_migration_tools/migration_tasks/holdings_marc_transformer.py +11 -21
  33. folio_migration_tools/migration_tasks/items_transformer.py +17 -30
  34. folio_migration_tools/migration_tasks/loans_migrator.py +53 -131
  35. folio_migration_tools/migration_tasks/migration_task_base.py +33 -55
  36. folio_migration_tools/migration_tasks/orders_transformer.py +21 -39
  37. folio_migration_tools/migration_tasks/organization_transformer.py +9 -18
  38. folio_migration_tools/migration_tasks/requests_migrator.py +11 -15
  39. folio_migration_tools/migration_tasks/reserves_migrator.py +1 -1
  40. folio_migration_tools/migration_tasks/user_transformer.py +10 -15
  41. folio_migration_tools/task_configuration.py +6 -7
  42. folio_migration_tools/transaction_migration/legacy_loan.py +15 -27
  43. folio_migration_tools/transaction_migration/legacy_request.py +1 -1
  44. {folio_migration_tools-1.9.10.dist-info → folio_migration_tools-1.10.0b1.dist-info}/METADATA +18 -28
  45. {folio_migration_tools-1.9.10.dist-info → folio_migration_tools-1.10.0b1.dist-info}/RECORD +47 -50
  46. folio_migration_tools-1.10.0b1.dist-info/WHEEL +4 -0
  47. folio_migration_tools-1.10.0b1.dist-info/entry_points.txt +3 -0
  48. folio_migration_tools/test_infrastructure/__init__.py +0 -0
  49. folio_migration_tools/test_infrastructure/mocked_classes.py +0 -406
  50. folio_migration_tools-1.9.10.dist-info/WHEEL +0 -4
  51. folio_migration_tools-1.9.10.dist-info/entry_points.txt +0 -3
  52. folio_migration_tools-1.9.10.dist-info/licenses/LICENSE +0 -21
@@ -53,10 +53,7 @@ class ItemsTransformer(MigrationTaskBase):
53
53
  HridHandling,
54
54
  Field(
55
55
  title="HRID handling",
56
- description=(
57
- "Determining how the HRID generation "
58
- "should be handled."
59
- ),
56
+ description=("Determining how the HRID generation should be handled."),
60
57
  ),
61
58
  ]
62
59
  files: Annotated[
@@ -91,10 +88,7 @@ class ItemsTransformer(MigrationTaskBase):
91
88
  Optional[str],
92
89
  Field(
93
90
  title="Temporary location map file name",
94
- description=(
95
- "Temporary file name for location map. "
96
- "Empty string by default."
97
- ),
91
+ description=("Temporary file name for location map. Empty string by default."),
98
92
  ),
99
93
  ] = ""
100
94
  material_types_map_file_name: Annotated[
@@ -115,10 +109,7 @@ class ItemsTransformer(MigrationTaskBase):
115
109
  Optional[str],
116
110
  Field(
117
111
  title="Temporary loan types map file name",
118
- description=(
119
- "File name for temporary loan types map. "
120
- "Empty string by default."
121
- ),
112
+ description=("File name for temporary loan types map. Empty string by default."),
122
113
  ),
123
114
  ] = ""
124
115
  statistical_codes_map_file_name: Annotated[
@@ -218,9 +209,8 @@ class ItemsTransformer(MigrationTaskBase):
218
209
  self.folio_keys = MappingFileMapperBase.get_mapped_folio_properties_from_map(
219
210
  self.items_map
220
211
  )
221
- if (
222
- any(k for k in self.folio_keys if k.startswith("statisticalCodeIds"))
223
- or any(getattr(k, "statistical_code", "") for k in self.task_configuration.files)
212
+ if any(k for k in self.folio_keys if k.startswith("statisticalCodeIds")) or any(
213
+ getattr(k, "statistical_code", "") for k in self.task_configuration.files
224
214
  ):
225
215
  statcode_mapping = self.load_ref_data_mapping_file(
226
216
  "statisticalCodeIds",
@@ -307,7 +297,7 @@ class ItemsTransformer(MigrationTaskBase):
307
297
  temporary_loan_type_mapping,
308
298
  temporary_location_mapping,
309
299
  self.library_configuration,
310
- self.task_configuration
300
+ self.task_configuration,
311
301
  )
312
302
  if (
313
303
  self.task_configuration.reset_hrid_settings
@@ -363,9 +353,7 @@ class ItemsTransformer(MigrationTaskBase):
363
353
  self.handle_notes(folio_rec)
364
354
  if folio_rec["holdingsRecordId"] in self.boundwith_relationship_map:
365
355
  for idx_, instance_id in enumerate(
366
- self.boundwith_relationship_map.get(
367
- folio_rec["holdingsRecordId"]
368
- )
356
+ self.boundwith_relationship_map.get(folio_rec["holdingsRecordId"])
369
357
  ):
370
358
  if idx_ == 0:
371
359
  bw_id = folio_rec["holdingsRecordId"]
@@ -453,29 +441,28 @@ class ItemsTransformer(MigrationTaskBase):
453
441
  def load_boundwith_relationships(self):
454
442
  try:
455
443
  with open(
456
- self.folder_structure.boundwith_relationships_map_path
444
+ self.folder_structure.boundwith_relationships_map_path
457
445
  ) as boundwith_relationship_file:
458
446
  self.boundwith_relationship_map = dict(
459
- json.loads(x) for x in boundwith_relationship_file
460
- )
461
- logging.info(
462
- "Rows in Bound with relationship map: %s",
463
- len(self.boundwith_relationship_map)
447
+ json.loads(x) for x in boundwith_relationship_file
464
448
  )
465
- except FileNotFoundError:
449
+ logging.info(
450
+ "Rows in Bound with relationship map: %s", len(self.boundwith_relationship_map)
451
+ )
452
+ except FileNotFoundError as fnfe:
466
453
  raise TransformationProcessError(
467
454
  "",
468
455
  "Boundwith relationship file specified, but relationships file "
469
456
  "from holdings transformation not found.",
470
- self.folder_structure.boundwith_relationships_map_path
471
- )
472
- except ValueError:
457
+ self.folder_structure.boundwith_relationships_map_path,
458
+ ) from fnfe
459
+ except ValueError as ve:
473
460
  raise TransformationProcessError(
474
461
  "",
475
462
  "Boundwith relationship file specified, but relationships file "
476
463
  "from holdings transformation is not a valid line JSON.",
477
464
  self.folder_structure.boundwith_relationships_map_path,
478
- )
465
+ ) from ve
479
466
 
480
467
  def wrap_up(self):
481
468
  logging.info("Done. Transformer wrapping up...")
@@ -76,18 +76,14 @@ class LoansMigrator(MigrationTaskBase):
76
76
  Optional[list[FileDefinition]],
77
77
  Field(
78
78
  title="Item files",
79
- description=(
80
- "List of files containing item data. By default is empty list."
81
- ),
79
+ description=("List of files containing item data. By default is empty list."),
82
80
  ),
83
81
  ] = []
84
82
  patron_files: Annotated[
85
83
  Optional[list[FileDefinition]],
86
84
  Field(
87
85
  title="Patron files",
88
- description=(
89
- "List of files containing patron data. By default is empty list."
90
- ),
86
+ description=("List of files containing patron data. By default is empty list."),
91
87
  ),
92
88
  ] = []
93
89
 
@@ -124,9 +120,7 @@ class LoansMigrator(MigrationTaskBase):
124
120
  my_path = "/configurations/entries?query=(module==ORG%20and%20configName==localeSettings)"
125
121
  try:
126
122
  self.tenant_timezone_str = json.loads(
127
- self.folio_client.folio_get_single_object(my_path)["configs"][0][
128
- "value"
129
- ]
123
+ self.folio_client.folio_get_single_object(my_path)["configs"][0]["value"]
130
124
  )["timezone"]
131
125
  logging.info("Tenant timezone is: %s", self.tenant_timezone_str)
132
126
  except Exception:
@@ -135,14 +129,10 @@ class LoansMigrator(MigrationTaskBase):
135
129
  self.tenant_timezone = ZoneInfo(self.tenant_timezone_str)
136
130
  self.semi_valid_legacy_loans = []
137
131
  for file_def in task_configuration.open_loans_files:
138
- loans_file_path = (
139
- self.folder_structure.legacy_records_folder / file_def.file_name
140
- )
132
+ loans_file_path = self.folder_structure.legacy_records_folder / file_def.file_name
141
133
  with open(loans_file_path, "r", encoding="utf-8") as loans_file:
142
- total_rows, empty_rows, reader = (
143
- MappingFileMapperBase._get_delimited_file_reader(
144
- loans_file, loans_file_path
145
- )
134
+ total_rows, empty_rows, reader = MappingFileMapperBase._get_delimited_file_reader(
135
+ loans_file, loans_file_path
146
136
  )
147
137
  logging.info("Source data file contains %d rows", total_rows)
148
138
  logging.info("Source data file contains %d empty rows", empty_rows)
@@ -159,8 +149,7 @@ class LoansMigrator(MigrationTaskBase):
159
149
  self.semi_valid_legacy_loans.extend(
160
150
  self.load_and_validate_legacy_loans(
161
151
  reader,
162
- file_def.service_point_id
163
- or task_configuration.fallback_service_point_id,
152
+ file_def.service_point_id or task_configuration.fallback_service_point_id,
164
153
  )
165
154
  )
166
155
 
@@ -169,12 +158,8 @@ class LoansMigrator(MigrationTaskBase):
169
158
  len(self.semi_valid_legacy_loans),
170
159
  file_def.file_name,
171
160
  )
172
- logging.info(
173
- "Loaded and validated %s loans in total", len(self.semi_valid_legacy_loans)
174
- )
175
- if any(self.task_configuration.item_files) or any(
176
- self.task_configuration.patron_files
177
- ):
161
+ logging.info("Loaded and validated %s loans in total", len(self.semi_valid_legacy_loans))
162
+ if any(self.task_configuration.item_files) or any(self.task_configuration.patron_files):
178
163
  self.valid_legacy_loans = list(self.check_barcodes())
179
164
  logging.info(
180
165
  "Loaded and validated %s loans against barcodes",
@@ -182,8 +167,7 @@ class LoansMigrator(MigrationTaskBase):
182
167
  )
183
168
  else:
184
169
  logging.info(
185
- "No item or user files supplied. Not validating against"
186
- "previously migrated objects"
170
+ "No item or user files supplied. Not validating againstpreviously migrated objects"
187
171
  )
188
172
  self.valid_legacy_loans = self.semi_valid_legacy_loans
189
173
  logging.info("Starting row number is %s", task_configuration.starting_row)
@@ -191,9 +175,9 @@ class LoansMigrator(MigrationTaskBase):
191
175
 
192
176
  def check_smtp_config(self):
193
177
  try:
194
- smtp_config = self.folio_client.folio_get_single_object(
195
- "/smtp-configuration"
196
- )["smtpConfigurations"][0]
178
+ smtp_config = self.folio_client.folio_get_single_object("/smtp-configuration")[
179
+ "smtpConfigurations"
180
+ ][0]
197
181
  smtp_config_disabled = "disabled" in smtp_config["host"].lower()
198
182
  except IndexError:
199
183
  smtp_config_disabled = True
@@ -201,9 +185,7 @@ class LoansMigrator(MigrationTaskBase):
201
185
  if not smtp_config_disabled:
202
186
  logging.warn("SMTP connection not disabled...")
203
187
  for i in range(10, 0, -1):
204
- sys.stdout.write(
205
- "Pausing for {:02d} seconds. Press Ctrl+C to exit...\r".format(i)
206
- )
188
+ sys.stdout.write("Pausing for {:02d} seconds. Press Ctrl+C to exit...\r".format(i))
207
189
  time.sleep(1)
208
190
  else:
209
191
  logging.info("SMTP connection is disabled...")
@@ -229,7 +211,8 @@ class LoansMigrator(MigrationTaskBase):
229
211
  self.checkout_single_loan(legacy_loan)
230
212
  except TransformationRecordFailedError as ee:
231
213
  logging.error(
232
- f"Transformation failed in row {num_loans} Item barcode: {legacy_loan.item_barcode} "
214
+ f"Transformation failed in row {num_loans} "
215
+ f"Item barcode: {legacy_loan.item_barcode} "
233
216
  f"Patron barcode: {legacy_loan.patron_barcode}"
234
217
  )
235
218
  ee.log_it()
@@ -239,9 +222,7 @@ class LoansMigrator(MigrationTaskBase):
239
222
  f"Patron barcode: {legacy_loan.patron_barcode} {ee}"
240
223
  )
241
224
  if num_loans % 25 == 0:
242
- logging.info(
243
- f"{timings(self.t0, t0_migration, num_loans)} {num_loans}"
244
- )
225
+ logging.info(f"{timings(self.t0, t0_migration, num_loans)} {num_loans}")
245
226
 
246
227
  def checkout_single_loan(self, legacy_loan: LegacyLoan):
247
228
  """Checks a legacy loan out. Retries once if it fails.
@@ -253,20 +234,14 @@ class LoansMigrator(MigrationTaskBase):
253
234
 
254
235
  if res_checkout.was_successful:
255
236
  self.migration_report.add("Details", i18n.t("Checked out on first try"))
256
- self.migration_report.add_general_statistics(
257
- i18n.t("Successfully checked out")
258
- )
237
+ self.migration_report.add_general_statistics(i18n.t("Successfully checked out"))
259
238
  self.set_renewal_count(legacy_loan, res_checkout)
260
239
  self.set_new_status(legacy_loan, res_checkout)
261
240
  elif res_checkout.should_be_retried:
262
241
  res_checkout2 = self.handle_checkout_failure(legacy_loan, res_checkout)
263
242
  if res_checkout2.was_successful and res_checkout2.folio_loan:
264
- self.migration_report.add(
265
- "Details", i18n.t("Checked out on second try")
266
- )
267
- self.migration_report.add_general_statistics(
268
- i18n.t("Successfully checked out")
269
- )
243
+ self.migration_report.add("Details", i18n.t("Checked out on second try"))
244
+ self.migration_report.add_general_statistics(i18n.t("Successfully checked out"))
270
245
  logging.info("Checked out on second try")
271
246
  self.set_renewal_count(legacy_loan, res_checkout2)
272
247
  self.set_new_status(legacy_loan, res_checkout2)
@@ -274,8 +249,7 @@ class LoansMigrator(MigrationTaskBase):
274
249
  if res_checkout2.error_message == "Aged to lost and checked out":
275
250
  self.migration_report.add(
276
251
  "Details",
277
- i18n.t("Second failure")
278
- + f": {res_checkout2.migration_report_message}",
252
+ i18n.t("Second failure") + f": {res_checkout2.migration_report_message}",
279
253
  )
280
254
  logging.error(
281
255
  f"{res_checkout2.error_message}. Item barcode: {legacy_loan.item_barcode}"
@@ -283,13 +257,10 @@ class LoansMigrator(MigrationTaskBase):
283
257
  else:
284
258
  self.failed[legacy_loan.item_barcode] = legacy_loan
285
259
  self.migration_report.add_general_statistics(i18n.t("Failed loans"))
286
- logging.error(
287
- "Failed on second try: %s", res_checkout2.error_message
288
- )
260
+ logging.error("Failed on second try: %s", res_checkout2.error_message)
289
261
  self.migration_report.add(
290
262
  "Details",
291
- i18n.t("Second failure")
292
- + f": {res_checkout2.migration_report_message}",
263
+ i18n.t("Second failure") + f": {res_checkout2.migration_report_message}",
293
264
  )
294
265
  raise TransformationRecordFailedError(
295
266
  f"Row {legacy_loan.row}",
@@ -297,9 +268,7 @@ class LoansMigrator(MigrationTaskBase):
297
268
  json.dumps(legacy_loan.to_dict()),
298
269
  )
299
270
  elif not res_checkout.should_be_retried:
300
- logging.error(
301
- "Failed first time. No retries: %s", res_checkout.error_message
302
- )
271
+ logging.error("Failed first time. No retries: %s", res_checkout.error_message)
303
272
  self.migration_report.add_general_statistics(i18n.t("Failed loans"))
304
273
  self.migration_report.add(
305
274
  "Details",
@@ -328,14 +297,10 @@ class LoansMigrator(MigrationTaskBase):
328
297
  elif legacy_loan.next_item_status not in ["Available", "", "Checked out"]:
329
298
  self.set_item_status(legacy_loan)
330
299
 
331
- def set_renewal_count(
332
- self, legacy_loan: LegacyLoan, res_checkout: TransactionResult
333
- ):
300
+ def set_renewal_count(self, legacy_loan: LegacyLoan, res_checkout: TransactionResult):
334
301
  if legacy_loan.renewal_count > 0:
335
302
  self.update_open_loan(res_checkout.folio_loan, legacy_loan)
336
- self.migration_report.add_general_statistics(
337
- i18n.t("Updated renewal count for loan")
338
- )
303
+ self.migration_report.add_general_statistics(i18n.t("Updated renewal count for loan"))
339
304
 
340
305
  def wrap_up(self):
341
306
  for k, v in self.failed.items():
@@ -362,9 +327,7 @@ class LoansMigrator(MigrationTaskBase):
362
327
  "service_point_id",
363
328
  ]
364
329
  with open(self.folder_structure.failed_recs_path, "w+") as failed_loans_file:
365
- writer = csv.DictWriter(
366
- failed_loans_file, fieldnames=csv_columns, dialect="tsv"
367
- )
330
+ writer = csv.DictWriter(failed_loans_file, fieldnames=csv_columns, dialect="tsv")
368
331
  writer.writeheader()
369
332
  for _k, failed_loan in self.failed_and_not_dupe.items():
370
333
  writer.writerow(failed_loan[0])
@@ -379,16 +342,12 @@ class LoansMigrator(MigrationTaskBase):
379
342
  user_barcodes, self.task_configuration.patron_files, self.folder_structure
380
343
  )
381
344
  for loan in self.semi_valid_legacy_loans:
382
- has_item_barcode = loan.item_barcode in item_barcodes or not any(
383
- item_barcodes
384
- )
385
- has_patron_barcode = loan.patron_barcode in user_barcodes or not any(
386
- user_barcodes
387
- )
345
+ has_item_barcode = loan.item_barcode in item_barcodes or not any(item_barcodes)
346
+ has_patron_barcode = loan.patron_barcode in user_barcodes or not any(user_barcodes)
388
347
  has_proxy_barcode = True
389
348
  if loan.proxy_patron_barcode:
390
- has_proxy_barcode = (
391
- loan.proxy_patron_barcode in user_barcodes or not any(user_barcodes)
349
+ has_proxy_barcode = loan.proxy_patron_barcode in user_barcodes or not any(
350
+ user_barcodes
392
351
  )
393
352
  if has_item_barcode and has_patron_barcode and has_proxy_barcode:
394
353
  self.migration_report.add_general_statistics(
@@ -424,9 +383,7 @@ class LoansMigrator(MigrationTaskBase):
424
383
  json.dumps(loan.to_dict()),
425
384
  )
426
385
 
427
- def load_and_validate_legacy_loans(
428
- self, loans_reader, service_point_id: str
429
- ) -> list:
386
+ def load_and_validate_legacy_loans(self, loans_reader, service_point_id: str) -> list:
430
387
  results = []
431
388
  num_bad = 0
432
389
  logging.info("Validating legacy loans in file...")
@@ -446,29 +403,23 @@ class LoansMigrator(MigrationTaskBase):
446
403
  )
447
404
  self.migration_report.add_general_statistics(i18n.t("Failed loans"))
448
405
  for error in legacy_loan.errors:
449
- self.migration_report.add(
450
- "DiscardedLoans", f"{error[0]} - {error[1]}"
451
- )
406
+ self.migration_report.add("DiscardedLoans", f"{error[0]} - {error[1]}")
452
407
  # Add this loan to failed loans for later correction and re-run.
453
- self.failed[
454
- legacy_loan.item_barcode or f"no_barcode_{legacy_loan_count}"
455
- ] = legacy_loan
408
+ self.failed[legacy_loan.item_barcode or f"no_barcode_{legacy_loan_count}"] = (
409
+ legacy_loan
410
+ )
456
411
  else:
457
412
  results.append(legacy_loan)
458
413
  except TransformationRecordFailedError as trfe:
459
414
  num_bad += 1
460
- self.migration_report.add_general_statistics(
461
- i18n.t("Loans failed pre-validation")
462
- )
415
+ self.migration_report.add_general_statistics(i18n.t("Loans failed pre-validation"))
463
416
  self.migration_report.add(
464
417
  "DiscardedLoans",
465
418
  f"{trfe.message} - see data issues log",
466
419
  )
467
420
  trfe.log_it()
468
421
  self.failed[
469
- legacy_loan_dict.get(
470
- "item_barcode", f"no_barcode_{legacy_loan_count}"
471
- )
422
+ legacy_loan_dict.get("item_barcode", f"no_barcode_{legacy_loan_count}")
472
423
  ] = legacy_loan_dict
473
424
  except ValueError as ve:
474
425
  logging.exception(ve)
@@ -516,9 +467,7 @@ class LoansMigrator(MigrationTaskBase):
516
467
  return self.handle_lost_item(legacy_loan, "Aged to lost")
517
468
  elif folio_checkout.error_message == "Declared lost":
518
469
  return self.handle_lost_item(legacy_loan, "Declared lost")
519
- elif folio_checkout.error_message.startswith(
520
- "Cannot check out to inactive user"
521
- ):
470
+ elif folio_checkout.error_message.startswith("Cannot check out to inactive user"):
522
471
  return self.checkout_to_inactive_user(legacy_loan)
523
472
  elif (
524
473
  "has the item status Claimed returned and cannot be checked out"
@@ -550,9 +499,7 @@ class LoansMigrator(MigrationTaskBase):
550
499
  f"Duplicate loans (or failed twice) Item barcode: "
551
500
  f"{legacy_loan.item_barcode} Patron barcode: {legacy_loan.patron_barcode}"
552
501
  )
553
- self.migration_report.add(
554
- "Details", i18n.t("Duplicate loans (or failed twice)")
555
- )
502
+ self.migration_report.add("Details", i18n.t("Duplicate loans (or failed twice)"))
556
503
  del self.failed[legacy_loan.item_barcode]
557
504
  return TransactionResult(False, False, "", "", "")
558
505
 
@@ -563,9 +510,7 @@ class LoansMigrator(MigrationTaskBase):
563
510
  user["expirationDate"] = datetime.isoformat(datetime.now() + timedelta(days=1))
564
511
  self.activate_user(user)
565
512
  logging.debug("Successfully Activated user")
566
- res = self.circulation_helper.check_out_by_barcode(
567
- legacy_loan
568
- ) # checkout_and_update
513
+ res = self.circulation_helper.check_out_by_barcode(legacy_loan) # checkout_and_update
569
514
  if res.should_be_retried:
570
515
  res = self.handle_checkout_failure(legacy_loan, res)
571
516
  self.migration_report.add("Details", res.migration_report_message)
@@ -670,9 +615,7 @@ class LoansMigrator(MigrationTaskBase):
670
615
  loan_to_put["dueDate"] = due_date.isoformat()
671
616
  loan_to_put["loanDate"] = out_date.isoformat()
672
617
  loan_to_put["renewalCount"] = renewal_count
673
- url = (
674
- f"{self.folio_client.gateway_url}/circulation/loans/{loan_to_put['id']}"
675
- )
618
+ url = f"{self.folio_client.gateway_url}/circulation/loans/{loan_to_put['id']}"
676
619
  req = self.http_client.put(
677
620
  url,
678
621
  headers=self.folio_client.okapi_headers,
@@ -693,8 +636,7 @@ class LoansMigrator(MigrationTaskBase):
693
636
  else:
694
637
  self.migration_report.add(
695
638
  "Details",
696
- i18n.t("Update open loan error http status")
697
- + f": {req.status_code}",
639
+ i18n.t("Update open loan error http status") + f": {req.status_code}",
698
640
  )
699
641
  req.raise_for_status()
700
642
  logging.debug("Updating open loan was successful")
@@ -724,41 +666,27 @@ class LoansMigrator(MigrationTaskBase):
724
666
  "servicePointId": str(self.task_configuration.fallback_service_point_id),
725
667
  }
726
668
  logging.debug(f"Declare lost data: {json.dumps(data, indent=4)}")
727
- if self.folio_put_post(
728
- declare_lost_url, data, "POST", i18n.t("Declare item as lost")
729
- ):
730
- self.migration_report.add(
731
- "Details", i18n.t("Successfully declared loan as lost")
732
- )
669
+ if self.folio_put_post(declare_lost_url, data, "POST", i18n.t("Declare item as lost")):
670
+ self.migration_report.add("Details", i18n.t("Successfully declared loan as lost"))
733
671
  else:
734
672
  logging.error(f"Unsuccessfully declared loan {folio_loan} as lost")
735
- self.migration_report.add(
736
- "Details", i18n.t("Unsuccessfully declared loan as lost")
737
- )
673
+ self.migration_report.add("Details", i18n.t("Unsuccessfully declared loan as lost"))
738
674
 
739
675
  def claim_returned(self, folio_loan):
740
- claim_returned_url = (
741
- f"/circulation/loans/{folio_loan['id']}/claim-item-returned"
742
- )
676
+ claim_returned_url = f"/circulation/loans/{folio_loan['id']}/claim-item-returned"
743
677
  logging.debug(f"Claim returned url:{claim_returned_url}")
744
678
  due_date = du_parser.isoparse(folio_loan["dueDate"])
745
679
  data = {
746
- "itemClaimedReturnedDateTime": datetime.isoformat(
747
- due_date + timedelta(days=1)
748
- ),
680
+ "itemClaimedReturnedDateTime": datetime.isoformat(due_date + timedelta(days=1)),
749
681
  "comment": "Created at migration. Date is due date + 1 day",
750
682
  }
751
683
  logging.debug(f"Claim returned data:\t{json.dumps(data)}")
752
- if self.folio_put_post(
753
- claim_returned_url, data, "POST", i18n.t("Claim item returned")
754
- ):
684
+ if self.folio_put_post(claim_returned_url, data, "POST", i18n.t("Claim item returned")):
755
685
  self.migration_report.add(
756
686
  "Details", i18n.t("Successfully declared loan as Claimed returned")
757
687
  )
758
688
  else:
759
- logging.error(
760
- f"Unsuccessfully declared loan {folio_loan} as Claimed returned"
761
- )
689
+ logging.error(f"Unsuccessfully declared loan {folio_loan} as Claimed returned")
762
690
  self.migration_report.add(
763
691
  "Details",
764
692
  i18n.t(
@@ -770,13 +698,9 @@ class LoansMigrator(MigrationTaskBase):
770
698
  def set_item_status(self, legacy_loan: LegacyLoan):
771
699
  try:
772
700
  # Get Item by barcode, update status.
773
- item_path = (
774
- f'item-storage/items?query=(barcode=="{legacy_loan.item_barcode}")'
775
- )
701
+ item_path = f'item-storage/items?query=(barcode=="{legacy_loan.item_barcode}")'
776
702
  item_url = f"{self.folio_client.gateway_url}/{item_path}"
777
- resp = self.http_client.get(
778
- item_url, headers=self.folio_client.okapi_headers
779
- )
703
+ resp = self.http_client.get(item_url, headers=self.folio_client.okapi_headers)
780
704
  resp.raise_for_status()
781
705
  data = resp.json()
782
706
  folio_item = data["items"][0]
@@ -897,9 +821,7 @@ class LoansMigrator(MigrationTaskBase):
897
821
  try:
898
822
  api_path = f"{folio_loan['id']}/change-due-date"
899
823
  api_url = f"{self.folio_client.gateway_url}/circulation/loans/{api_path}"
900
- body = {
901
- "dueDate": du_parser.isoparse(str(legacy_loan.due_date)).isoformat()
902
- }
824
+ body = {"dueDate": du_parser.isoparse(str(legacy_loan.due_date)).isoformat()}
903
825
  req = self.http_client.post(
904
826
  api_url, headers=self.folio_client.okapi_headers, json=body
905
827
  )