folio-migration-tools 1.9.10__py3-none-any.whl → 1.10.0__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.
- folio_migration_tools/__init__.py +3 -4
- folio_migration_tools/__main__.py +53 -31
- folio_migration_tools/circulation_helper.py +118 -108
- folio_migration_tools/custom_dict.py +2 -2
- folio_migration_tools/custom_exceptions.py +4 -5
- folio_migration_tools/folder_structure.py +17 -7
- folio_migration_tools/helper.py +8 -7
- folio_migration_tools/holdings_helper.py +4 -3
- folio_migration_tools/i18n_cache.py +79 -0
- folio_migration_tools/library_configuration.py +77 -37
- folio_migration_tools/mapper_base.py +45 -31
- folio_migration_tools/mapping_file_transformation/courses_mapper.py +1 -1
- folio_migration_tools/mapping_file_transformation/holdings_mapper.py +7 -3
- folio_migration_tools/mapping_file_transformation/item_mapper.py +13 -26
- folio_migration_tools/mapping_file_transformation/manual_fee_fines_mapper.py +1 -2
- folio_migration_tools/mapping_file_transformation/mapping_file_mapper_base.py +13 -11
- folio_migration_tools/mapping_file_transformation/order_mapper.py +6 -5
- folio_migration_tools/mapping_file_transformation/organization_mapper.py +3 -3
- folio_migration_tools/mapping_file_transformation/user_mapper.py +47 -28
- folio_migration_tools/marc_rules_transformation/conditions.py +82 -97
- folio_migration_tools/marc_rules_transformation/holdings_statementsparser.py +13 -5
- folio_migration_tools/marc_rules_transformation/hrid_handler.py +3 -2
- folio_migration_tools/marc_rules_transformation/marc_file_processor.py +26 -24
- folio_migration_tools/marc_rules_transformation/rules_mapper_base.py +56 -51
- folio_migration_tools/marc_rules_transformation/rules_mapper_bibs.py +28 -17
- folio_migration_tools/marc_rules_transformation/rules_mapper_holdings.py +68 -37
- folio_migration_tools/migration_report.py +18 -7
- folio_migration_tools/migration_tasks/batch_poster.py +285 -354
- folio_migration_tools/migration_tasks/bibs_transformer.py +14 -9
- folio_migration_tools/migration_tasks/courses_migrator.py +2 -3
- folio_migration_tools/migration_tasks/holdings_csv_transformer.py +23 -24
- folio_migration_tools/migration_tasks/holdings_marc_transformer.py +14 -24
- folio_migration_tools/migration_tasks/items_transformer.py +23 -34
- folio_migration_tools/migration_tasks/loans_migrator.py +67 -144
- folio_migration_tools/migration_tasks/manual_fee_fines_transformer.py +3 -3
- folio_migration_tools/migration_tasks/migration_task_base.py +47 -60
- folio_migration_tools/migration_tasks/orders_transformer.py +25 -42
- folio_migration_tools/migration_tasks/organization_transformer.py +9 -18
- folio_migration_tools/migration_tasks/requests_migrator.py +21 -24
- folio_migration_tools/migration_tasks/reserves_migrator.py +6 -5
- folio_migration_tools/migration_tasks/user_transformer.py +25 -20
- folio_migration_tools/task_configuration.py +6 -7
- folio_migration_tools/transaction_migration/legacy_loan.py +15 -27
- folio_migration_tools/transaction_migration/legacy_request.py +1 -1
- folio_migration_tools/translations/en.json +0 -7
- {folio_migration_tools-1.9.10.dist-info → folio_migration_tools-1.10.0.dist-info}/METADATA +19 -28
- folio_migration_tools-1.10.0.dist-info/RECORD +63 -0
- folio_migration_tools-1.10.0.dist-info/WHEEL +4 -0
- folio_migration_tools-1.10.0.dist-info/entry_points.txt +3 -0
- folio_migration_tools/marc_rules_transformation/rules_mapper_authorities.py +0 -241
- folio_migration_tools/migration_tasks/authority_transformer.py +0 -119
- folio_migration_tools/test_infrastructure/__init__.py +0 -0
- folio_migration_tools/test_infrastructure/mocked_classes.py +0 -406
- folio_migration_tools-1.9.10.dist-info/RECORD +0 -67
- folio_migration_tools-1.9.10.dist-info/WHEEL +0 -4
- folio_migration_tools-1.9.10.dist-info/entry_points.txt +0 -3
- folio_migration_tools-1.9.10.dist-info/licenses/LICENSE +0 -21
|
@@ -15,6 +15,7 @@ from folio_uuid.folio_uuid import FOLIONamespaces, FolioUUID
|
|
|
15
15
|
from folioclient import FolioClient
|
|
16
16
|
from pymarc import Field, Optional, Record, Subfield
|
|
17
17
|
|
|
18
|
+
from folio_migration_tools.i18n_cache import i18n_t
|
|
18
19
|
from folio_migration_tools.custom_exceptions import (
|
|
19
20
|
TransformationFieldMappingError,
|
|
20
21
|
TransformationProcessError,
|
|
@@ -52,7 +53,10 @@ class RulesMapperBase(MapperBase):
|
|
|
52
53
|
self.mappings: dict = {}
|
|
53
54
|
self.schema_properties = None
|
|
54
55
|
self.create_source_records = all(
|
|
55
|
-
[
|
|
56
|
+
[
|
|
57
|
+
self.task_configuration.create_source_records,
|
|
58
|
+
(not getattr(self.task_configuration, "data_import_marc", False)),
|
|
59
|
+
]
|
|
56
60
|
)
|
|
57
61
|
if hasattr(self.task_configuration, "hrid_handling"):
|
|
58
62
|
self.hrid_handler = HRIDHandler(
|
|
@@ -190,10 +194,10 @@ class RulesMapperBase(MapperBase):
|
|
|
190
194
|
):
|
|
191
195
|
values: List[str] = []
|
|
192
196
|
if mapping.get("subfield") and (custom_delimiters := mapping.get("subFieldDelimiter")):
|
|
193
|
-
delimiter_map =
|
|
197
|
+
delimiter_map = dict.fromkeys(mapping.get("subfield"), " ")
|
|
194
198
|
for custom_delimiter in custom_delimiters:
|
|
195
199
|
delimiter_map.update(
|
|
196
|
-
|
|
200
|
+
dict.fromkeys(custom_delimiter["subfields"], custom_delimiter["value"])
|
|
197
201
|
)
|
|
198
202
|
custom_delimited_strings: List[Tuple[str, List[str]]] = []
|
|
199
203
|
subfields = mapping.get("subfield")
|
|
@@ -296,13 +300,13 @@ class RulesMapperBase(MapperBase):
|
|
|
296
300
|
def perform_proxy_mapping(self, marc_field):
|
|
297
301
|
proxy_mapping = next(iter(self.mappings.get("880", [])), [])
|
|
298
302
|
if "6" not in marc_field:
|
|
299
|
-
self.migration_report.add("Field880Mappings",
|
|
303
|
+
self.migration_report.add("Field880Mappings", i18n_t("Records without $6"))
|
|
300
304
|
return None
|
|
301
305
|
if not proxy_mapping or not proxy_mapping.get("fieldReplacementBy3Digits", False):
|
|
302
306
|
return None
|
|
303
307
|
if not marc_field["6"][:3] or len(marc_field["6"][:3]) != 3:
|
|
304
308
|
self.migration_report.add(
|
|
305
|
-
"Field880Mappings",
|
|
309
|
+
"Field880Mappings", i18n_t("Records with unexpected length in $6")
|
|
306
310
|
)
|
|
307
311
|
return None
|
|
308
312
|
first_three = marc_field["6"][:3]
|
|
@@ -317,16 +321,16 @@ class RulesMapperBase(MapperBase):
|
|
|
317
321
|
)
|
|
318
322
|
self.migration_report.add(
|
|
319
323
|
"Field880Mappings",
|
|
320
|
-
|
|
324
|
+
i18n_t("Source digits")
|
|
321
325
|
+ f": {marc_field['6']} "
|
|
322
|
-
+
|
|
326
|
+
+ i18n_t("Target field")
|
|
323
327
|
+ f": {target_field}",
|
|
324
328
|
)
|
|
325
329
|
mappings = self.mappings.get(target_field, {})
|
|
326
330
|
if not mappings:
|
|
327
331
|
self.migration_report.add(
|
|
328
332
|
"Field880Mappings",
|
|
329
|
-
|
|
333
|
+
i18n_t("Mapping not set up for target field")
|
|
330
334
|
+ f": {target_field} ({marc_field['6']})",
|
|
331
335
|
)
|
|
332
336
|
return mappings
|
|
@@ -334,7 +338,7 @@ class RulesMapperBase(MapperBase):
|
|
|
334
338
|
def report_marc_stats(
|
|
335
339
|
self, marc_field: Field, bad_tags, legacy_ids, ignored_subsequent_fields
|
|
336
340
|
):
|
|
337
|
-
self.migration_report.add("Trivia",
|
|
341
|
+
self.migration_report.add("Trivia", i18n_t("Total number of Tags processed"))
|
|
338
342
|
self.report_source_and_links(marc_field)
|
|
339
343
|
self.report_bad_tags(marc_field, bad_tags, legacy_ids)
|
|
340
344
|
mapped = marc_field.tag in self.mappings
|
|
@@ -348,7 +352,7 @@ class RulesMapperBase(MapperBase):
|
|
|
348
352
|
for subfield_2 in marc_field.get_subfields("2"):
|
|
349
353
|
self.migration_report.add(
|
|
350
354
|
"AuthoritySources",
|
|
351
|
-
|
|
355
|
+
i18n_t("Source of heading or term") + f": {subfield_2.split(' ')[0]}",
|
|
352
356
|
)
|
|
353
357
|
for subfield_0 in marc_field.get_subfields("0"):
|
|
354
358
|
code = ""
|
|
@@ -360,7 +364,7 @@ class RulesMapperBase(MapperBase):
|
|
|
360
364
|
code = subfield_0[: subfield_0.find(url.path)]
|
|
361
365
|
if code:
|
|
362
366
|
self.migration_report.add(
|
|
363
|
-
"AuthoritySources",
|
|
367
|
+
"AuthoritySources", i18n_t("$0 base uri or source code") + f": {code}"
|
|
364
368
|
)
|
|
365
369
|
|
|
366
370
|
def apply_rules(self, marc_field: pymarc.Field, mapping, legacy_ids):
|
|
@@ -399,7 +403,7 @@ class RulesMapperBase(MapperBase):
|
|
|
399
403
|
)
|
|
400
404
|
trfe.log_it()
|
|
401
405
|
self.migration_report.add_general_statistics(
|
|
402
|
-
|
|
406
|
+
i18n_t("Records failed due to an error. See data issues log for details")
|
|
403
407
|
)
|
|
404
408
|
except Exception as exception:
|
|
405
409
|
self.handle_generic_exception(self.parsed_records, exception)
|
|
@@ -505,7 +509,7 @@ class RulesMapperBase(MapperBase):
|
|
|
505
509
|
+ i18n.t("Check mapping file against the schema.")
|
|
506
510
|
+ " "
|
|
507
511
|
+ i18n.t("Target type")
|
|
508
|
-
+ f": {sch.get(target_string,{}).get('type','')} "
|
|
512
|
+
+ f": {sch.get(target_string, {}).get('type', '')} "
|
|
509
513
|
+ i18n.t("Value")
|
|
510
514
|
+ f": {value}",
|
|
511
515
|
"",
|
|
@@ -529,7 +533,7 @@ class RulesMapperBase(MapperBase):
|
|
|
529
533
|
"",
|
|
530
534
|
(
|
|
531
535
|
f"Edge! Target string: {target_string} "
|
|
532
|
-
f"Target type: {sch.get(target_string,{}).get('type','')} Value: {value}"
|
|
536
|
+
f"Target type: {sch.get(target_string, {}).get('type', '')} Value: {value}"
|
|
533
537
|
),
|
|
534
538
|
)
|
|
535
539
|
|
|
@@ -564,8 +568,9 @@ class RulesMapperBase(MapperBase):
|
|
|
564
568
|
if subfield != "9":
|
|
565
569
|
Helper.log_data_issue(
|
|
566
570
|
index_or_legacy_id,
|
|
567
|
-
f"authorityId mapping from ${subfield} is not supported. Data Import
|
|
568
|
-
"Use only $9 for authority id mapping in MARC-to-Instance
|
|
571
|
+
f"authorityId mapping from ${subfield} is not supported. Data Import "
|
|
572
|
+
"will fail. Use only $9 for authority id mapping in MARC-to-Instance "
|
|
573
|
+
"mapping rules.",
|
|
569
574
|
marc_field,
|
|
570
575
|
)
|
|
571
576
|
entity_mapping["subfield"] = ["9"]
|
|
@@ -599,7 +604,8 @@ class RulesMapperBase(MapperBase):
|
|
|
599
604
|
entity = {}
|
|
600
605
|
Helper.log_data_issue(
|
|
601
606
|
index_or_legacy_id,
|
|
602
|
-
f"Missing one or more required property in entity {entity_parent_key}
|
|
607
|
+
f"Missing one or more required property in entity {entity_parent_key} "
|
|
608
|
+
f"({missing_required_props})",
|
|
603
609
|
marc_field,
|
|
604
610
|
)
|
|
605
611
|
return entity
|
|
@@ -639,7 +645,8 @@ class RulesMapperBase(MapperBase):
|
|
|
639
645
|
)
|
|
640
646
|
or e_parent in ["electronicAccess", "publication"]
|
|
641
647
|
or (
|
|
642
|
-
e_parent.startswith("holdingsStatements")
|
|
648
|
+
e_parent.startswith("holdingsStatements")
|
|
649
|
+
and any(v for k, v in entity.items())
|
|
643
650
|
)
|
|
644
651
|
):
|
|
645
652
|
self.add_entity_to_record(entity, e_parent, folio_record, self.schema)
|
|
@@ -661,12 +668,12 @@ class RulesMapperBase(MapperBase):
|
|
|
661
668
|
folio_record["discoverySuppress"] = file_def.discovery_suppressed
|
|
662
669
|
self.migration_report.add(
|
|
663
670
|
"Suppression",
|
|
664
|
-
i18n.t("Suppressed from discovery") + f
|
|
671
|
+
i18n.t("Suppressed from discovery") + f" = {folio_record['discoverySuppress']}",
|
|
665
672
|
)
|
|
666
673
|
if not only_discovery_suppress:
|
|
667
674
|
folio_record["staffSuppress"] = file_def.staff_suppressed
|
|
668
675
|
self.migration_report.add(
|
|
669
|
-
"Suppression", i18n.t("Staff suppressed") + f
|
|
676
|
+
"Suppression", i18n.t("Staff suppressed") + f" = {folio_record['staffSuppress']} "
|
|
670
677
|
)
|
|
671
678
|
|
|
672
679
|
def create_preceding_succeeding_titles(
|
|
@@ -825,7 +832,6 @@ class RulesMapperBase(MapperBase):
|
|
|
825
832
|
)
|
|
826
833
|
data_import_marc_file.write(marc_record.as_marc())
|
|
827
834
|
|
|
828
|
-
|
|
829
835
|
def map_statistical_codes(
|
|
830
836
|
self,
|
|
831
837
|
folio_record: dict,
|
|
@@ -854,11 +860,17 @@ class RulesMapperBase(MapperBase):
|
|
|
854
860
|
for mapping in self.task_configuration.statistical_code_mapping_fields:
|
|
855
861
|
stat_code_marc_fields.append(mapping.split("$"))
|
|
856
862
|
for field_map in stat_code_marc_fields:
|
|
857
|
-
mapped_codes = self.map_stat_codes_from_marc_field(
|
|
858
|
-
|
|
863
|
+
mapped_codes = self.map_stat_codes_from_marc_field(
|
|
864
|
+
field_map, marc_record, self.library_configuration.multi_field_delimiter
|
|
865
|
+
)
|
|
866
|
+
folio_record["statisticalCodeIds"] = (
|
|
867
|
+
folio_record.get("statisticalCodeIds", []) + mapped_codes
|
|
868
|
+
)
|
|
859
869
|
|
|
860
870
|
@staticmethod
|
|
861
|
-
def map_stat_codes_from_marc_field(
|
|
871
|
+
def map_stat_codes_from_marc_field(
|
|
872
|
+
field_map: List[str], marc_record: Record, multi_field_delimiter: str = "<delimiter>"
|
|
873
|
+
) -> List[str]:
|
|
862
874
|
"""Map statistical codes from MARC field to FOLIO instance.
|
|
863
875
|
|
|
864
876
|
This function extracts statistical codes from a MARC field based on the provided field map.
|
|
@@ -871,30 +883,26 @@ class RulesMapperBase(MapperBase):
|
|
|
871
883
|
|
|
872
884
|
Returns:
|
|
873
885
|
str: A string of statistical codes extracted from the MARC field, formatted as "<field>_<subfield>:<value>".
|
|
874
|
-
"""
|
|
886
|
+
""" # noqa: E501
|
|
875
887
|
field_values = []
|
|
876
888
|
if len(field_map) == 2:
|
|
877
889
|
subfields = []
|
|
878
890
|
for mf in marc_record.get_fields(field_map[0]):
|
|
879
891
|
subfields.extend(
|
|
880
|
-
multi_field_delimiter.join(
|
|
881
|
-
|
|
882
|
-
)
|
|
892
|
+
multi_field_delimiter.join(mf.get_subfields(field_map[1])).split(
|
|
893
|
+
multi_field_delimiter
|
|
894
|
+
)
|
|
883
895
|
)
|
|
884
|
-
field_values.extend(
|
|
885
|
-
[
|
|
886
|
-
f"{field_map[0]}_{field_map[1]}:{x}" for
|
|
887
|
-
x in subfields
|
|
888
|
-
]
|
|
889
|
-
)
|
|
896
|
+
field_values.extend([f"{field_map[0]}_{field_map[1]}:{x}" for x in subfields])
|
|
890
897
|
elif len(field_map) > 2:
|
|
891
898
|
for mf in marc_record.get_fields(field_map[0]):
|
|
892
899
|
for sf in field_map[1:]:
|
|
893
900
|
field_values.extend(
|
|
894
901
|
[
|
|
895
|
-
f"{field_map[0]}_{sf}:{x}"
|
|
896
|
-
|
|
897
|
-
|
|
902
|
+
f"{field_map[0]}_{sf}:{x}"
|
|
903
|
+
for x in multi_field_delimiter.join(mf.get_subfields(sf)).split(
|
|
904
|
+
multi_field_delimiter
|
|
905
|
+
)
|
|
898
906
|
]
|
|
899
907
|
)
|
|
900
908
|
elif field_map:
|
|
@@ -955,16 +963,11 @@ class RulesMapperBase(MapperBase):
|
|
|
955
963
|
srs_types = {
|
|
956
964
|
FOLIONamespaces.holdings: FOLIONamespaces.srs_records_holdingsrecord,
|
|
957
965
|
FOLIONamespaces.instances: FOLIONamespaces.srs_records_bib,
|
|
958
|
-
FOLIONamespaces.authorities: FOLIONamespaces.srs_records_auth,
|
|
959
966
|
FOLIONamespaces.edifact: FOLIONamespaces.srs_records_edifact,
|
|
960
967
|
}
|
|
961
968
|
|
|
962
969
|
return str(
|
|
963
|
-
FolioUUID(
|
|
964
|
-
self.base_string_for_folio_uuid,
|
|
965
|
-
srs_types.get(record_type),
|
|
966
|
-
legacy_id
|
|
967
|
-
)
|
|
970
|
+
FolioUUID(self.base_string_for_folio_uuid, srs_types.get(record_type), legacy_id)
|
|
968
971
|
)
|
|
969
972
|
|
|
970
973
|
@staticmethod
|
|
@@ -1017,7 +1020,6 @@ class RulesMapperBase(MapperBase):
|
|
|
1017
1020
|
record_types = {
|
|
1018
1021
|
FOLIONamespaces.holdings: "MARC_HOLDING",
|
|
1019
1022
|
FOLIONamespaces.instances: "MARC_BIB",
|
|
1020
|
-
FOLIONamespaces.authorities: "MARC_AUTHORITY",
|
|
1021
1023
|
FOLIONamespaces.edifact: "EDIFACT",
|
|
1022
1024
|
}
|
|
1023
1025
|
|
|
@@ -1030,10 +1032,6 @@ class RulesMapperBase(MapperBase):
|
|
|
1030
1032
|
"holdingsId": folio_object["id"],
|
|
1031
1033
|
"holdingsHrid": folio_object.get("hrid", ""),
|
|
1032
1034
|
},
|
|
1033
|
-
FOLIONamespaces.authorities: {
|
|
1034
|
-
"authorityId": folio_object["id"],
|
|
1035
|
-
"authorityHrid": marc_record["001"].data,
|
|
1036
|
-
},
|
|
1037
1035
|
FOLIONamespaces.edifact: {},
|
|
1038
1036
|
}
|
|
1039
1037
|
|
|
@@ -1075,6 +1073,7 @@ def is_array_of_objects(schema_property):
|
|
|
1075
1073
|
sc_prop_type = schema_property.get("type", "string")
|
|
1076
1074
|
return sc_prop_type == "array" and schema_property["items"]["type"] == "object"
|
|
1077
1075
|
|
|
1076
|
+
|
|
1078
1077
|
def entity_indicators_match(entity_mapping, marc_field):
|
|
1079
1078
|
"""
|
|
1080
1079
|
Check if the indicators of the entity mapping match the indicators of the MARC field.
|
|
@@ -1095,12 +1094,18 @@ def entity_indicators_match(entity_mapping, marc_field):
|
|
|
1095
1094
|
|
|
1096
1095
|
Returns:
|
|
1097
1096
|
bool: True if the indicators match, False otherwise.
|
|
1098
|
-
"""
|
|
1097
|
+
""" # noqa: E501
|
|
1099
1098
|
if indicator_rule := [x["indicators"] for x in entity_mapping if "indicators" in x]:
|
|
1100
1099
|
return all(
|
|
1101
1100
|
[
|
|
1102
|
-
(
|
|
1103
|
-
|
|
1101
|
+
(
|
|
1102
|
+
marc_field.indicator1 == indicator_rule[0]["ind1"]
|
|
1103
|
+
or indicator_rule[0]["ind1"] == "*"
|
|
1104
|
+
),
|
|
1105
|
+
(
|
|
1106
|
+
marc_field.indicator2 == indicator_rule[0]["ind2"]
|
|
1107
|
+
or indicator_rule[0]["ind2"] == "*"
|
|
1108
|
+
),
|
|
1104
1109
|
]
|
|
1105
1110
|
)
|
|
1106
1111
|
else:
|
|
@@ -17,6 +17,7 @@ from folioclient import FolioClient
|
|
|
17
17
|
from pymarc.record import Leader, Record
|
|
18
18
|
from pymarc.field import Field
|
|
19
19
|
|
|
20
|
+
from folio_migration_tools.i18n_cache import i18n_t
|
|
20
21
|
from folio_migration_tools.custom_exceptions import (
|
|
21
22
|
TransformationProcessError,
|
|
22
23
|
TransformationRecordFailedError,
|
|
@@ -67,7 +68,9 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
67
68
|
self.hrid_handler.deactivate035_from001 = True
|
|
68
69
|
self.start = time.time()
|
|
69
70
|
|
|
70
|
-
def perform_initial_preparation(
|
|
71
|
+
def perform_initial_preparation(
|
|
72
|
+
self, file_def: FileDefinition, marc_record: Record, legacy_ids: List[str]
|
|
73
|
+
):
|
|
71
74
|
folio_instance = {}
|
|
72
75
|
folio_instance["id"] = str(
|
|
73
76
|
FolioUUID(
|
|
@@ -95,7 +98,7 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
95
98
|
|
|
96
99
|
def handle_leader_05(self, marc_record: Record, legacy_ids: List[str]):
|
|
97
100
|
leader_05 = marc_record.leader[5] or "Empty"
|
|
98
|
-
self.migration_report.add("RecordStatus",
|
|
101
|
+
self.migration_report.add("RecordStatus", i18n_t("Original value") + f": {leader_05}")
|
|
99
102
|
if leader_05 not in ["a", "c", "d", "n", "p"]:
|
|
100
103
|
marc_record.leader = Leader(f"{marc_record.leader[:5]}c{marc_record.leader[6:]}")
|
|
101
104
|
self.migration_report.add(
|
|
@@ -145,7 +148,13 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
145
148
|
self.report_folio_mapping(clean_folio_instance, self.schema)
|
|
146
149
|
return [clean_folio_instance]
|
|
147
150
|
|
|
148
|
-
def simple_bib_map(
|
|
151
|
+
def simple_bib_map(
|
|
152
|
+
self,
|
|
153
|
+
folio_instance: dict,
|
|
154
|
+
marc_record: Record,
|
|
155
|
+
ignored_subsequent_fields: set,
|
|
156
|
+
legacy_ids: List[str],
|
|
157
|
+
):
|
|
149
158
|
"""
|
|
150
159
|
This method applies a much simplified MARC-to-instance
|
|
151
160
|
mapping to create a minimal FOLIO Instance record to be
|
|
@@ -164,20 +173,24 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
164
173
|
if len(main_entry_fields) > 1:
|
|
165
174
|
Helper.log_data_issue(
|
|
166
175
|
legacy_ids,
|
|
167
|
-
"Multiple main entry fields in record. Record will fail Data Import.
|
|
168
|
-
|
|
176
|
+
"Multiple main entry fields in record. Record will fail Data Import. "
|
|
177
|
+
"Creating Instance anyway.",
|
|
178
|
+
[str(field) for field in main_entry_fields],
|
|
169
179
|
)
|
|
170
180
|
if not main_entry_fields:
|
|
171
181
|
main_entry_fields += marc_record.get_fields("700", "710", "711", "730")
|
|
172
182
|
main_entry_fields.sort(key=lambda x: int(x.tag))
|
|
173
183
|
if main_entry_fields:
|
|
174
|
-
self.process_marc_field(
|
|
184
|
+
self.process_marc_field(
|
|
185
|
+
folio_instance, main_entry_fields[0], ignored_subsequent_fields, legacy_ids
|
|
186
|
+
)
|
|
175
187
|
try:
|
|
176
|
-
self.process_marc_field(
|
|
188
|
+
self.process_marc_field(
|
|
189
|
+
folio_instance, marc_record["245"], ignored_subsequent_fields, legacy_ids
|
|
190
|
+
)
|
|
177
191
|
except KeyError as ke:
|
|
178
192
|
raise TransformationRecordFailedError(
|
|
179
|
-
legacy_ids,
|
|
180
|
-
"No 245 field in MARC record"
|
|
193
|
+
legacy_ids, "No 245 field in MARC record"
|
|
181
194
|
) from ke
|
|
182
195
|
|
|
183
196
|
def perform_additional_parsing(
|
|
@@ -220,10 +233,8 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
220
233
|
|
|
221
234
|
def handle_languages(self, folio_instance: Dict, marc_record: Record, legacy_ids: List[str]):
|
|
222
235
|
if "languages" in folio_instance:
|
|
223
|
-
orig_languages =
|
|
224
|
-
orig_languages.update(
|
|
225
|
-
{lang: None for lang in self.get_languages(marc_record, legacy_ids)}
|
|
226
|
-
)
|
|
236
|
+
orig_languages = dict.fromkeys(folio_instance["languages"])
|
|
237
|
+
orig_languages.update(dict.fromkeys(self.get_languages(marc_record, legacy_ids)))
|
|
227
238
|
folio_instance["languages"] = list(orig_languages.keys())
|
|
228
239
|
else:
|
|
229
240
|
folio_instance["languages"] = self.get_languages(marc_record, legacy_ids)
|
|
@@ -313,7 +324,7 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
313
324
|
raise TransformationProcessError("", "No instance_types setup in tenant")
|
|
314
325
|
|
|
315
326
|
if "336" in marc_record and "b" not in marc_record["336"]:
|
|
316
|
-
self.migration_report.add("RecourceTypeMapping",
|
|
327
|
+
self.migration_report.add("RecourceTypeMapping", i18n_t("Subfield b not in 336"))
|
|
317
328
|
if "a" in marc_record["336"]:
|
|
318
329
|
return_id = get_folio_id_by_name(marc_record["336"]["a"])
|
|
319
330
|
|
|
@@ -422,7 +433,7 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
422
433
|
return True
|
|
423
434
|
self.migration_report.add(
|
|
424
435
|
"InstanceFormat",
|
|
425
|
-
("InstanceFormat not mapped since 338$2 (Source)
|
|
436
|
+
(f"InstanceFormat not mapped since 338$2 (Source) is set to {field['2']}. "),
|
|
426
437
|
)
|
|
427
438
|
return False
|
|
428
439
|
|
|
@@ -533,10 +544,10 @@ class BibsRulesMapper(RulesMapperBase):
|
|
|
533
544
|
return ""
|
|
534
545
|
|
|
535
546
|
def get_languages_041(self, marc_record: Record, legacy_id: List[str]) -> Dict[str, None]:
|
|
536
|
-
languages =
|
|
547
|
+
languages = {}
|
|
537
548
|
lang_fields = marc_record.get_fields("041")
|
|
538
549
|
if not any(lang_fields):
|
|
539
|
-
return
|
|
550
|
+
return {}
|
|
540
551
|
subfields = "abdefghjkmn"
|
|
541
552
|
for lang_tag in lang_fields:
|
|
542
553
|
if "2" in lang_tag:
|