folio-migration-tools 1.9.4__tar.gz → 1.9.5__tar.gz
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.
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/PKG-INFO +1 -1
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/pyproject.toml +1 -1
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/circulation_helper.py +8 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/helper.py +4 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/loans_migrator.py +21 -11
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/transaction_migration/legacy_loan.py +31 -9
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/LICENSE +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/README.md +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/__main__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/colors.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/config_file_load.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/custom_dict.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/custom_exceptions.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/extradata_writer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/folder_structure.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/holdings_helper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/i18n_config.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/library_configuration.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapper_base.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/courses_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/holdings_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/item_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/notes_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/order_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/organization_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapping_file_transformation/user_mapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/conditions.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/hrid_handler.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/marc_file_processor.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_report.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/authority_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/batch_poster.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/bibs_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/courses_migrator.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/holdings_csv_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/holdings_marc_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/items_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/migration_task_base.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/orders_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/organization_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/requests_migrator.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/reserves_migrator.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/migration_tasks/user_transformer.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/task_configuration.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/test_infrastructure/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/test_infrastructure/mocked_classes.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/transaction_migration/__init__.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/transaction_migration/legacy_request.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/transaction_migration/legacy_reserve.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/transaction_migration/transaction_result.py +0 -0
- {folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/translations/en.json +0 -0
|
@@ -198,6 +198,14 @@ class CirculationHelper:
|
|
|
198
198
|
error_message_from_folio,
|
|
199
199
|
error_message_from_folio,
|
|
200
200
|
)
|
|
201
|
+
elif "Item is already checked out" in error_message_from_folio:
|
|
202
|
+
return TransactionResult(
|
|
203
|
+
False,
|
|
204
|
+
True,
|
|
205
|
+
None,
|
|
206
|
+
error_message_from_folio,
|
|
207
|
+
error_message_from_folio,
|
|
208
|
+
)
|
|
201
209
|
logging.error(
|
|
202
210
|
f"{error_message} "
|
|
203
211
|
f"Patron barcode: {legacy_loan.patron_barcode} "
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/helper.py
RENAMED
|
@@ -56,6 +56,10 @@ class Helper:
|
|
|
56
56
|
@staticmethod
|
|
57
57
|
def log_data_issue(index_or_id, message, legacy_value):
|
|
58
58
|
logging.log(26, "DATA ISSUE\t%s\t%s\t%s", index_or_id, message, legacy_value)
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def log_data_issue_failed(index_or_id, message, legacy_value):
|
|
62
|
+
logging.log(26, "RECORD FAILED\t%s\t%s\t%s", index_or_id, message, legacy_value)
|
|
59
63
|
|
|
60
64
|
@staticmethod
|
|
61
65
|
def write_to_file(file, folio_record):
|
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
import time
|
|
7
7
|
import traceback
|
|
8
8
|
from datetime import datetime, timedelta
|
|
9
|
-
from typing import Annotated, Literal, Optional
|
|
9
|
+
from typing import Annotated, List, Literal, Optional
|
|
10
10
|
from urllib.error import HTTPError
|
|
11
11
|
from zoneinfo import ZoneInfo
|
|
12
12
|
from pydantic import Field
|
|
@@ -110,7 +110,7 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
110
110
|
self.failed: dict = {}
|
|
111
111
|
self.failed_and_not_dupe: dict = {}
|
|
112
112
|
self.migration_report = MigrationReport()
|
|
113
|
-
self.valid_legacy_loans = []
|
|
113
|
+
self.valid_legacy_loans: List[LegacyLoan] = []
|
|
114
114
|
super().__init__(library_config, task_configuration, folio_client)
|
|
115
115
|
self.circulation_helper = CirculationHelper(
|
|
116
116
|
self.folio_client,
|
|
@@ -227,6 +227,12 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
227
227
|
)
|
|
228
228
|
try:
|
|
229
229
|
self.checkout_single_loan(legacy_loan)
|
|
230
|
+
except TransformationRecordFailedError as ee:
|
|
231
|
+
logging.error(
|
|
232
|
+
f"Transformation failed in row {num_loans} Item barcode: {legacy_loan.item_barcode} "
|
|
233
|
+
f"Patron barcode: {legacy_loan.patron_barcode}"
|
|
234
|
+
)
|
|
235
|
+
ee.log_it()
|
|
230
236
|
except Exception as ee:
|
|
231
237
|
logging.exception(
|
|
232
238
|
f"Error in row {num_loans} Item barcode: {legacy_loan.item_barcode} "
|
|
@@ -277,11 +283,6 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
277
283
|
else:
|
|
278
284
|
self.failed[legacy_loan.item_barcode] = legacy_loan
|
|
279
285
|
self.migration_report.add_general_statistics(i18n.t("Failed loans"))
|
|
280
|
-
Helper.log_data_issue(
|
|
281
|
-
"",
|
|
282
|
-
"Loans failing during checkout",
|
|
283
|
-
json.dumps(legacy_loan.to_dict()),
|
|
284
|
-
)
|
|
285
286
|
logging.error(
|
|
286
287
|
"Failed on second try: %s", res_checkout2.error_message
|
|
287
288
|
)
|
|
@@ -290,6 +291,11 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
290
291
|
i18n.t("Second failure")
|
|
291
292
|
+ f": {res_checkout2.migration_report_message}",
|
|
292
293
|
)
|
|
294
|
+
raise TransformationRecordFailedError(
|
|
295
|
+
f"Row {legacy_loan.row}",
|
|
296
|
+
i18n.t("Loans failing during checkout, second try"),
|
|
297
|
+
json.dumps(legacy_loan.to_dict()),
|
|
298
|
+
)
|
|
293
299
|
elif not res_checkout.should_be_retried:
|
|
294
300
|
logging.error(
|
|
295
301
|
"Failed first time. No retries: %s", res_checkout.error_message
|
|
@@ -301,8 +307,10 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
301
307
|
+ f": {res_checkout.migration_report_message}",
|
|
302
308
|
)
|
|
303
309
|
self.failed[legacy_loan.item_barcode] = legacy_loan
|
|
304
|
-
|
|
305
|
-
"
|
|
310
|
+
raise TransformationRecordFailedError(
|
|
311
|
+
f"Row {legacy_loan.row}",
|
|
312
|
+
i18n.t("Loans failing during checkout"),
|
|
313
|
+
json.dumps(legacy_loan.to_dict()),
|
|
306
314
|
)
|
|
307
315
|
|
|
308
316
|
def set_new_status(self, legacy_loan: LegacyLoan, res_checkout: TransactionResult):
|
|
@@ -400,7 +408,7 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
400
408
|
+ f": {has_proxy_barcode}",
|
|
401
409
|
)
|
|
402
410
|
if not has_item_barcode:
|
|
403
|
-
Helper.
|
|
411
|
+
Helper.log_data_issue_failed(
|
|
404
412
|
"", "Loan without matched item barcode", json.dumps(loan.to_dict())
|
|
405
413
|
)
|
|
406
414
|
if not has_patron_barcode:
|
|
@@ -410,7 +418,7 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
410
418
|
json.dumps(loan.to_dict()),
|
|
411
419
|
)
|
|
412
420
|
if not has_proxy_barcode:
|
|
413
|
-
Helper.
|
|
421
|
+
Helper.log_data_issue_failed(
|
|
414
422
|
"",
|
|
415
423
|
"Loan without matched proxy patron barcode",
|
|
416
424
|
json.dumps(loan.to_dict()),
|
|
@@ -502,6 +510,8 @@ class LoansMigrator(MigrationTaskBase):
|
|
|
502
510
|
"Cannot check out item that already has an open loan"
|
|
503
511
|
):
|
|
504
512
|
return self.handle_checked_out_item(legacy_loan)
|
|
513
|
+
elif "Item is already checked out" in folio_checkout.error_message:
|
|
514
|
+
return self.handle_checked_out_item(legacy_loan)
|
|
505
515
|
elif "Aged to lost" in folio_checkout.error_message:
|
|
506
516
|
return self.handle_lost_item(legacy_loan, "Aged to lost")
|
|
507
517
|
elif folio_checkout.error_message == "Declared lost":
|
|
@@ -7,6 +7,7 @@ from zoneinfo import ZoneInfo
|
|
|
7
7
|
from dateutil import tz
|
|
8
8
|
from dateutil.parser import parse, ParserError
|
|
9
9
|
|
|
10
|
+
from folio_migration_tools.helper import Helper
|
|
10
11
|
from folio_migration_tools.migration_report import MigrationReport
|
|
11
12
|
from folio_migration_tools.custom_exceptions import TransformationRecordFailedError
|
|
12
13
|
|
|
@@ -62,15 +63,25 @@ class LegacyLoan(object):
|
|
|
62
63
|
temp_date_due: datetime = parse(self.legacy_loan_dict["due_date"])
|
|
63
64
|
if temp_date_due.tzinfo != tz.UTC:
|
|
64
65
|
temp_date_due = temp_date_due.replace(tzinfo=self.tenant_timezone)
|
|
65
|
-
|
|
66
|
+
Helper.log_data_issue(
|
|
67
|
+
self.row,
|
|
66
68
|
f"Provided due_date is not UTC in {row=}, "
|
|
67
|
-
f"setting tz-info to tenant timezone ({self.tenant_timezone})"
|
|
69
|
+
f"setting tz-info to tenant timezone ({self.tenant_timezone})",
|
|
70
|
+
json.dumps(self.legacy_loan_dict)
|
|
71
|
+
)
|
|
72
|
+
self.report(
|
|
73
|
+
f"Provided due_date is not UTC, setting tz-info to tenant timezone ({self.tenant_timezone})"
|
|
68
74
|
)
|
|
69
75
|
if temp_date_due.hour == 0 and temp_date_due.minute == 0:
|
|
70
76
|
temp_date_due = temp_date_due.replace(hour=23, minute=59)
|
|
71
|
-
|
|
77
|
+
Helper.log_data_issue(
|
|
78
|
+
self.row,
|
|
72
79
|
f"Hour and minute not specified for due date in {row=}. "
|
|
73
|
-
"Assuming end of local calendar day (23:59)..."
|
|
80
|
+
"Assuming end of local calendar day (23:59)...",
|
|
81
|
+
json.dumps(self.legacy_loan_dict)
|
|
82
|
+
)
|
|
83
|
+
self.report(
|
|
84
|
+
"Hour and minute not specified for due date"
|
|
74
85
|
)
|
|
75
86
|
except (ParserError, OverflowError) as ee:
|
|
76
87
|
logging.error(ee)
|
|
@@ -82,9 +93,14 @@ class LegacyLoan(object):
|
|
|
82
93
|
temp_date_out: datetime = parse(self.legacy_loan_dict["out_date"])
|
|
83
94
|
if temp_date_out.tzinfo != tz.UTC:
|
|
84
95
|
temp_date_out = temp_date_out.replace(tzinfo=self.tenant_timezone)
|
|
85
|
-
|
|
96
|
+
Helper.log_data_issue(
|
|
97
|
+
self.row,
|
|
86
98
|
f"Provided out_date is not UTC in {row=}, "
|
|
87
|
-
f"setting tz-info to tenant timezone ({self.tenant_timezone})"
|
|
99
|
+
f"setting tz-info to tenant timezone ({self.tenant_timezone})",
|
|
100
|
+
json.dumps(self.legacy_loan_dict)
|
|
101
|
+
)
|
|
102
|
+
self.report(
|
|
103
|
+
f"Provided out_date is not UTC, setting tz-info to tenant timezone ({self.tenant_timezone})"
|
|
88
104
|
)
|
|
89
105
|
except (ParserError, OverflowError):
|
|
90
106
|
temp_date_out = datetime.now(
|
|
@@ -122,11 +138,17 @@ class LegacyLoan(object):
|
|
|
122
138
|
try:
|
|
123
139
|
return int(renewal_count)
|
|
124
140
|
except ValueError:
|
|
125
|
-
|
|
126
|
-
|
|
141
|
+
Helper.log_data_issue(
|
|
142
|
+
self.row,
|
|
143
|
+
i18n.t("Unresolvable %{renewal_count=} was replaced with 0."),
|
|
144
|
+
json.dumps(loan)
|
|
127
145
|
)
|
|
128
146
|
else:
|
|
129
|
-
|
|
147
|
+
Helper.log_data_issue(
|
|
148
|
+
self.row,
|
|
149
|
+
i18n.t("Missing renewal count was replaced with 0."),
|
|
150
|
+
json.dumps(loan)
|
|
151
|
+
)
|
|
130
152
|
return 0
|
|
131
153
|
|
|
132
154
|
def correct_for_1_day_loans(self):
|
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/__init__.py
RENAMED
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/__main__.py
RENAMED
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/colors.py
RENAMED
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/custom_dict.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/i18n_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{folio_migration_tools-1.9.4 → folio_migration_tools-1.9.5}/src/folio_migration_tools/mapper_base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|