folio-migration-tools 1.9.3__tar.gz → 1.9.4__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.3 → folio_migration_tools-1.9.4}/PKG-INFO +2 -1
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/pyproject.toml +17 -9
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +2 -2
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +7 -1
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/batch_poster.py +119 -18
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/items_transformer.py +4 -1
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/loans_migrator.py +221 -76
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/organization_transformer.py +1 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/transaction_migration/legacy_loan.py +23 -9
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/translations/en.json +19 -10
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/LICENSE +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/README.md +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/__main__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/circulation_helper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/colors.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/config_file_load.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/custom_dict.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/custom_exceptions.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/extradata_writer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/folder_structure.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/helper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/holdings_helper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/i18n_config.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/library_configuration.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapper_base.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/courses_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/holdings_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/item_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/notes_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/order_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/organization_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/ref_data_mapping.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/mapping_file_transformation/user_mapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/conditions.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/hrid_handler.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/loc_language_codes.xml +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/marc_file_processor.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/marc_reader_wrapper.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_report.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/authority_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/bibs_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/courses_migrator.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/holdings_csv_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/holdings_marc_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/migration_task_base.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/orders_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/requests_migrator.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/reserves_migrator.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/migration_tasks/user_transformer.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/task_configuration.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/test_infrastructure/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/test_infrastructure/mocked_classes.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/transaction_migration/__init__.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/transaction_migration/legacy_request.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/transaction_migration/legacy_reserve.py +0 -0
- {folio_migration_tools-1.9.3 → folio_migration_tools-1.9.4}/src/folio_migration_tools/transaction_migration/transaction_result.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: folio_migration_tools
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.4
|
|
4
4
|
Summary: A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: FOLIO,ILS,LSP,Library Systems,MARC21,Library data
|
|
@@ -19,6 +19,7 @@ Requires-Dist: argparse-prompt (>=0.0.5,<0.0.6)
|
|
|
19
19
|
Requires-Dist: art (>=6.5,<7.0)
|
|
20
20
|
Requires-Dist: deepdiff (>=6.2.3,<7.0.0)
|
|
21
21
|
Requires-Dist: defusedxml (>=0.7.1,<0.8.0)
|
|
22
|
+
Requires-Dist: folio-data-import (>=0.3.2,<0.4.0)
|
|
22
23
|
Requires-Dist: folio-uuid (>=0.2.8,<0.3.0)
|
|
23
24
|
Requires-Dist: folioclient (>=0.70.1,<0.71.0)
|
|
24
25
|
Requires-Dist: pyaml (>=21.10.1,<22.0.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "folio_migration_tools"
|
|
3
|
-
version = "1.9.
|
|
3
|
+
version = "1.9.4"
|
|
4
4
|
description = "A tool allowing you to migrate data from legacy ILS:s (Library systems) into FOLIO LSP"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Theodor Tolstoy", email = "github.teddes@tolstoy.se"},
|
|
@@ -56,6 +56,7 @@ deepdiff = "^6.2.3"
|
|
|
56
56
|
pyaml = "^21.10.1"
|
|
57
57
|
python-i18n = "^0.3.9"
|
|
58
58
|
art = "^6.5"
|
|
59
|
+
folio-data-import = "^0.3.2"
|
|
59
60
|
|
|
60
61
|
[tool.poetry.group.dev.dependencies]
|
|
61
62
|
pytest = "^7.1.3"
|
|
@@ -63,24 +64,31 @@ lxml = ">4.9"
|
|
|
63
64
|
coverage = {extras = ["toml"], version = "^6.5.0"}
|
|
64
65
|
pytest-cov = "^4.0.0"
|
|
65
66
|
black = "^22.10.0"
|
|
66
|
-
flake8 = "^
|
|
67
|
+
flake8 = "^7.3.0"
|
|
67
68
|
mypy = "^0.982"
|
|
68
|
-
flake8-black = "^0.3.
|
|
69
|
-
flake8-bugbear = "^
|
|
69
|
+
flake8-black = "^0.3.6"
|
|
70
|
+
flake8-bugbear = "^24.12.12"
|
|
70
71
|
flake8-bandit = "^4.1.1"
|
|
71
|
-
flake8-isort = "^
|
|
72
|
+
flake8-isort = "^6.1.2"
|
|
72
73
|
flake8-docstrings = "^1.6.0"
|
|
73
74
|
darglint = "^1.8.1"
|
|
74
|
-
sphinx = "^5.3.0"
|
|
75
|
-
sphinx-autodoc-typehints = "^1.19.4"
|
|
76
|
-
myst-parser = "^0.18.1"
|
|
77
75
|
types-requests = "^2.28.11.17"
|
|
78
76
|
types-python-dateutil = "^2.8.19.11"
|
|
79
77
|
ipykernel = "^6.29.5"
|
|
80
78
|
pytest-asyncio = "^0.23.0"
|
|
79
|
+
sphinx-autobuild = "^2024.10.3"
|
|
80
|
+
|
|
81
|
+
[tool.poetry.group.docs.dependencies]
|
|
82
|
+
m2r = "^0.2.1"
|
|
83
|
+
myst-parser = "<4.0.0"
|
|
84
|
+
sphinx = ">=6.0.0, <8.0.0"
|
|
85
|
+
sphinx-autodoc-typehints = "^1.17.0"
|
|
86
|
+
sphinx-rtd-theme = "^1.0.0"
|
|
87
|
+
toml = "^0.10.2"
|
|
88
|
+
sphinx-book-theme = "^1.1.4"
|
|
81
89
|
|
|
82
90
|
[tool.poetry.extras]
|
|
83
|
-
docs = ["m2r", "sphinx", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "toml"]
|
|
91
|
+
docs = ["m2r", "sphinx", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "toml",]
|
|
84
92
|
|
|
85
93
|
[tool.poetry.requires-plugins]
|
|
86
94
|
poetry-plugin-export = ">=1.8"
|
|
@@ -174,11 +174,11 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
174
174
|
self.process_marc_field(folio_instance, main_entry_fields[0], ignored_subsequent_fields, legacy_ids)
|
|
175
175
|
try:
|
|
176
176
|
self.process_marc_field(folio_instance, marc_record['245'], ignored_subsequent_fields, legacy_ids)
|
|
177
|
-
except KeyError:
|
|
177
|
+
except KeyError as ke:
|
|
178
178
|
raise TransformationRecordFailedError(
|
|
179
179
|
legacy_ids,
|
|
180
180
|
"No 245 field in MARC record"
|
|
181
|
-
)
|
|
181
|
+
) from ke
|
|
182
182
|
|
|
183
183
|
def perform_additional_parsing(
|
|
184
184
|
self,
|
|
@@ -196,9 +196,15 @@ class RulesMapperHoldings(RulesMapperBase):
|
|
|
196
196
|
if "004" not in marc_record:
|
|
197
197
|
raise TransformationProcessError(
|
|
198
198
|
"",
|
|
199
|
-
("No 004 in record. The tools only support bib-mfhd linking
|
|
199
|
+
("No 004 in record. The tools only support bib-mfhd linking through 004"),
|
|
200
200
|
legacy_ids,
|
|
201
201
|
)
|
|
202
|
+
if len(marc_record.get_fields("004")) > 1:
|
|
203
|
+
Helper.log_data_issue(
|
|
204
|
+
legacy_ids,
|
|
205
|
+
"More than one linked bib (004) found in record. Using the first one",
|
|
206
|
+
[str(x) for x in marc_record.get_fields("004")],
|
|
207
|
+
)
|
|
202
208
|
legacy_instance_id = marc_record["004"].data.strip()
|
|
203
209
|
folio_holding["formerIds"].append(f"{self.bib_id_template}{legacy_instance_id}")
|
|
204
210
|
if legacy_instance_id in self.parent_id_map:
|
|
@@ -131,6 +131,56 @@ class BatchPoster(MigrationTaskBase):
|
|
|
131
131
|
),
|
|
132
132
|
),
|
|
133
133
|
] = False
|
|
134
|
+
preserve_statistical_codes: Annotated[
|
|
135
|
+
bool,
|
|
136
|
+
Field(
|
|
137
|
+
title="Preserve statistical codes",
|
|
138
|
+
description=(
|
|
139
|
+
"Toggles whether or not to preserve statistical codes "
|
|
140
|
+
"during the upsert process. Defaults to False"
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
] = False
|
|
144
|
+
preserve_administrative_notes: Annotated[
|
|
145
|
+
bool,
|
|
146
|
+
Field(
|
|
147
|
+
title="Preserve administrative notes",
|
|
148
|
+
description=(
|
|
149
|
+
"Toggles whether or not to preserve administrative notes "
|
|
150
|
+
"during the upsert process. Defaults to False"
|
|
151
|
+
),
|
|
152
|
+
),
|
|
153
|
+
] = False
|
|
154
|
+
preserve_temporary_locations: Annotated[
|
|
155
|
+
bool,
|
|
156
|
+
Field(
|
|
157
|
+
title="Preserve temporary locations",
|
|
158
|
+
description=(
|
|
159
|
+
"Toggles whether or not to preserve temporary locations "
|
|
160
|
+
"on items during the upsert process. Defaults to False"
|
|
161
|
+
),
|
|
162
|
+
),
|
|
163
|
+
] = False
|
|
164
|
+
preserve_temporary_loan_types: Annotated[
|
|
165
|
+
bool,
|
|
166
|
+
Field(
|
|
167
|
+
title="Preserve temporary loan types",
|
|
168
|
+
description=(
|
|
169
|
+
"Toggles whether or not to preserve temporary loan types "
|
|
170
|
+
"on items during the upsert process. Defaults to False"
|
|
171
|
+
),
|
|
172
|
+
),
|
|
173
|
+
] = False
|
|
174
|
+
preserve_item_status: Annotated[
|
|
175
|
+
bool,
|
|
176
|
+
Field(
|
|
177
|
+
title="Preserve item status",
|
|
178
|
+
description=(
|
|
179
|
+
"Toggles whether or not to preserve item status "
|
|
180
|
+
"on items during the upsert process. Defaults to False"
|
|
181
|
+
),
|
|
182
|
+
),
|
|
183
|
+
] = True
|
|
134
184
|
|
|
135
185
|
task_configuration: TaskConfiguration
|
|
136
186
|
|
|
@@ -292,7 +342,7 @@ class BatchPoster(MigrationTaskBase):
|
|
|
292
342
|
"""
|
|
293
343
|
fetch_batch_size = 90
|
|
294
344
|
fetch_tasks = []
|
|
295
|
-
|
|
345
|
+
existing_records = {}
|
|
296
346
|
async with httpx.AsyncClient(base_url=self.folio_client.gateway_url) as client:
|
|
297
347
|
for i in range(0, len(batch), fetch_batch_size):
|
|
298
348
|
batch_slice = batch[i:i + fetch_batch_size]
|
|
@@ -313,31 +363,82 @@ class BatchPoster(MigrationTaskBase):
|
|
|
313
363
|
responses = await asyncio.gather(*fetch_tasks)
|
|
314
364
|
|
|
315
365
|
for response in responses:
|
|
316
|
-
self.
|
|
366
|
+
self.collect_existing_records_for_upsert(object_type, response, existing_records)
|
|
317
367
|
for record in batch:
|
|
318
|
-
if record["id"] in
|
|
319
|
-
|
|
368
|
+
if record["id"] in existing_records:
|
|
369
|
+
self.prepare_record_for_upsert(record, existing_records[record["id"]])
|
|
370
|
+
|
|
371
|
+
def handle_source_marc(self, new_record: dict, existing_record: dict):
|
|
372
|
+
updates = {}
|
|
373
|
+
updates.update(existing_record)
|
|
374
|
+
self.handle_upsert_for_administrative_notes(updates)
|
|
375
|
+
self.handle_upsert_for_statistical_codes(updates)
|
|
376
|
+
keep_new = {k: v for k, v in new_record.items() if k in ["statisticalCodeIds", "administrativeNotes"]}
|
|
377
|
+
if "instanceStatusId" in new_record:
|
|
378
|
+
updates["instanceStatusId"] = new_record["instanceStatusId"]
|
|
379
|
+
for k, v in keep_new.items():
|
|
380
|
+
updates[k] = list(dict.fromkeys(updates.get(k, []) + v))
|
|
381
|
+
new_record.update(updates)
|
|
320
382
|
|
|
321
383
|
@staticmethod
|
|
322
|
-
def
|
|
384
|
+
def collect_existing_records_for_upsert(object_type: str, response: httpx.Response, existing_records: dict):
|
|
323
385
|
if response.status_code == 200:
|
|
324
386
|
response_json = response.json()
|
|
325
387
|
for record in response_json[object_type]:
|
|
326
|
-
|
|
327
|
-
"_version": record["_version"],
|
|
328
|
-
}
|
|
329
|
-
if "hrid" in record:
|
|
330
|
-
updates[record["id"]]["hrid"] = record["hrid"]
|
|
331
|
-
if "status" in record:
|
|
332
|
-
updates[record["id"]]["status"] = record["status"]
|
|
333
|
-
if "lastCheckIn" in record:
|
|
334
|
-
updates[record["id"]]["lastCheckIn"] = record["lastCheckIn"]
|
|
388
|
+
existing_records[record["id"]] = record
|
|
335
389
|
else:
|
|
336
390
|
logging.error(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
391
|
+
"Failed to fetch current records. HTTP %s\t%s",
|
|
392
|
+
response.status_code,
|
|
393
|
+
response.text,
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
def handle_upsert_for_statistical_codes(self, updates: dict):
|
|
397
|
+
if not self.task_configuration.preserve_statistical_codes:
|
|
398
|
+
updates.pop("statisticalCodeIds", None)
|
|
399
|
+
|
|
400
|
+
def handle_upsert_for_administrative_notes(self, updates: dict):
|
|
401
|
+
if not self.task_configuration.preserve_administrative_notes:
|
|
402
|
+
updates.pop("administrativeNotes", None)
|
|
403
|
+
|
|
404
|
+
def handle_upsert_for_temporary_locations(self, updates: dict):
|
|
405
|
+
if not self.task_configuration.preserve_temporary_locations:
|
|
406
|
+
updates.pop("temporaryLocationId", None)
|
|
407
|
+
|
|
408
|
+
def handle_upsert_for_temporary_loan_types(self, updates: dict):
|
|
409
|
+
if not self.task_configuration.preserve_temporary_loan_types:
|
|
410
|
+
updates.pop("temporaryLoanTypeId", None)
|
|
411
|
+
|
|
412
|
+
def keep_existing_fields(self, updates: dict, existing_record: dict):
|
|
413
|
+
keep_existing_fields = ["hrid", "lastCheckIn"]
|
|
414
|
+
if self.task_configuration.preserve_item_status:
|
|
415
|
+
keep_existing_fields.append("status")
|
|
416
|
+
for key in keep_existing_fields:
|
|
417
|
+
if key in existing_record:
|
|
418
|
+
updates[key] = existing_record[key]
|
|
419
|
+
|
|
420
|
+
def prepare_record_for_upsert(self, new_record: dict, existing_record: dict):
|
|
421
|
+
if "source" in existing_record and "MARC" in existing_record["source"]:
|
|
422
|
+
self.handle_source_marc(new_record, existing_record)
|
|
423
|
+
else:
|
|
424
|
+
updates = {
|
|
425
|
+
"_version": existing_record["_version"],
|
|
426
|
+
}
|
|
427
|
+
self.keep_existing_fields(updates, existing_record)
|
|
428
|
+
keep_new = {k: v for k, v in new_record.items() if k in ["statisticalCodeIds", "administrativeNotes"]}
|
|
429
|
+
self.handle_upsert_for_statistical_codes(existing_record)
|
|
430
|
+
self.handle_upsert_for_administrative_notes(existing_record)
|
|
431
|
+
self.handle_upsert_for_temporary_locations(existing_record)
|
|
432
|
+
self.handle_upsert_for_temporary_loan_types(existing_record)
|
|
433
|
+
for k, v in keep_new.items():
|
|
434
|
+
updates[k] = list(dict.fromkeys(existing_record.get(k, []) + v))
|
|
435
|
+
for key in [
|
|
436
|
+
"temporaryLocationId",
|
|
437
|
+
"temporaryLoanTypeId",
|
|
438
|
+
]:
|
|
439
|
+
if key in existing_record:
|
|
440
|
+
updates[key] = existing_record[key]
|
|
441
|
+
new_record.update(updates)
|
|
341
442
|
|
|
342
443
|
async def get_with_retry(self, client: httpx.AsyncClient, url: str, params=None):
|
|
343
444
|
if params is None:
|
|
@@ -218,7 +218,10 @@ class ItemsTransformer(MigrationTaskBase):
|
|
|
218
218
|
self.folio_keys = MappingFileMapperBase.get_mapped_folio_properties_from_map(
|
|
219
219
|
self.items_map
|
|
220
220
|
)
|
|
221
|
-
if
|
|
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)
|
|
224
|
+
):
|
|
222
225
|
statcode_mapping = self.load_ref_data_mapping_file(
|
|
223
226
|
"statisticalCodeIds",
|
|
224
227
|
self.folder_structure.mapping_files_folder
|